1 // Copyright 2013 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.
5 #include "chrome/browser/chromeos/file_manager/file_tasks.h"
10 #include "base/command_line.h"
11 #include "base/prefs/pref_registry_simple.h"
12 #include "base/prefs/testing_pref_service.h"
13 #include "base/values.h"
14 #include "chrome/browser/chromeos/drive/file_system_util.h"
15 #include "chrome/browser/chromeos/file_manager/app_id.h"
16 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
17 #include "chrome/browser/chromeos/settings/cros_settings.h"
18 #include "chrome/browser/chromeos/settings/device_settings_service.h"
19 #include "chrome/browser/drive/drive_app_registry.h"
20 #include "chrome/browser/extensions/extension_service.h"
21 #include "chrome/browser/extensions/test_extension_system.h"
22 #include "chrome/common/pref_names.h"
23 #include "chrome/test/base/testing_profile.h"
24 #include "content/public/test/test_browser_thread_bundle.h"
25 #include "extensions/browser/extension_prefs.h"
26 #include "extensions/browser/extension_system.h"
27 #include "extensions/common/extension_builder.h"
28 #include "google_apis/drive/drive_api_parser.h"
29 #include "testing/gtest/include/gtest/gtest.h"
32 namespace file_manager {
33 namespace file_tasks {
36 // Registers the default task preferences. Used for testing
37 // ChooseAndSetDefaultTask().
38 void RegisterDefaultTaskPreferences(TestingPrefServiceSimple* pref_service) {
41 pref_service->registry()->RegisterDictionaryPref(
42 prefs::kDefaultTasksByMimeType);
43 pref_service->registry()->RegisterDictionaryPref(
44 prefs::kDefaultTasksBySuffix);
47 // Updates the default task preferences per the given dictionary values. Used
48 // for testing ChooseAndSetDefaultTask.
49 void UpdateDefaultTaskPreferences(TestingPrefServiceSimple* pref_service,
50 const base::DictionaryValue& mime_types,
51 const base::DictionaryValue& suffixes) {
54 pref_service->Set(prefs::kDefaultTasksByMimeType, mime_types);
55 pref_service->Set(prefs::kDefaultTasksBySuffix, suffixes);
60 TEST(FileManagerFileTasksTest,
61 FullTaskDescriptor_NonDriveAppWithIconAndDefault) {
62 FullTaskDescriptor full_descriptor(
63 TaskDescriptor("app-id",
64 TASK_TYPE_FILE_BROWSER_HANDLER,
67 GURL("http://example.com/icon.png"),
68 true /* is_default */);
70 const std::string task_id =
71 TaskDescriptorToId(full_descriptor.task_descriptor());
72 EXPECT_EQ("app-id|file|action-id", task_id);
73 EXPECT_EQ("http://example.com/icon.png", full_descriptor.icon_url().spec());
74 EXPECT_EQ("task title", full_descriptor.task_title());
75 EXPECT_TRUE(full_descriptor.is_default());
78 TEST(FileManagerFileTasksTest,
79 FullTaskDescriptor_DriveAppWithoutIconAndNotDefault) {
80 FullTaskDescriptor full_descriptor(
81 TaskDescriptor("app-id",
85 GURL(), // No icon URL.
86 false /* is_default */);
88 const std::string task_id =
89 TaskDescriptorToId(full_descriptor.task_descriptor());
90 EXPECT_EQ("app-id|drive|action-id", task_id);
91 EXPECT_TRUE(full_descriptor.icon_url().is_empty());
92 EXPECT_EQ("task title", full_descriptor.task_title());
93 EXPECT_FALSE(full_descriptor.is_default());
96 TEST(FileManagerFileTasksTest, MakeTaskID) {
97 EXPECT_EQ("app-id|file|action-id",
98 MakeTaskID("app-id", TASK_TYPE_FILE_BROWSER_HANDLER, "action-id"));
99 EXPECT_EQ("app-id|app|action-id",
100 MakeTaskID("app-id", TASK_TYPE_FILE_HANDLER, "action-id"));
101 EXPECT_EQ("app-id|drive|action-id",
102 MakeTaskID("app-id", TASK_TYPE_DRIVE_APP, "action-id"));
105 TEST(FileManagerFileTasksTest, TaskDescriptorToId) {
106 EXPECT_EQ("app-id|file|action-id",
107 TaskDescriptorToId(TaskDescriptor("app-id",
108 TASK_TYPE_FILE_BROWSER_HANDLER,
112 TEST(FileManagerFileTasksTest, ParseTaskID_FileBrowserHandler) {
114 EXPECT_TRUE(ParseTaskID("app-id|file|action-id", &task));
115 EXPECT_EQ("app-id", task.app_id);
116 EXPECT_EQ(TASK_TYPE_FILE_BROWSER_HANDLER, task.task_type);
117 EXPECT_EQ("action-id", task.action_id);
120 TEST(FileManagerFileTasksTest, ParseTaskID_FileHandler) {
122 EXPECT_TRUE(ParseTaskID("app-id|app|action-id", &task));
123 EXPECT_EQ("app-id", task.app_id);
124 EXPECT_EQ(TASK_TYPE_FILE_HANDLER, task.task_type);
125 EXPECT_EQ("action-id", task.action_id);
128 TEST(FileManagerFileTasksTest, ParseTaskID_DriveApp) {
130 EXPECT_TRUE(ParseTaskID("app-id|drive|action-id", &task));
131 EXPECT_EQ("app-id", task.app_id);
132 EXPECT_EQ(TASK_TYPE_DRIVE_APP, task.task_type);
133 EXPECT_EQ("action-id", task.action_id);
136 TEST(FileManagerFileTasksTest, ParseTaskID_Legacy) {
138 // A legacy task ID only has two parts. The task type should be
139 // TASK_TYPE_FILE_BROWSER_HANDLER.
140 EXPECT_TRUE(ParseTaskID("app-id|action-id", &task));
141 EXPECT_EQ("app-id", task.app_id);
142 EXPECT_EQ(TASK_TYPE_FILE_BROWSER_HANDLER, task.task_type);
143 EXPECT_EQ("action-id", task.action_id);
146 TEST(FileManagerFileTasksTest, ParseTaskID_LegacyDrive) {
148 // A legacy task ID only has two parts. For Drive app, the app ID is
149 // prefixed with "drive-app:".
150 EXPECT_TRUE(ParseTaskID("drive-app:app-id|action-id", &task));
151 EXPECT_EQ("app-id", task.app_id);
152 EXPECT_EQ(TASK_TYPE_DRIVE_APP, task.task_type);
153 EXPECT_EQ("action-id", task.action_id);
156 TEST(FileManagerFileTasksTest, ParseTaskID_Invalid) {
158 EXPECT_FALSE(ParseTaskID("invalid", &task));
161 TEST(FileManagerFileTasksTest, ParseTaskID_UnknownTaskType) {
163 EXPECT_FALSE(ParseTaskID("app-id|unknown|action-id", &task));
166 TEST(FileManagerFileTasksTest, FindDriveAppTasks) {
167 TestingProfile profile;
168 // For DriveAppRegistry, which checks CurrentlyOn(BrowserThread::UI).
169 content::TestBrowserThreadBundle thread_bundle;
171 // Foo.app can handle "text/plain" and "text/html"
172 scoped_ptr<google_apis::AppResource> foo_app(new google_apis::AppResource);
173 foo_app->set_product_id("foo_app_id");
174 foo_app->set_application_id("foo_app_id");
175 foo_app->set_name("Foo");
176 foo_app->set_object_type("foo_object_type");
177 ScopedVector<std::string> foo_mime_types;
178 foo_mime_types.push_back(new std::string("text/plain"));
179 foo_mime_types.push_back(new std::string("text/html"));
180 foo_app->set_primary_mimetypes(foo_mime_types.Pass());
182 // Bar.app can only handle "text/plain".
183 scoped_ptr<google_apis::AppResource> bar_app(new google_apis::AppResource);
184 bar_app->set_product_id("bar_app_id");
185 bar_app->set_application_id("bar_app_id");
186 bar_app->set_name("Bar");
187 bar_app->set_object_type("bar_object_type");
188 ScopedVector<std::string> bar_mime_types;
189 bar_mime_types.push_back(new std::string("text/plain"));
190 bar_app->set_primary_mimetypes(bar_mime_types.Pass());
192 // Prepare DriveAppRegistry from Foo.app and Bar.app.
193 ScopedVector<google_apis::AppResource> app_resources;
194 app_resources.push_back(foo_app.release());
195 app_resources.push_back(bar_app.release());
196 google_apis::AppList app_list;
197 app_list.set_items(app_resources.Pass());
198 drive::DriveAppRegistry drive_app_registry(NULL);
199 drive_app_registry.UpdateFromAppList(app_list);
201 // Find apps for a "text/plain" file. Foo.app and Bar.app should be found.
202 PathAndMimeTypeSet path_mime_set;
203 path_mime_set.insert(
205 drive::util::GetDriveMountPointPath(&profile).AppendASCII("foo.txt"),
207 std::vector<FullTaskDescriptor> tasks;
208 FindDriveAppTasks(drive_app_registry,
211 ASSERT_EQ(2U, tasks.size());
212 // Sort the app IDs, as the order is not guaranteed.
213 std::vector<std::string> app_ids;
214 app_ids.push_back(tasks[0].task_descriptor().app_id);
215 app_ids.push_back(tasks[1].task_descriptor().app_id);
216 std::sort(app_ids.begin(), app_ids.end());
217 // Confirm that both Foo.app and Bar.app are found.
218 EXPECT_EQ("bar_app_id", app_ids[0]);
219 EXPECT_EQ("foo_app_id", app_ids[1]);
221 // Find apps for "text/plain" and "text/html" files. Only Foo.app should be
223 path_mime_set.clear();
224 path_mime_set.insert(
226 drive::util::GetDriveMountPointPath(&profile).AppendASCII("foo.txt"),
228 path_mime_set.insert(
230 drive::util::GetDriveMountPointPath(&profile).AppendASCII("foo.html"),
233 FindDriveAppTasks(drive_app_registry,
236 ASSERT_EQ(1U, tasks.size());
237 // Confirm that only Foo.app is found.
238 EXPECT_EQ("foo_app_id", tasks[0].task_descriptor().app_id);
240 // Add a "text/plain" file not on Drive. No tasks should be found.
241 path_mime_set.insert(
242 std::make_pair(base::FilePath::FromUTF8Unsafe("not_on_drive.txt"),
245 FindDriveAppTasks(drive_app_registry,
248 // Confirm no tasks are found.
249 ASSERT_TRUE(tasks.empty());
252 // Test that the right task is chosen from multiple choices per mime types
253 // and file extensions.
254 TEST(FileManagerFileTasksTest, ChooseAndSetDefaultTask_MultipleTasks) {
255 TestingPrefServiceSimple pref_service;
256 RegisterDefaultTaskPreferences(&pref_service);
258 // Text.app and Nice.app were found for "foo.txt".
259 TaskDescriptor text_app_task("text-app-id",
260 TASK_TYPE_FILE_HANDLER,
262 TaskDescriptor nice_app_task("nice-app-id",
263 TASK_TYPE_FILE_HANDLER,
265 std::vector<FullTaskDescriptor> tasks;
266 tasks.push_back(FullTaskDescriptor(
269 GURL("http://example.com/text_app.png"),
270 false /* is_default */));
271 tasks.push_back(FullTaskDescriptor(
274 GURL("http://example.com/nice_app.png"),
275 false /* is_default */));
276 PathAndMimeTypeSet path_mime_set;
277 path_mime_set.insert(std::make_pair(
278 base::FilePath::FromUTF8Unsafe("foo.txt"),
281 // None of them should be chosen as default, as nothing is set in the
283 ChooseAndSetDefaultTask(pref_service, path_mime_set, &tasks);
284 EXPECT_FALSE(tasks[0].is_default());
285 EXPECT_FALSE(tasks[1].is_default());
287 // Set Text.app as default for "text/plain" in the preferences.
288 base::DictionaryValue empty;
289 base::DictionaryValue mime_types;
290 mime_types.SetStringWithoutPathExpansion(
292 TaskDescriptorToId(text_app_task));
293 UpdateDefaultTaskPreferences(&pref_service, mime_types, empty);
295 // Text.app should be chosen as default.
296 ChooseAndSetDefaultTask(pref_service, path_mime_set, &tasks);
297 EXPECT_TRUE(tasks[0].is_default());
298 EXPECT_FALSE(tasks[1].is_default());
300 // Change it back to non-default for testing further.
301 tasks[0].set_is_default(false);
303 // Clear the preferences and make sure none of them are default.
304 UpdateDefaultTaskPreferences(&pref_service, empty, empty);
305 ChooseAndSetDefaultTask(pref_service, path_mime_set, &tasks);
306 EXPECT_FALSE(tasks[0].is_default());
307 EXPECT_FALSE(tasks[1].is_default());
309 // Set Nice.app as default for ".txt" in the preferences.
310 base::DictionaryValue suffixes;
311 suffixes.SetStringWithoutPathExpansion(
313 TaskDescriptorToId(nice_app_task));
314 UpdateDefaultTaskPreferences(&pref_service, empty, suffixes);
316 // Now Nice.app should be chosen as default.
317 ChooseAndSetDefaultTask(pref_service, path_mime_set, &tasks);
318 EXPECT_FALSE(tasks[0].is_default());
319 EXPECT_TRUE(tasks[1].is_default());
322 // Test that Files.app's internal file browser handler is chosen as default
323 // even if nothing is set in the preferences.
324 TEST(FileManagerFileTasksTest, ChooseAndSetDefaultTask_FallbackFileBrowser) {
325 TestingPrefServiceSimple pref_service;
326 RegisterDefaultTaskPreferences(&pref_service);
328 // Files.app's internal file browser handler was found for "foo.txt".
329 TaskDescriptor files_app_task(kFileManagerAppId,
330 TASK_TYPE_FILE_BROWSER_HANDLER,
332 std::vector<FullTaskDescriptor> tasks;
333 tasks.push_back(FullTaskDescriptor(
336 GURL("http://example.com/some_icon.png"),
337 false /* is_default */));
338 PathAndMimeTypeSet path_mime_set;
339 path_mime_set.insert(std::make_pair(
340 base::FilePath::FromUTF8Unsafe("foo.txt"),
343 // The internal file browser handler should be chosen as default, as it's a
344 // fallback file browser handler.
345 ChooseAndSetDefaultTask(pref_service, path_mime_set, &tasks);
346 EXPECT_TRUE(tasks[0].is_default());
349 // Test using the test extension system, which needs lots of setup.
350 class FileManagerFileTasksComplexTest : public testing::Test {
352 FileManagerFileTasksComplexTest()
353 : command_line_(CommandLine::NO_PROGRAM),
354 extension_service_(NULL) {
355 extensions::TestExtensionSystem* test_extension_system =
356 static_cast<extensions::TestExtensionSystem*>(
357 extensions::ExtensionSystem::Get(&test_profile_));
358 extension_service_ = test_extension_system->CreateExtensionService(
360 base::FilePath() /* install_directory */,
361 false /* autoupdate_enabled*/);
364 content::TestBrowserThreadBundle thread_bundle_;
365 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
366 chromeos::ScopedTestCrosSettings test_cros_settings_;
367 chromeos::ScopedTestUserManager test_user_manager_;
368 TestingProfile test_profile_;
369 CommandLine command_line_;
370 ExtensionService* extension_service_; // Owned by test_profile_;
373 // The basic logic is similar to a test case for FindDriveAppTasks above.
374 TEST_F(FileManagerFileTasksComplexTest, FindFileHandlerTasks) {
375 // Random IDs generated by
376 // % ruby -le 'print (0...32).to_a.map{(?a + rand(16)).chr}.join'
377 const char kFooId[] = "hhgbjpmdppecanaaogonaigmmifgpaph";
378 const char kBarId[] = "odlhccgofgkadkkhcmhgnhgahonahoca";
379 const char kEphemeralId[] = "opoomfdlbjcbjinalcjdjfoiikdeaoel";
381 // Foo.app can handle "text/plain" and "text/html".
382 extensions::ExtensionBuilder foo_app;
383 foo_app.SetManifest(extensions::DictionaryBuilder()
385 .Set("version", "1.0.0")
386 .Set("manifest_version", 2)
388 extensions::DictionaryBuilder()
390 extensions::DictionaryBuilder()
392 extensions::ListBuilder()
393 .Append("background.js"))))
394 .Set("file_handlers",
395 extensions::DictionaryBuilder()
397 extensions::DictionaryBuilder()
398 .Set("title", "Text")
400 extensions::ListBuilder()
401 .Append("text/plain")
402 .Append("text/html")))));
403 foo_app.SetID(kFooId);
404 extension_service_->AddExtension(foo_app.Build().get());
406 // Bar.app can only handle "text/plain".
407 extensions::ExtensionBuilder bar_app;
408 bar_app.SetManifest(extensions::DictionaryBuilder()
410 .Set("version", "1.0.0")
411 .Set("manifest_version", 2)
413 extensions::DictionaryBuilder()
415 extensions::DictionaryBuilder()
417 extensions::ListBuilder()
418 .Append("background.js"))))
419 .Set("file_handlers",
420 extensions::DictionaryBuilder()
422 extensions::DictionaryBuilder()
423 .Set("title", "Text")
425 extensions::ListBuilder()
426 .Append("text/plain")))));
427 bar_app.SetID(kBarId);
428 extension_service_->AddExtension(bar_app.Build().get());
430 // Ephemeral.app is an ephemeral app that can handle "text/plain".
431 // It should not ever be found as ephemeral apps cannot be file handlers.
432 extensions::ExtensionBuilder ephemeral_app;
433 ephemeral_app.SetManifest(
434 extensions::DictionaryBuilder()
435 .Set("name", "Ephemeral")
436 .Set("version", "1.0.0")
437 .Set("manifest_version", 2)
439 extensions::DictionaryBuilder().Set(
441 extensions::DictionaryBuilder().Set(
443 extensions::ListBuilder().Append("background.js"))))
444 .Set("file_handlers",
445 extensions::DictionaryBuilder().Set(
447 extensions::DictionaryBuilder().Set("title", "Text").Set(
449 extensions::ListBuilder().Append("text/plain")))));
450 ephemeral_app.SetID(kEphemeralId);
451 scoped_refptr<extensions::Extension> built_ephemeral_app(
452 ephemeral_app.Build());
453 extension_service_->AddExtension(built_ephemeral_app.get());
454 extensions::ExtensionPrefs* extension_prefs =
455 extensions::ExtensionPrefs::Get(&test_profile_);
456 extension_prefs->OnExtensionInstalled(built_ephemeral_app.get(),
457 extensions::Extension::ENABLED,
458 syncer::StringOrdinal(),
459 extensions::kInstallFlagIsEphemeral,
462 // Find apps for a "text/plain" file. Foo.app and Bar.app should be found.
463 PathAndMimeTypeSet path_mime_set;
464 path_mime_set.insert(
466 drive::util::GetDriveMountPointPath(&test_profile_).AppendASCII(
470 std::vector<FullTaskDescriptor> tasks;
471 FindFileHandlerTasks(&test_profile_, path_mime_set, &tasks);
472 ASSERT_EQ(2U, tasks.size());
473 // Sort the app IDs, as the order is not guaranteed.
474 std::vector<std::string> app_ids;
475 app_ids.push_back(tasks[0].task_descriptor().app_id);
476 app_ids.push_back(tasks[1].task_descriptor().app_id);
477 std::sort(app_ids.begin(), app_ids.end());
478 // Confirm that both Foo.app and Bar.app are found.
479 EXPECT_EQ(kFooId, app_ids[0]);
480 EXPECT_EQ(kBarId, app_ids[1]);
482 // Find apps for "text/plain" and "text/html" files. Only Foo.app should be
484 path_mime_set.clear();
485 path_mime_set.insert(
487 drive::util::GetDriveMountPointPath(&test_profile_).AppendASCII(
490 path_mime_set.insert(
492 drive::util::GetDriveMountPointPath(&test_profile_).AppendASCII(
496 FindFileHandlerTasks(&test_profile_, path_mime_set, &tasks);
497 ASSERT_EQ(1U, tasks.size());
498 // Confirm that only Foo.app is found.
499 EXPECT_EQ(kFooId, tasks[0].task_descriptor().app_id);
501 // Add an "image/png" file. No tasks should be found.
502 path_mime_set.insert(
503 std::make_pair(base::FilePath::FromUTF8Unsafe("foo.png"),
506 FindFileHandlerTasks(&test_profile_, path_mime_set, &tasks);
507 // Confirm no tasks are found.
508 ASSERT_TRUE(tasks.empty());
511 // The basic logic is similar to a test case for FindDriveAppTasks above.
512 TEST_F(FileManagerFileTasksComplexTest, FindFileBrowserHandlerTasks) {
513 // Copied from FindFileHandlerTasks test above.
514 const char kFooId[] = "hhgbjpmdppecanaaogonaigmmifgpaph";
515 const char kBarId[] = "odlhccgofgkadkkhcmhgnhgahonahoca";
516 const char kEphemeralId[] = "opoomfdlbjcbjinalcjdjfoiikdeaoel";
518 // Foo.app can handle ".txt" and ".html".
519 // This one is an extension, and has "file_browser_handlers"
520 extensions::ExtensionBuilder foo_app;
521 foo_app.SetManifest(extensions::DictionaryBuilder()
523 .Set("version", "1.0.0")
524 .Set("manifest_version", 2)
525 .Set("file_browser_handlers",
526 extensions::ListBuilder()
527 .Append(extensions::DictionaryBuilder()
529 .Set("default_title", "open")
531 extensions::ListBuilder()
532 .Append("filesystem:*.txt")
533 .Append("filesystem:*.html")))));
534 foo_app.SetID(kFooId);
535 extension_service_->AddExtension(foo_app.Build().get());
537 // Bar.app can only handle ".txt".
538 extensions::ExtensionBuilder bar_app;
539 bar_app.SetManifest(extensions::DictionaryBuilder()
541 .Set("version", "1.0.0")
542 .Set("manifest_version", 2)
543 .Set("file_browser_handlers",
544 extensions::ListBuilder()
545 .Append(extensions::DictionaryBuilder()
547 .Set("default_title", "open")
549 extensions::ListBuilder()
550 .Append("filesystem:*.txt")))));
551 bar_app.SetID(kBarId);
552 extension_service_->AddExtension(bar_app.Build().get());
554 // Ephemeral.app is an ephemeral app that can handle ".txt".
555 // It should not ever be found as ephemeral apps cannot be file browser
557 extensions::ExtensionBuilder ephemeral_app;
558 ephemeral_app.SetManifest(
559 extensions::DictionaryBuilder()
560 .Set("name", "Ephemeral")
561 .Set("version", "1.0.0")
562 .Set("manifest_version", 2)
563 .Set("file_browser_handlers",
564 extensions::ListBuilder().Append(
565 extensions::DictionaryBuilder()
567 .Set("default_title", "open")
569 extensions::ListBuilder().Append(
570 "filesystem:*.txt")))));
571 ephemeral_app.SetID(kEphemeralId);
572 scoped_refptr<extensions::Extension> built_ephemeral_app(
573 ephemeral_app.Build());
574 extension_service_->AddExtension(built_ephemeral_app.get());
575 extensions::ExtensionPrefs* extension_prefs =
576 extensions::ExtensionPrefs::Get(&test_profile_);
577 extension_prefs->OnExtensionInstalled(built_ephemeral_app.get(),
578 extensions::Extension::ENABLED,
579 syncer::StringOrdinal(),
580 extensions::kInstallFlagIsEphemeral,
583 // Find apps for a ".txt" file. Foo.app and Bar.app should be found.
584 std::vector<GURL> file_urls;
585 file_urls.push_back(GURL("filesystem:chrome-extension://id/dir/foo.txt"));
587 std::vector<FullTaskDescriptor> tasks;
588 FindFileBrowserHandlerTasks(&test_profile_, file_urls, &tasks);
589 ASSERT_EQ(2U, tasks.size());
590 // Sort the app IDs, as the order is not guaranteed.
591 std::vector<std::string> app_ids;
592 app_ids.push_back(tasks[0].task_descriptor().app_id);
593 app_ids.push_back(tasks[1].task_descriptor().app_id);
594 std::sort(app_ids.begin(), app_ids.end());
595 // Confirm that both Foo.app and Bar.app are found.
596 EXPECT_EQ(kFooId, app_ids[0]);
597 EXPECT_EQ(kBarId, app_ids[1]);
599 // Find apps for ".txt" and ".html" files. Only Foo.app should be found.
601 file_urls.push_back(GURL("filesystem:chrome-extension://id/dir/foo.txt"));
602 file_urls.push_back(GURL("filesystem:chrome-extension://id/dir/foo.html"));
604 FindFileBrowserHandlerTasks(&test_profile_, file_urls, &tasks);
605 ASSERT_EQ(1U, tasks.size());
606 // Confirm that only Foo.app is found.
607 EXPECT_EQ(kFooId, tasks[0].task_descriptor().app_id);
609 // Add an ".png" file. No tasks should be found.
610 file_urls.push_back(GURL("filesystem:chrome-extension://id/dir/foo.png"));
612 FindFileBrowserHandlerTasks(&test_profile_, file_urls, &tasks);
613 // Confirm no tasks are found.
614 ASSERT_TRUE(tasks.empty());
617 // Test that all kinds of apps (file handler, file browser handler, and Drive
618 // app) are returned.
619 TEST_F(FileManagerFileTasksComplexTest, FindAllTypesOfTasks) {
620 // kFooId and kBarId copied from FindFileHandlerTasks test above.
621 const char kFooId[] = "hhgbjpmdppecanaaogonaigmmifgpaph";
622 const char kBarId[] = "odlhccgofgkadkkhcmhgnhgahonahoca";
623 const char kBazId[] = "plifkpkakemokpflgbnnigcoldgcbdmc";
625 // Foo.app can handle "text/plain".
626 // This is a packaged app (file handler).
627 extensions::ExtensionBuilder foo_app;
628 foo_app.SetManifest(extensions::DictionaryBuilder()
630 .Set("version", "1.0.0")
631 .Set("manifest_version", 2)
633 extensions::DictionaryBuilder()
635 extensions::DictionaryBuilder()
637 extensions::ListBuilder()
638 .Append("background.js"))))
639 .Set("file_handlers",
640 extensions::DictionaryBuilder()
642 extensions::DictionaryBuilder()
643 .Set("title", "Text")
645 extensions::ListBuilder()
646 .Append("text/plain")))));
647 foo_app.SetID(kFooId);
648 extension_service_->AddExtension(foo_app.Build().get());
650 // Bar.app can only handle ".txt".
651 // This is an extension (file browser handler).
652 extensions::ExtensionBuilder bar_app;
653 bar_app.SetManifest(extensions::DictionaryBuilder()
655 .Set("version", "1.0.0")
656 .Set("manifest_version", 2)
657 .Set("file_browser_handlers",
658 extensions::ListBuilder()
659 .Append(extensions::DictionaryBuilder()
661 .Set("default_title", "open")
663 extensions::ListBuilder()
664 .Append("filesystem:*.txt")))));
665 bar_app.SetID(kBarId);
666 extension_service_->AddExtension(bar_app.Build().get());
668 // Baz.app can handle "text/plain".
669 // This is a Drive app.
670 scoped_ptr<google_apis::AppResource> baz_app(new google_apis::AppResource);
671 baz_app->set_product_id("baz_app_id");
672 baz_app->set_application_id(kBazId);
673 baz_app->set_name("Baz");
674 baz_app->set_object_type("baz_object_type");
675 ScopedVector<std::string> baz_mime_types;
676 baz_mime_types.push_back(new std::string("text/plain"));
677 baz_app->set_primary_mimetypes(baz_mime_types.Pass());
678 // Set up DriveAppRegistry.
679 ScopedVector<google_apis::AppResource> app_resources;
680 app_resources.push_back(baz_app.release());
681 google_apis::AppList app_list;
682 app_list.set_items(app_resources.Pass());
683 drive::DriveAppRegistry drive_app_registry(NULL);
684 drive_app_registry.UpdateFromAppList(app_list);
686 // Find apps for "foo.txt". All apps should be found.
687 PathAndMimeTypeSet path_mime_set;
688 std::vector<GURL> file_urls;
689 path_mime_set.insert(
691 drive::util::GetDriveMountPointPath(&test_profile_).AppendASCII(
694 file_urls.push_back(GURL("filesystem:chrome-extension://id/dir/foo.txt"));
696 std::vector<FullTaskDescriptor> tasks;
697 FindAllTypesOfTasks(&test_profile_,
702 ASSERT_EQ(3U, tasks.size());
704 // Sort the app IDs, as the order is not guaranteed.
705 std::vector<std::string> app_ids;
706 app_ids.push_back(tasks[0].task_descriptor().app_id);
707 app_ids.push_back(tasks[1].task_descriptor().app_id);
708 app_ids.push_back(tasks[2].task_descriptor().app_id);
709 std::sort(app_ids.begin(), app_ids.end());
710 // Confirm that all apps are found.
711 EXPECT_EQ(kFooId, app_ids[0]);
712 EXPECT_EQ(kBarId, app_ids[1]);
713 EXPECT_EQ(kBazId, app_ids[2]);
716 TEST_F(FileManagerFileTasksComplexTest, FindAllTypesOfTasks_GoogleDocument) {
717 // kFooId and kBarId copied from FindFileHandlerTasks test above.
718 const char kFooId[] = "hhgbjpmdppecanaaogonaigmmifgpaph";
719 const char kBarId[] = "odlhccgofgkadkkhcmhgnhgahonahoca";
721 // Foo.app can handle ".gdoc" files.
722 scoped_ptr<google_apis::AppResource> foo_app(new google_apis::AppResource);
723 foo_app->set_product_id("foo_app");
724 foo_app->set_application_id(kFooId);
725 foo_app->set_name("Foo");
726 foo_app->set_object_type("foo_object_type");
727 ScopedVector<std::string> foo_extensions;
728 foo_extensions.push_back(new std::string("gdoc")); // Not ".gdoc"
729 foo_app->set_primary_file_extensions(foo_extensions.Pass());
731 // Prepare DriveAppRegistry from Foo.app.
732 ScopedVector<google_apis::AppResource> app_resources;
733 app_resources.push_back(foo_app.release());
734 google_apis::AppList app_list;
735 app_list.set_items(app_resources.Pass());
736 drive::DriveAppRegistry drive_app_registry(NULL);
737 drive_app_registry.UpdateFromAppList(app_list);
739 // Bar.app can handle ".gdoc" files.
740 // This is an extension (file browser handler).
741 extensions::ExtensionBuilder bar_app;
742 bar_app.SetManifest(extensions::DictionaryBuilder()
744 .Set("version", "1.0.0")
745 .Set("manifest_version", 2)
746 .Set("file_browser_handlers",
747 extensions::ListBuilder()
748 .Append(extensions::DictionaryBuilder()
750 .Set("default_title", "open")
752 extensions::ListBuilder()
753 .Append("filesystem:*.gdoc")))));
754 bar_app.SetID(kBarId);
755 extension_service_->AddExtension(bar_app.Build().get());
757 // Files.app can handle ".gdoc" files.
758 // The ID "kFileManagerAppId" used here is precisely the one that identifies
759 // the Chrome OS Files.app application.
760 extensions::ExtensionBuilder files_app;
761 files_app.SetManifest(extensions::DictionaryBuilder()
762 .Set("name", "Files")
763 .Set("version", "1.0.0")
764 .Set("manifest_version", 2)
765 .Set("file_browser_handlers",
766 extensions::ListBuilder()
767 .Append(extensions::DictionaryBuilder()
769 .Set("default_title", "open")
771 extensions::ListBuilder()
772 .Append("filesystem:*.gdoc")))));
773 files_app.SetID(kFileManagerAppId);
774 extension_service_->AddExtension(files_app.Build().get());
776 // Find apps for a ".gdoc file". Only the built-in handler of Files.apps
778 PathAndMimeTypeSet path_mime_set;
779 std::vector<GURL> file_urls;
780 path_mime_set.insert(
782 drive::util::GetDriveMountPointPath(&test_profile_).AppendASCII(
784 "application/vnd.google-apps.document"));
785 file_urls.push_back(GURL("filesystem:chrome-extension://id/dir/foo.gdoc"));
787 std::vector<FullTaskDescriptor> tasks;
788 FindAllTypesOfTasks(&test_profile_,
793 ASSERT_EQ(1U, tasks.size());
794 EXPECT_EQ(kFileManagerAppId, tasks[0].task_descriptor().app_id);
797 } // namespace file_tasks
798 } // namespace file_manager.