Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(243)

Side by Side Diff: chrome/browser/apps/drive/drive_app_provider_browsertest.cc

Issue 308003005: app_list: Drive app integration. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: move to c/b/apps, add OWNERS Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/apps/drive/drive_app_provider.h"
6
7 #include "base/logging.h"
8 #include "base/macros.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/path_service.h"
11 #include "base/timer/timer.h"
12 #include "chrome/browser/apps/drive/drive_app_mapping.h"
13 #include "chrome/browser/apps/drive/drive_service_bridge.h"
14 #include "chrome/browser/drive/drive_app_registry.h"
15 #include "chrome/browser/drive/fake_drive_service.h"
16 #include "chrome/browser/extensions/extension_browsertest.h"
17 #include "chrome/browser/extensions/install_tracker.h"
18 #include "chrome/browser/extensions/install_tracker_factory.h"
19 #include "chrome/common/chrome_paths.h"
20 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
21 #include "content/public/test/test_utils.h"
22 #include "extensions/browser/extension_registry.h"
23 #include "sync/api/string_ordinal.h"
24 #include "ui/app_list/app_list_folder_item.h"
25 #include "ui/app_list/app_list_item.h"
26 #include "ui/app_list/app_list_item_list.h"
27 #include "ui/app_list/test/app_list_test_model.h"
28
29 namespace extensions {
30
31 namespace {
32
33 const char kDriveAppId[] = "drive_app_id";
34 const char kDriveAppName[] = "Fake Drive App";
35 const char kLaunchUrl[] = "http://example.com/drive";
36
37 // App id of hosted_app.crx.
38 const char kChromeAppId[] = "kbmnembihfiondgfjekmnmcbddelicoi";
39
40 // Stub drive service bridge.
41 class TestDriveServiceBridge : public DriveServiceBridge {
42 public:
43 explicit TestDriveServiceBridge(drive::DriveAppRegistry* registry)
44 : registry_(registry) {}
45 virtual ~TestDriveServiceBridge() {}
46
47 virtual drive::DriveAppRegistry* GetAppRegistry() OVERRIDE {
48 return registry_;
49 }
50
51 private:
52 drive::DriveAppRegistry* registry_;
53
54 DISALLOW_COPY_AND_ASSIGN(TestDriveServiceBridge);
55 };
56
57 // A model builder that creates and deletes items of a given model when app
58 // is installed and uninstalled in the given profile.
59 class TestModelBuilder : public InstallObserver {
60 public:
61 TestModelBuilder(Profile* profile, app_list::test::AppListTestModel* model)
62 : profile_(profile), model_(model) {
63 InstallTracker::Get(profile_)->AddObserver(this);
64 }
65 virtual ~TestModelBuilder() {
66 InstallTracker::Get(profile_)->RemoveObserver(this);
67 }
68
69 // InstallObserver
70 virtual void OnExtensionLoaded(const Extension* extension) OVERRIDE {
71 model_->CreateAndAddItem(extension->id());
72 }
73 virtual void OnExtensionUninstalled(const Extension* extension) OVERRIDE {
74 model_->DeleteItem(extension->id());
75 }
76
77 private:
78 Profile* profile_;
79 app_list::test::AppListTestModel* model_;
80
81 DISALLOW_COPY_AND_ASSIGN(TestModelBuilder);
82 };
83
84 } // namespace
85
86 class DriveAppProviderTest : public ExtensionBrowserTest {
87 public:
88 DriveAppProviderTest() {}
89 virtual ~DriveAppProviderTest() {}
90
91 // ExtensionBrowserTest:
92 virtual void SetUpOnMainThread() OVERRIDE {
93 ExtensionBrowserTest::SetUpOnMainThread();
94
95 fake_drive_service_.reset(new drive::FakeDriveService);
96 fake_drive_service_->LoadAppListForDriveApi("drive/applist_empty.json");
97 apps_registry_.reset(
98 new drive::DriveAppRegistry(fake_drive_service_.get()));
99
100 model_.reset(new app_list::test::AppListTestModel);
101 model_builder_.reset(new TestModelBuilder(profile(), model_.get()));
102
103 provider_.reset(new DriveAppProvider(profile(), model_.get()));
104 provider_->SetDriveServiceBridgeForTest(
105 make_scoped_ptr(new TestDriveServiceBridge(apps_registry_.get()))
106 .PassAs<DriveServiceBridge>());
107 }
108
109 virtual void CleanUpOnMainThread() OVERRIDE {
110 provider_.reset();
111 apps_registry_.reset();
112 fake_drive_service_.reset();
113 model_builder_.reset();
114
115 ExtensionBrowserTest::CleanUpOnMainThread();
116 }
117
118 const Extension* InstallChromeApp(int expected_change) {
119 base::FilePath test_data_path;
120 if (!PathService::Get(chrome::DIR_TEST_DATA, &test_data_path)) {
121 ADD_FAILURE();
122 return NULL;
123 }
124 test_data_path =
125 test_data_path.AppendASCII("extensions").AppendASCII("hosted_app.crx");
126 const Extension* extension =
127 InstallExtension(test_data_path, expected_change);
128 return extension;
129 }
130
131 void RefreshDriveAppRegistry() {
132 apps_registry_->Update();
133 content::RunAllPendingInMessageLoop();
134 }
135
136 void WaitForPendingDriveAppConverters() {
137 DCHECK(!runner_);
138
139 if (provider_->pending_converters_.empty())
140 return;
141
142 runner_ = new content::MessageLoopRunner;
143
144 pending_drive_app_converter_check_timer_.Start(
145 FROM_HERE,
146 base::TimeDelta::FromMilliseconds(50),
147 base::Bind(&DriveAppProviderTest::OnPendingDriveAppConverterCheckTimer,
148 base::Unretained(this)));
149
150 runner_->Run();
151
152 pending_drive_app_converter_check_timer_.Stop();
153 runner_ = NULL;
154 }
155
156 drive::FakeDriveService* fake_drive_service() {
157 return fake_drive_service_.get();
158 }
159 app_list::test::AppListTestModel* model() { return model_.get(); }
160 DriveAppProvider* provider() { return provider_.get(); }
161 DriveAppMapping* mapping() { return provider_->mapping_.get(); }
162
163 private:
164 void OnPendingDriveAppConverterCheckTimer() {
165 if (provider_->pending_converters_.empty())
166 runner_->Quit();
167 }
168
169 scoped_ptr<drive::FakeDriveService> fake_drive_service_;
170 scoped_ptr<drive::DriveAppRegistry> apps_registry_;
171 scoped_ptr<TestModelBuilder> model_builder_;
172 scoped_ptr<app_list::test::AppListTestModel> model_;
173 scoped_ptr<DriveAppProvider> provider_;
174
175 base::RepeatingTimer<DriveAppProviderTest>
176 pending_drive_app_converter_check_timer_;
177 scoped_refptr<content::MessageLoopRunner> runner_;
178
179 DISALLOW_COPY_AND_ASSIGN(DriveAppProviderTest);
180 };
181
182 // A Drive app maps to an existing Chrome app that has a matching id.
183 // Uninstalling the chrome app would also disconnect the drive app.
184 IN_PROC_BROWSER_TEST_F(DriveAppProviderTest, ExistingChromeApp) {
185 // Prepare an existing chrome app.
186 const Extension* chrome_app = InstallChromeApp(1);
187 ASSERT_TRUE(chrome_app);
188
189 // Prepare a Drive app that matches the chrome app id.
190 fake_drive_service()->AddApp(
191 kDriveAppId, kDriveAppName, chrome_app->id(), kLaunchUrl);
192 RefreshDriveAppRegistry();
193 WaitForPendingDriveAppConverters();
194
195 // The Drive app should use the matching chrome app.
196 EXPECT_EQ(chrome_app->id(), mapping()->GetChromeApp(kDriveAppId));
197
198 // Unintalling chrome app should disconnect the Drive app on server.
199 EXPECT_TRUE(fake_drive_service()->HasApp(kDriveAppId));
200 UninstallExtension(chrome_app->id());
201 EXPECT_FALSE(fake_drive_service()->HasApp(kDriveAppId));
202 }
203
204 // A Drive app creates an URL app when no matching Chrome app presents.
205 IN_PROC_BROWSER_TEST_F(DriveAppProviderTest, CreateUrlApp) {
206 // Prepare a Drive app with no underlying chrome app.
207 fake_drive_service()->AddApp(kDriveAppId, kDriveAppName, "", kLaunchUrl);
208 RefreshDriveAppRegistry();
209 WaitForPendingDriveAppConverters();
210
211 // An Url app should be created.
212 const Extension* chrome_app =
213 ExtensionRegistry::Get(profile())->GetExtensionById(
214 mapping()->GetChromeApp(kDriveAppId), ExtensionRegistry::EVERYTHING);
215 ASSERT_TRUE(chrome_app);
216 EXPECT_EQ(kDriveAppName, chrome_app->name());
217 EXPECT_TRUE(chrome_app->is_hosted_app());
218 EXPECT_TRUE(chrome_app->from_bookmark());
219 EXPECT_EQ(GURL(kLaunchUrl), AppLaunchInfo::GetLaunchWebURL(chrome_app));
220
221 EXPECT_EQ(chrome_app->id(), mapping()->GetChromeApp(kDriveAppId));
222
223 // Unintalling the chrome app should disconnect the Drive app on server.
224 EXPECT_TRUE(fake_drive_service()->HasApp(kDriveAppId));
225 UninstallExtension(chrome_app->id());
226 EXPECT_FALSE(fake_drive_service()->HasApp(kDriveAppId));
227 }
228
229 // A matching Chrome app replaces the created URL app.
230 IN_PROC_BROWSER_TEST_F(DriveAppProviderTest, MatchingChromeAppInstalled) {
231 // Prepare a Drive app that matches the not-yet-installed kChromeAppId.
232 fake_drive_service()->AddApp(
233 kDriveAppId, kDriveAppName, kChromeAppId, kLaunchUrl);
234 RefreshDriveAppRegistry();
235 WaitForPendingDriveAppConverters();
236
237 // An Url app should be created.
238 const Extension* url_app =
239 ExtensionRegistry::Get(profile())->GetExtensionById(
240 mapping()->GetChromeApp(kDriveAppId), ExtensionRegistry::EVERYTHING);
241 EXPECT_TRUE(url_app->is_hosted_app());
242 EXPECT_TRUE(url_app->from_bookmark());
243
244 const std::string url_app_id = url_app->id();
245 EXPECT_NE(kChromeAppId, url_app_id);
246 EXPECT_EQ(url_app_id, mapping()->GetChromeApp(kDriveAppId));
247
248 // Installs a chrome app with matching id.
249 InstallChromeApp(0);
250
251 // The Drive app should be mapped to chrome app.
252 EXPECT_EQ(kChromeAppId, mapping()->GetChromeApp(kDriveAppId));
253
254 // Url app should be auto uninstalled.
255 EXPECT_FALSE(ExtensionRegistry::Get(profile())->GetExtensionById(
256 url_app_id, ExtensionRegistry::EVERYTHING));
257 }
258
259 // Tests that the corresponding URL app is uninstalled when a Drive app is
260 // disconnected.
261 IN_PROC_BROWSER_TEST_F(DriveAppProviderTest,
262 DisconnectDriveAppUninstallUrlApp) {
263 // Prepare a Drive app that matches the not-yet-installed kChromeAppId.
264 fake_drive_service()->AddApp(
265 kDriveAppId, kDriveAppName, kChromeAppId, kLaunchUrl);
266 RefreshDriveAppRegistry();
267 WaitForPendingDriveAppConverters();
268
269 // Url app is created.
270 const std::string url_app_id = mapping()->GetChromeApp(kDriveAppId);
271 EXPECT_TRUE(ExtensionRegistry::Get(profile())->GetExtensionById(
272 url_app_id, ExtensionRegistry::EVERYTHING));
273
274 fake_drive_service()->RemoveAppByProductId(kChromeAppId);
275 RefreshDriveAppRegistry();
276
277 // Url app is auto uninstalled.
278 EXPECT_FALSE(ExtensionRegistry::Get(profile())->GetExtensionById(
279 url_app_id, ExtensionRegistry::EVERYTHING));
280 }
281
282 // Tests that the matching Chrome app is preserved when a Drive app is
283 // disconnected.
284 IN_PROC_BROWSER_TEST_F(DriveAppProviderTest,
285 DisconnectDriveAppPreserveChromeApp) {
286 // Prepare an existing chrome app.
287 const Extension* chrome_app = InstallChromeApp(1);
288 ASSERT_TRUE(chrome_app);
289
290 // Prepare a Drive app that matches the chrome app id.
291 fake_drive_service()->AddApp(
292 kDriveAppId, kDriveAppName, kChromeAppId, kLaunchUrl);
293 RefreshDriveAppRegistry();
294 WaitForPendingDriveAppConverters();
295
296 fake_drive_service()->RemoveAppByProductId(kChromeAppId);
297 RefreshDriveAppRegistry();
298
299 // Chrome app is still present after the Drive app is disconnected.
300 EXPECT_TRUE(ExtensionRegistry::Get(profile())->GetExtensionById(
301 kChromeAppId, ExtensionRegistry::EVERYTHING));
302 }
303
304 // A new URL app replaces the existing one and keeps existing// position when a
305 // Drive app changes its name or URL.
306 IN_PROC_BROWSER_TEST_F(DriveAppProviderTest, DriveAppChanged) {
307 // Prepare a Drive app with no underlying chrome app.
308 fake_drive_service()->AddApp(
309 kDriveAppId, kDriveAppName, kChromeAppId, kLaunchUrl);
310 RefreshDriveAppRegistry();
311 WaitForPendingDriveAppConverters();
312
313 // An Url app should be created.
314 const std::string url_app_id = mapping()->GetChromeApp(kDriveAppId);
315 const Extension* url_app =
316 ExtensionRegistry::Get(profile())
317 ->GetExtensionById(url_app_id, ExtensionRegistry::EVERYTHING);
318 ASSERT_TRUE(url_app);
319 EXPECT_EQ(kDriveAppName, url_app->name());
320 EXPECT_TRUE(url_app->is_hosted_app());
321 EXPECT_TRUE(url_app->from_bookmark());
322 EXPECT_EQ(GURL(kLaunchUrl), AppLaunchInfo::GetLaunchWebURL(url_app));
323
324 // Put url app into a test folder position.
325 const char kTestFolder[] = "test-folder";
326 const size_t kExpectedIndex = 3;
327 for (size_t i = 0; i < kExpectedIndex; ++i) {
328 model()->AddItemToFolder(
329 model()->CreateItem(model()->GetItemName(static_cast<int>(i))),
330 kTestFolder);
331 }
332 app_list::AppListFolderItem* folder = model()->FindFolderItem(kTestFolder);
333 ASSERT_TRUE(folder);
334 model()->MoveItemToFolderAt(model()->FindItem(url_app->id()),
335 kTestFolder,
336 folder->item_list()
337 ->item_at(kExpectedIndex - 1)
338 ->position()
339 .CreateAfter());
340
341 // Register the Drive app with a different name and URL.
342 const char kAnotherName[] = "Another drive app name";
343 const char kAnotherLaunchUrl[] = "http://example.com/another_end_point";
344 fake_drive_service()->RemoveAppByProductId(kChromeAppId);
345 fake_drive_service()->AddApp(
346 kDriveAppId, kAnotherName, kChromeAppId, kAnotherLaunchUrl);
347 RefreshDriveAppRegistry();
348 WaitForPendingDriveAppConverters();
349
350 // Old URL app should be auto uninstalled.
351 url_app = ExtensionRegistry::Get(profile())
352 ->GetExtensionById(url_app_id, ExtensionRegistry::EVERYTHING);
353 EXPECT_FALSE(url_app);
354
355 // New URL app should be used.
356 const std::string new_url_app_id = mapping()->GetChromeApp(kDriveAppId);
357 EXPECT_NE(new_url_app_id, url_app_id);
358
359 const Extension* new_url_app =
360 ExtensionRegistry::Get(profile())
361 ->GetExtensionById(new_url_app_id, ExtensionRegistry::EVERYTHING);
362 ASSERT_TRUE(new_url_app);
363 EXPECT_EQ(kAnotherName, new_url_app->name());
364 EXPECT_TRUE(new_url_app->is_hosted_app());
365 EXPECT_TRUE(new_url_app->from_bookmark());
366 EXPECT_EQ(GURL(kAnotherLaunchUrl),
367 AppLaunchInfo::GetLaunchWebURL(new_url_app));
368
369 app_list::AppListItem* item = model()->FindItem(new_url_app_id);
370 ASSERT_TRUE(item);
371 EXPECT_EQ(kTestFolder, item->folder_id());
372 size_t item_index;
373 ASSERT_TRUE(folder->item_list()->FindItemIndex(new_url_app_id, &item_index));
374 EXPECT_EQ(kExpectedIndex, item_index);
375 }
376
377 // An existing URL app is not changed when underlying drive app data (name and
378 // URL) is not changed.
379 IN_PROC_BROWSER_TEST_F(DriveAppProviderTest, NoChange) {
380 // Prepare one Drive app.
381 fake_drive_service()->AddApp(
382 kDriveAppId, kDriveAppName, kChromeAppId, kLaunchUrl);
383 RefreshDriveAppRegistry();
384 WaitForPendingDriveAppConverters();
385
386 const std::string url_app_id = mapping()->GetChromeApp(kDriveAppId);
387 const Extension* url_app =
388 ExtensionRegistry::Get(profile())
389 ->GetExtensionById(url_app_id, ExtensionRegistry::EVERYTHING);
390
391 // Refresh with no actual change.
392 RefreshDriveAppRegistry();
393 WaitForPendingDriveAppConverters();
394
395 // Url app should remain unchanged.
396 const std::string new_url_app_id = mapping()->GetChromeApp(kDriveAppId);
397 EXPECT_EQ(new_url_app_id, url_app_id);
398
399 const Extension* new_url_app =
400 ExtensionRegistry::Get(profile())
401 ->GetExtensionById(new_url_app_id, ExtensionRegistry::EVERYTHING);
402 EXPECT_EQ(url_app, new_url_app);
403 }
404
405 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698