| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/bind.h" | 5 #include "base/bind.h" |
| 6 #include "base/file_path.h" | 6 #include "base/file_path.h" |
| 7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
| 8 #include "base/files/scoped_temp_dir.h" | 8 #include "base/files/scoped_temp_dir.h" |
| 9 #include "base/json/json_file_value_serializer.h" | 9 #include "base/json/json_file_value_serializer.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| 11 #include "base/message_loop_proxy.h" | 11 #include "base/message_loop_proxy.h" |
| 12 #include "base/path_service.h" | 12 #include "base/path_service.h" |
| 13 #include "base/threading/worker_pool.h" | 13 #include "base/threading/worker_pool.h" |
| 14 #include "base/values.h" | 14 #include "base/values.h" |
| 15 #include "chrome/browser/chromeos/drive/drive_file_system.h" | 15 #include "chrome/browser/chromeos/drive/drive_file_system.h" |
| 16 #include "chrome/browser/chromeos/drive/drive_system_service.h" | 16 #include "chrome/browser/chromeos/drive/drive_system_service.h" |
| 17 #include "chrome/browser/extensions/event_router.h" | 17 #include "chrome/browser/extensions/event_router.h" |
| 18 #include "chrome/browser/extensions/extension_apitest.h" | 18 #include "chrome/browser/extensions/extension_apitest.h" |
| 19 #include "chrome/browser/extensions/extension_service.h" | 19 #include "chrome/browser/extensions/extension_service.h" |
| 20 #include "chrome/browser/extensions/extension_system.h" | 20 #include "chrome/browser/extensions/extension_system.h" |
| 21 #include "chrome/browser/extensions/extension_test_message_listener.h" | 21 #include "chrome/browser/extensions/extension_test_message_listener.h" |
| 22 #include "chrome/browser/google_apis/dummy_drive_service.h" | 22 #include "chrome/browser/google_apis/fake_drive_service.h" |
| 23 #include "chrome/browser/google_apis/gdata_wapi_parser.h" | 23 #include "chrome/browser/google_apis/gdata_wapi_parser.h" |
| 24 #include "chrome/browser/google_apis/test_util.h" | 24 #include "chrome/browser/google_apis/test_util.h" |
| 25 #include "chrome/browser/google_apis/time_util.h" | 25 #include "chrome/browser/google_apis/time_util.h" |
| 26 #include "chrome/browser/profiles/profile.h" | 26 #include "chrome/browser/profiles/profile.h" |
| 27 #include "chrome/browser/ui/browser.h" | 27 #include "chrome/browser/ui/browser.h" |
| 28 #include "chrome/common/chrome_notification_types.h" | 28 #include "chrome/common/chrome_notification_types.h" |
| 29 #include "chrome/common/chrome_paths.h" | 29 #include "chrome/common/chrome_paths.h" |
| 30 #include "chrome/common/chrome_switches.h" | 30 #include "chrome/common/chrome_switches.h" |
| 31 #include "chrome/test/base/ui_test_utils.h" | 31 #include "chrome/test/base/ui_test_utils.h" |
| 32 #include "content/public/browser/browser_context.h" | 32 #include "content/public/browser/browser_context.h" |
| 33 #include "content/public/browser/browser_thread.h" | 33 #include "content/public/browser/browser_thread.h" |
| 34 #include "content/public/browser/notification_service.h" | 34 #include "content/public/browser/notification_service.h" |
| 35 #include "content/public/browser/storage_partition.h" | 35 #include "content/public/browser/storage_partition.h" |
| 36 #include "content/public/test/test_utils.h" | 36 #include "content/public/test/test_utils.h" |
| 37 #include "webkit/fileapi/file_system_context.h" | 37 #include "webkit/fileapi/file_system_context.h" |
| 38 #include "webkit/fileapi/file_system_mount_point_provider.h" | 38 #include "webkit/fileapi/file_system_mount_point_provider.h" |
| 39 | 39 |
| 40 using content::BrowserContext; | 40 using content::BrowserContext; |
| 41 using extensions::Extension; | 41 using extensions::Extension; |
| 42 | 42 |
| 43 namespace { | 43 namespace { |
| 44 | 44 |
| 45 // These should match the counterparts in remote.js. | 45 // These should match the counterparts in remote.js. |
| 46 // Also, the size of the file in |kTestRootFeed| has to be set to | 46 // Also, the size of the file in |kTestRootFeed| has to be set to |
| 47 // length of kTestFileContent string. | 47 // length of kTestFileContent string. |
| 48 const char kTestFileContent[] = "hello, world!"; | 48 const char kTestFileContent[] = "hello, world!"; |
| 49 | 49 |
| 50 // Contains a folder entry for the folder 'Folder' that will be 'created'. | |
| 51 const char kTestDirectory[] = "gdata/new_folder_entry.json"; | |
| 52 | |
| 53 // Contains a folder named Folder that has a file File.aBc inside of it. | 50 // Contains a folder named Folder that has a file File.aBc inside of it. |
| 54 const char kTestRootFeed[] = "gdata/remote_file_system_apitest_root_feed.json"; | 51 const char kTestRootFeed[] = "gdata/remote_file_system_apitest_root_feed.json"; |
| 55 | 52 |
| 56 // Contains metadata of the document that will be "downloaded" in test. | |
| 57 const char kTestDocumentToDownloadEntry[] = | |
| 58 "gdata/remote_file_system_apitest_document_to_download.json"; | |
| 59 | |
| 60 // Flags used to run the tests with a COMPONENT extension. | 53 // Flags used to run the tests with a COMPONENT extension. |
| 61 const int kComponentFlags = ExtensionApiTest::kFlagEnableFileAccess | | 54 const int kComponentFlags = ExtensionApiTest::kFlagEnableFileAccess | |
| 62 ExtensionApiTest::kFlagLoadAsComponent; | 55 ExtensionApiTest::kFlagLoadAsComponent; |
| 63 | 56 |
| 64 // Helper class to wait for a background page to load or close again. | 57 // Helper class to wait for a background page to load or close again. |
| 65 // TODO(tbarzic): We can probably share this with e.g. | 58 // TODO(tbarzic): We can probably share this with e.g. |
| 66 // lazy_background_page_apitest. | 59 // lazy_background_page_apitest. |
| 67 class BackgroundObserver { | 60 class BackgroundObserver { |
| 68 public: | 61 public: |
| 69 BackgroundObserver() | 62 BackgroundObserver() |
| (...skipping 11 matching lines...) Expand all Loading... |
| 81 | 74 |
| 82 void WaitUntilClosed() { | 75 void WaitUntilClosed() { |
| 83 page_closed_.Wait(); | 76 page_closed_.Wait(); |
| 84 } | 77 } |
| 85 | 78 |
| 86 private: | 79 private: |
| 87 content::WindowedNotificationObserver page_created_; | 80 content::WindowedNotificationObserver page_created_; |
| 88 content::WindowedNotificationObserver page_closed_; | 81 content::WindowedNotificationObserver page_closed_; |
| 89 }; | 82 }; |
| 90 | 83 |
| 91 // Adds a next feed URL property to the given feed value. | |
| 92 bool AddNextFeedURLToFeedValue(const std::string& url, base::Value* feed) { | |
| 93 DictionaryValue* feed_as_dictionary; | |
| 94 if (!feed->GetAsDictionary(&feed_as_dictionary)) | |
| 95 return false; | |
| 96 | |
| 97 ListValue* links; | |
| 98 if (!feed_as_dictionary->GetList("feed.link", &links)) | |
| 99 return false; | |
| 100 | |
| 101 DictionaryValue* link_value = new DictionaryValue(); | |
| 102 link_value->SetString("href", url); | |
| 103 link_value->SetString("rel", "next"); | |
| 104 link_value->SetString("type", "application/atom_xml"); | |
| 105 | |
| 106 links->Append(link_value); | |
| 107 | |
| 108 return true; | |
| 109 } | |
| 110 | |
| 111 // Creates a cache representation of the test file with predetermined content. | 84 // Creates a cache representation of the test file with predetermined content. |
| 112 void CreateFileWithContent(const FilePath& path, const std::string& content) { | 85 void CreateFileWithContent(const FilePath& path, const std::string& content) { |
| 113 int content_size = static_cast<int>(content.length()); | 86 int content_size = static_cast<int>(content.length()); |
| 114 ASSERT_EQ(content_size, | 87 ASSERT_EQ(content_size, |
| 115 file_util::WriteFile(path, content.c_str(), content_size)); | 88 file_util::WriteFile(path, content.c_str(), content_size)); |
| 116 } | 89 } |
| 117 | 90 |
| 118 // Fake google_apis::DriveServiceInterface implementation used by | |
| 119 // RemoteFileSystemExtensionApiTest. | |
| 120 class FakeDriveService : public google_apis::DummyDriveService { | |
| 121 public: | |
| 122 // google_apis::DriveServiceInterface overrides: | |
| 123 virtual void GetResourceList( | |
| 124 const GURL& feed_url, | |
| 125 int64 start_changestamp, | |
| 126 const std::string& search_string, | |
| 127 bool shared_with_me, | |
| 128 const std::string& directory_resource_id, | |
| 129 const google_apis::GetResourceListCallback& callback) OVERRIDE { | |
| 130 scoped_ptr<base::Value> value( | |
| 131 google_apis::test_util::LoadJSONFile(kTestRootFeed)); | |
| 132 if (!search_string.empty()) { | |
| 133 // Search results will be returned in two parts: | |
| 134 // 1. Search will be given empty initial feed url. The returned feed will | |
| 135 // have next feed URL set to mock the situation when server returns | |
| 136 // partial result feed. | |
| 137 // 2. Search will be given next feed URL from the first call as the | |
| 138 // initial feed url. Result feed will not have next feed url set. | |
| 139 // In both cases search will return all files and directories in test root | |
| 140 // feed. | |
| 141 if (feed_url.is_empty()) { | |
| 142 ASSERT_TRUE( | |
| 143 AddNextFeedURLToFeedValue("https://next_feed", value.get())); | |
| 144 } else { | |
| 145 EXPECT_EQ(GURL("https://next_feed"), feed_url); | |
| 146 } | |
| 147 } | |
| 148 scoped_ptr<google_apis::ResourceList> result( | |
| 149 google_apis::ResourceList::ExtractAndParse(*value)); | |
| 150 base::MessageLoopProxy::current()->PostTask( | |
| 151 FROM_HERE, | |
| 152 base::Bind(callback, google_apis::HTTP_SUCCESS, base::Passed(&result))); | |
| 153 } | |
| 154 | |
| 155 virtual void GetResourceEntry( | |
| 156 const std::string& resource_id, | |
| 157 const google_apis::GetResourceEntryCallback& callback) OVERRIDE { | |
| 158 EXPECT_EQ("file:1_file_resource_id", resource_id); | |
| 159 | |
| 160 scoped_ptr<base::Value> file_to_download_value( | |
| 161 google_apis::test_util::LoadJSONFile(kTestDocumentToDownloadEntry)); | |
| 162 scoped_ptr<google_apis::ResourceEntry> file_to_download( | |
| 163 google_apis::ResourceEntry::ExtractAndParse(*file_to_download_value)); | |
| 164 | |
| 165 base::MessageLoopProxy::current()->PostTask( | |
| 166 FROM_HERE, | |
| 167 base::Bind(callback, google_apis::HTTP_SUCCESS, | |
| 168 base::Passed(&file_to_download))); | |
| 169 } | |
| 170 | |
| 171 virtual void GetAccountMetadata( | |
| 172 const google_apis::GetAccountMetadataCallback& callback) OVERRIDE { | |
| 173 scoped_ptr<google_apis::AccountMetadataFeed> account_metadata( | |
| 174 new google_apis::AccountMetadataFeed); | |
| 175 base::MessageLoopProxy::current()->PostTask( | |
| 176 FROM_HERE, | |
| 177 base::Bind(callback, google_apis::HTTP_SUCCESS, | |
| 178 base::Passed(&account_metadata))); | |
| 179 } | |
| 180 | |
| 181 virtual void AddNewDirectory( | |
| 182 const GURL& parent_content_url, | |
| 183 const std::string& directory_name, | |
| 184 const google_apis::GetResourceEntryCallback& callback) OVERRIDE { | |
| 185 scoped_ptr<base::Value> dir_value( | |
| 186 google_apis::test_util::LoadJSONFile(kTestDirectory)); | |
| 187 scoped_ptr<google_apis::ResourceEntry> dir_resource_entry( | |
| 188 google_apis::ResourceEntry::ExtractAndParse(*dir_value)); | |
| 189 base::MessageLoopProxy::current()->PostTask( | |
| 190 FROM_HERE, | |
| 191 base::Bind(callback, google_apis::HTTP_SUCCESS, | |
| 192 base::Passed(&dir_resource_entry))); | |
| 193 } | |
| 194 | |
| 195 virtual void DownloadFile( | |
| 196 const FilePath& virtual_path, | |
| 197 const FilePath& local_cache_path, | |
| 198 const GURL& content_url, | |
| 199 const google_apis::DownloadActionCallback& download_action_callback, | |
| 200 const google_apis::GetContentCallback& get_content_callback) OVERRIDE { | |
| 201 EXPECT_EQ(GURL("https://file_content_url_changed"), content_url); | |
| 202 ASSERT_TRUE(content::BrowserThread::PostBlockingPoolTaskAndReply( | |
| 203 FROM_HERE, | |
| 204 base::Bind(&CreateFileWithContent, local_cache_path, kTestFileContent), | |
| 205 base::Bind(download_action_callback, google_apis::HTTP_SUCCESS, | |
| 206 local_cache_path))); | |
| 207 } | |
| 208 }; | |
| 209 | |
| 210 class FileSystemExtensionApiTest : public ExtensionApiTest { | 91 class FileSystemExtensionApiTest : public ExtensionApiTest { |
| 211 public: | 92 public: |
| 212 FileSystemExtensionApiTest() {} | 93 FileSystemExtensionApiTest() {} |
| 213 | 94 |
| 214 virtual ~FileSystemExtensionApiTest() {} | 95 virtual ~FileSystemExtensionApiTest() {} |
| 215 | 96 |
| 216 virtual void SetUp() OVERRIDE { | 97 virtual void SetUp() OVERRIDE { |
| 217 ASSERT_TRUE(tmp_dir_.CreateUniqueTempDir()); | 98 ASSERT_TRUE(tmp_dir_.CreateUniqueTempDir()); |
| 218 mount_point_dir_ = tmp_dir_.path().Append("tmp"); | 99 mount_point_dir_ = tmp_dir_.path().Append("tmp"); |
| 219 // Create the mount point. | 100 // Create the mount point. |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 } | 206 } |
| 326 | 207 |
| 327 protected: | 208 protected: |
| 328 base::ScopedTempDir tmp_dir_; | 209 base::ScopedTempDir tmp_dir_; |
| 329 FilePath mount_point_dir_; | 210 FilePath mount_point_dir_; |
| 330 }; | 211 }; |
| 331 | 212 |
| 332 | 213 |
| 333 class RemoteFileSystemExtensionApiTest : public ExtensionApiTest { | 214 class RemoteFileSystemExtensionApiTest : public ExtensionApiTest { |
| 334 public: | 215 public: |
| 335 RemoteFileSystemExtensionApiTest() {} | 216 RemoteFileSystemExtensionApiTest() : fake_drive_service_(NULL) {} |
| 336 | 217 |
| 337 virtual ~RemoteFileSystemExtensionApiTest() {} | 218 virtual ~RemoteFileSystemExtensionApiTest() {} |
| 338 | 219 |
| 339 virtual void SetUp() OVERRIDE { | 220 virtual void SetUp() OVERRIDE { |
| 340 // Set up cache root and documents service to be used when creating gdata | 221 // Set up cache root and documents service to be used when creating gdata |
| 341 // system service. This has to be done early on (before the browser is | 222 // system service. This has to be done early on (before the browser is |
| 342 // created) because the system service instance is initialized very early | 223 // created) because the system service instance is initialized very early |
| 343 // by FileBrowserEventRouter. | 224 // by FileBrowserEventRouter. |
| 344 FilePath tmp_dir_path; | 225 FilePath tmp_dir_path; |
| 345 PathService::Get(base::DIR_TEMP, &tmp_dir_path); | 226 PathService::Get(base::DIR_TEMP, &tmp_dir_path); |
| 346 ASSERT_TRUE(test_cache_root_.CreateUniqueTempDirUnderPath(tmp_dir_path)); | 227 ASSERT_TRUE(test_cache_root_.CreateUniqueTempDirUnderPath(tmp_dir_path)); |
| 347 | 228 |
| 348 drive::DriveSystemServiceFactory::SetFactoryForTest( | 229 drive::DriveSystemServiceFactory::SetFactoryForTest( |
| 349 base::Bind(&RemoteFileSystemExtensionApiTest::CreateDriveSystemService, | 230 base::Bind(&RemoteFileSystemExtensionApiTest::CreateDriveSystemService, |
| 350 base::Unretained(this))); | 231 base::Unretained(this))); |
| 351 | 232 |
| 352 ExtensionApiTest::SetUp(); | 233 ExtensionApiTest::SetUp(); |
| 353 } | 234 } |
| 354 | 235 |
| 355 protected: | 236 protected: |
| 356 // DriveSystemService factory function for this test. | 237 // DriveSystemService factory function for this test. |
| 357 drive::DriveSystemService* CreateDriveSystemService(Profile* profile) { | 238 drive::DriveSystemService* CreateDriveSystemService(Profile* profile) { |
| 239 fake_drive_service_ = new google_apis::FakeDriveService; |
| 240 fake_drive_service_->LoadResourceListForWapi( |
| 241 kTestRootFeed); |
| 242 fake_drive_service_->LoadAccountMetadataForWapi( |
| 243 "gdata/account_metadata.json"); |
| 244 |
| 358 return new drive::DriveSystemService(profile, | 245 return new drive::DriveSystemService(profile, |
| 359 new FakeDriveService(), | 246 fake_drive_service_, |
| 360 test_cache_root_.path(), | 247 test_cache_root_.path(), |
| 361 NULL); | 248 NULL); |
| 362 } | 249 } |
| 363 | 250 |
| 364 base::ScopedTempDir test_cache_root_; | 251 base::ScopedTempDir test_cache_root_; |
| 252 google_apis::FakeDriveService* fake_drive_service_; |
| 365 }; | 253 }; |
| 366 | 254 |
| 367 IN_PROC_BROWSER_TEST_F(FileSystemExtensionApiTest, LocalFileSystem) { | 255 IN_PROC_BROWSER_TEST_F(FileSystemExtensionApiTest, LocalFileSystem) { |
| 368 ASSERT_TRUE(RunFileBrowserHandlerTest("test.html", "local_filesystem", "")) | 256 ASSERT_TRUE(RunFileBrowserHandlerTest("test.html", "local_filesystem", "")) |
| 369 << message_; | 257 << message_; |
| 370 } | 258 } |
| 371 | 259 |
| 372 IN_PROC_BROWSER_TEST_F(FileSystemExtensionApiTest, FileBrowserTest) { | 260 IN_PROC_BROWSER_TEST_F(FileSystemExtensionApiTest, FileBrowserTest) { |
| 373 ASSERT_TRUE(RunFileBrowserHandlerTest("read.html", | 261 ASSERT_TRUE(RunFileBrowserHandlerTest("read.html", |
| 374 "filebrowser_component", | 262 "filebrowser_component", |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 452 BackgroundObserver page_complete; | 340 BackgroundObserver page_complete; |
| 453 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("filesystem_handler"))) | 341 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("filesystem_handler"))) |
| 454 << message_; | 342 << message_; |
| 455 page_complete.WaitUntilLoaded(); | 343 page_complete.WaitUntilLoaded(); |
| 456 | 344 |
| 457 EXPECT_TRUE(RunExtensionSubtest("filebrowser_component", "remote.html", | 345 EXPECT_TRUE(RunExtensionSubtest("filebrowser_component", "remote.html", |
| 458 kComponentFlags)) << message_; | 346 kComponentFlags)) << message_; |
| 459 } | 347 } |
| 460 | 348 |
| 461 IN_PROC_BROWSER_TEST_F(RemoteFileSystemExtensionApiTest, ContentSearch) { | 349 IN_PROC_BROWSER_TEST_F(RemoteFileSystemExtensionApiTest, ContentSearch) { |
| 350 // Configure the drive service to return only one search result at a time |
| 351 // to simulate paginated searches. |
| 352 fake_drive_service_->set_default_max_results(1); |
| 462 EXPECT_TRUE(RunExtensionSubtest("filebrowser_component", "remote_search.html", | 353 EXPECT_TRUE(RunExtensionSubtest("filebrowser_component", "remote_search.html", |
| 463 kComponentFlags)) << message_; | 354 kComponentFlags)) << message_; |
| 464 } | 355 } |
| 465 | 356 |
| 466 } // namespace | 357 } // namespace |
| OLD | NEW |