summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortbarzic@chromium.org <tbarzic@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-19 23:48:28 +0000
committertbarzic@chromium.org <tbarzic@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-19 23:48:28 +0000
commit24d2574e3e3db858eae7635f9dd43f3a6574e32c (patch)
tree1aa6a8238cf38141d5dcb8d84e5d400fa214b720
parent894a97bd82076be6dbc5865228d83e770f504c22 (diff)
downloadchromium_src-24d2574e3e3db858eae7635f9dd43f3a6574e32c.zip
chromium_src-24d2574e3e3db858eae7635f9dd43f3a6574e32c.tar.gz
chromium_src-24d2574e3e3db858eae7635f9dd43f3a6574e32c.tar.bz2
Add end-to-end test for gdata file handler
this is the test for http://crrev.com/128417 Existing gdata file system tests are updated to include filesystem behaviour instead of mocking it out. We mock document service layer now. This is to make sure we test file permissions for cache file. Also this tests file system operations are properly wired up gdata file system (up to documents service layer). We ensure the cache directory is empty initially. Additionally, cl adds test for executing file handler tasks on gdata file system (the same file handler extension as in other file system api tests). This is to ensure file permissions are properly set for file handlers. The test does the following: (1) Creates new directory in file browser test extension. (2) Opens and reads a file in the created directory from file browser test extension (mocked documents service will return 'created' directory with a file in it when asked for root) (3) runs file handler extension, and invokes its registered task from file browser test extension (we have to make sure file we read has the file extension the handler handles) Feeds used by documents service are created in gdata test dir. BUG=none TEST=*RemoteFileSystem* Review URL: https://chromiumcodereview.appspot.com/9836087 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@133087 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chromeos/extensions/external_filesystem_apitest.cc259
-rw-r--r--chrome/browser/chromeos/gdata/gdata_file_system.cc31
-rw-r--r--chrome/browser/chromeos/gdata/gdata_file_system.h15
-rw-r--r--chrome/chrome_tests.gypi2
-rw-r--r--chrome/test/data/chromeos/gdata/remote_file_system_apitest_folder_entry.json89
-rw-r--r--chrome/test/data/chromeos/gdata/remote_file_system_apitest_root_feed.json232
-rw-r--r--chrome/test/data/extensions/api_test/filebrowser_component/remote.js181
7 files changed, 621 insertions, 188 deletions
diff --git a/chrome/browser/chromeos/extensions/external_filesystem_apitest.cc b/chrome/browser/chromeos/extensions/external_filesystem_apitest.cc
index a4120bc..130cac7 100644
--- a/chrome/browser/chromeos/extensions/external_filesystem_apitest.cc
+++ b/chrome/browser/chromeos/extensions/external_filesystem_apitest.cc
@@ -2,13 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/bind.h"
+#include "base/file_path.h"
#include "base/file_util.h"
-#include "base/platform_file.h"
+#include "base/json/json_file_value_serializer.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop_proxy.h"
#include "base/path_service.h"
#include "base/scoped_temp_dir.h"
-#include "base/stringprintf.h"
-#include "chrome/browser/chromeos/gdata/gdata_file_system_proxy.h"
+#include "base/threading/worker_pool.h"
+#include "base/values.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/browser/chromeos/gdata/gdata_file_system.h"
+#include "chrome/browser/chromeos/gdata/gdata_system_service.h"
+#include "chrome/browser/chromeos/gdata/gdata_parser.h"
+#include "chrome/browser/chromeos/gdata/gdata_errorcode.h"
#include "chrome/browser/chromeos/gdata/gdata_util.h"
+#include "chrome/browser/chromeos/gdata/mock_gdata_documents_service.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_test_message_listener.h"
#include "chrome/browser/profiles/profile.h"
@@ -20,17 +30,21 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "webkit/fileapi/file_system_context.h"
#include "webkit/fileapi/file_system_mount_point_provider.h"
-#include "webkit/chromeos/fileapi/remote_file_system_proxy.h"
using ::testing::_;
+using ::testing::Return;
using content::BrowserContext;
+namespace {
+
// These should match the counterparts in remote.js.
-const char kTestDirPath[] = "/test_dir";
-const char kTestFilePath[] = "/test_dir/hello.txt";
const char kTestFileContents[] = "hello, world";
-namespace {
+// Contains a folder entry for the folder 'Folder' that will be 'created'.
+const char kTestDirectory[] = "remote_file_system_apitest_folder_entry.json";
+
+// Contains a folder named Folder that has a file File.aBc inside of it.
+const char kTestRootFeed[] = "remote_file_system_apitest_root_feed.json";
// The ID of the file browser extension.
const char kFileBrowserExtensionId[] = "ddammdhioacbehjngdmkjcjbnfginlla";
@@ -66,83 +80,62 @@ class BackgroundObserver {
ui_test_utils::WindowedNotificationObserver page_closed_;
};
-// Returns the expected URL for the given path.
-GURL GetExpectedURL(const std::string& path) {
- return GURL(
- base::StringPrintf(
- "filesystem:chrome-extension://%s/external/%s",
- kFileBrowserExtensionId,
- path.c_str()));
+// TODO(tbarzic): We should probably share GetTestFilePath and LoadJSONFile
+// with gdata_file_system_unittest.
+// Generates file path in gdata test directory for a file with name |filename|.
+FilePath GetTestFilePath(const FilePath::StringType& filename) {
+ FilePath path;
+ std::string error;
+ PathService::Get(chrome::DIR_TEST_DATA, &path);
+ path = path.AppendASCII("chromeos")
+ .AppendASCII("gdata")
+ .AppendASCII(filename);
+ EXPECT_TRUE(file_util::PathExists(path)) <<
+ "Couldn't find " << path.value();
+ return path;
}
-// Action used to set mock expectations for CreateDirectory().
-ACTION_P(MockCreateDirectory, status) {
- arg3.Run(status);
+// Loads and deserializes a json file in gdata test directory whose name is
+// |filename|. Returns new Value object the file is deserialized to.
+base::Value* LoadJSONFile(const std::string& filename) {
+ FilePath path = GetTestFilePath(filename);
+ std::string error;
+ JSONFileValueSerializer serializer(path);
+ Value* value = serializer.Deserialize(NULL, &error);
+ EXPECT_TRUE(value) <<
+ "Parse error " << path.value() << ": " << error;
+ return value;
}
-// Action used to set mock expectations for GetFileInfo().
-ACTION_P3(MockGetFileInfo, status, file_info, path) {
- arg1.Run(status, file_info, path);
+// Action used to set mock expectations for CreateDirectory().
+ACTION_P2(MockCreateDirectoryCallback, status, value) {
+ base::MessageLoopProxy::current()->PostTask(FROM_HERE,
+ base::Bind(arg2, status, base::Passed(value)));
}
-// Action used to set mock expectations for CreateSnapshotFile().
-ACTION_P4(MockCreateSnapshotFile, status, file_info, path, file_ref) {
- arg1.Run(status, file_info, path, file_ref);
+// Action used to set mock expecteations for GetDocuments.
+ACTION_P2(MockGetDocumentsCallback, status, value) {
+ base::MessageLoopProxy::current()->PostTask(FROM_HERE,
+ base::Bind(arg2, status, base::Passed(value)));
}
-// The mock is used to add a remote mount point, and write tests for it.
-class MockRemoteFileSystemProxy :
- public fileapi::RemoteFileSystemProxyInterface {
- public:
- MockRemoteFileSystemProxy() {}
- virtual ~MockRemoteFileSystemProxy() {}
-
- MOCK_METHOD2(
- GetFileInfo,
- void(const GURL& path,
- const fileapi::FileSystemOperationInterface::GetMetadataCallback&
- callback));
- MOCK_METHOD3(
- Copy,
- void(const GURL& src_path,
- const GURL& dest_path,
- const fileapi::FileSystemOperationInterface::StatusCallback&
- callback));
- MOCK_METHOD3(
- Move,
- void(const GURL& src_path,
- const GURL& dest_path,
- const fileapi::FileSystemOperationInterface::StatusCallback&
- callback));
- MOCK_METHOD2(
- ReadDirectory,
- void(const GURL& path,
- const fileapi::FileSystemOperationInterface::ReadDirectoryCallback&
- callback));
- MOCK_METHOD3(
- Remove,
- void(const GURL& path,
- bool recursive,
- const fileapi::FileSystemOperationInterface::StatusCallback&
- callback));
- MOCK_METHOD4(
- CreateDirectory,
- void(const GURL& file_url,
- bool exclusive,
- bool recursive,
- const fileapi::FileSystemOperationInterface::StatusCallback&
- callback));
- MOCK_METHOD2(
- CreateSnapshotFile,
- void(const GURL& path,
- const fileapi::FileSystemOperationInterface::SnapshotFileCallback&
- callback));
-};
+// Creates a cache representation of the test file with predetermined content.
+void CreateDownloadFile(const FilePath& path) {
+ int file_content_size = static_cast<int>(sizeof(kTestFileContents));
+ ASSERT_EQ(file_content_size,
+ file_util::WriteFile(path, kTestFileContents, file_content_size));
+}
-const char kExpectedWriteError[] =
- "Got unexpected error: File handler error: SECURITY_ERR";
+// Action used to set mock expectations for DownloadFile().
+ACTION_P(MockDownloadFileCallback, status) {
+ ASSERT_TRUE(base::WorkerPool::PostTaskAndReply(FROM_HERE,
+ base::Bind(&CreateDownloadFile, arg1),
+ base::Bind(arg3, status, arg2, arg1),
+ false));
}
+} // namespace
+
class FileSystemExtensionApiTest : public ExtensionApiTest {
public:
FileSystemExtensionApiTest() : test_mount_point_("/tmp") {
@@ -180,51 +173,39 @@ class FileSystemExtensionApiTest : public ExtensionApiTest {
class RemoteFileSystemExtensionApiTest : public ExtensionApiTest {
public:
- RemoteFileSystemExtensionApiTest()
- : mock_remote_file_system_proxy_(NULL) {
- }
+ RemoteFileSystemExtensionApiTest() {}
virtual ~RemoteFileSystemExtensionApiTest() {}
virtual void SetUp() OVERRIDE {
FilePath tmp_dir_path;
PathService::Get(base::DIR_TEMP, &tmp_dir_path);
+ ASSERT_TRUE(test_cache_root_.CreateUniqueTempDirUnderPath(tmp_dir_path));
- ASSERT_TRUE(test_mount_point_.CreateUniqueTempDirUnderPath(tmp_dir_path));
-
- file_util::CreateTemporaryFileInDir(test_mount_point_.path(),
- &test_file_path_);
- file_util::WriteFile(test_file_path_,
- kTestFileContents,
- sizeof(kTestFileContents) - 1);
- file_util::GetFileInfo(test_file_path_, &test_file_info_);
-
- // ExtensionApiTest::SetUp() should be called at the end. For some
- // reason, ExtensionApiTest::SetUp() starts running tests, so any
- // setup has to be done before calling this.
ExtensionApiTest::SetUp();
}
- // Adds a remote mount point at at mount point /tmp.
- void AddTmpMountPoint() {
- fileapi::ExternalFileSystemMountPointProvider* provider =
- BrowserContext::GetFileSystemContext(browser()->profile())->
- external_provider();
- mock_remote_file_system_proxy_ = new MockRemoteFileSystemProxy;
- // Take the ownership of mock_remote_file_system_proxy_.
- provider->AddRemoteMountPoint(test_mount_point_.path(),
- mock_remote_file_system_proxy_);
- }
-
- std::string GetPathOnMountPoint(const std::string& path) {
- return test_mount_point_.path().BaseName().value() + path;
+ // Sets up GDataFileSystem that will be used in the test.
+ // NOTE: Remote mount point should get added to mount poitn provider when
+ // getLocalFileSystem is called from filebrowser_component extension.
+ virtual void SetupGDataFileSystemForTest() {
+ gdata::GDataSystemService* system_service =
+ gdata::GDataSystemServiceFactory::GetForProfile(browser()->profile());
+ EXPECT_TRUE(system_service && system_service->file_system());
+
+ mock_documents_service_ = new gdata::MockDocumentsService();
+ operation_registry_.reset(new gdata::GDataOperationRegistry());
+ system_service->file_system()->SetDocumentsServiceForTesting(
+ mock_documents_service_);
+
+ EXPECT_TRUE(system_service->file_system()->SetCacheRootPathForTesting(
+ test_cache_root_.path()));
}
protected:
- base::PlatformFileInfo test_file_info_;
- FilePath test_file_path_;
- ScopedTempDir test_mount_point_;
- MockRemoteFileSystemProxy* mock_remote_file_system_proxy_;
+ ScopedTempDir test_cache_root_;
+ gdata::MockDocumentsService* mock_documents_service_;
+ scoped_ptr<gdata::GDataOperationRegistry> operation_registry_;
};
IN_PROC_BROWSER_TEST_F(FileSystemExtensionApiTest, LocalFileSystem) {
@@ -272,34 +253,44 @@ IN_PROC_BROWSER_TEST_F(FileSystemExtensionApiTest,
}
IN_PROC_BROWSER_TEST_F(RemoteFileSystemExtensionApiTest, RemoteMountPoint) {
- AddTmpMountPoint();
- // The test directory is created first.
- const GURL test_dir_url =
- GetExpectedURL(GetPathOnMountPoint(kTestDirPath));
- EXPECT_CALL(*mock_remote_file_system_proxy_,
- CreateDirectory(test_dir_url, false, false, _))
- .WillOnce(MockCreateDirectory(base::PLATFORM_FILE_OK));
-
- // Then GetFileInfo() is called over "tmp/test_dir/hello.txt".
- const std::string expected_path = GetPathOnMountPoint(kTestFilePath);
- GURL expected_url = GetExpectedURL(expected_path);
- EXPECT_CALL(*mock_remote_file_system_proxy_,
- GetFileInfo(expected_url, _))
- .WillOnce(MockGetFileInfo(
- base::PLATFORM_FILE_OK,
- test_file_info_,
- FilePath::FromUTF8Unsafe(expected_path)));
-
- // Then CreateSnapshotFile() is called over "tmp/test_dir/hello.txt".
- EXPECT_CALL(*mock_remote_file_system_proxy_,
- CreateSnapshotFile(expected_url, _))
- .WillOnce(MockCreateSnapshotFile(
- base::PLATFORM_FILE_OK,
- test_file_info_,
- // Returns the path to the temporary file on the local drive.
- test_file_path_,
- scoped_refptr<webkit_blob::ShareableFileReference>(NULL)));
- ASSERT_TRUE(RunExtensionSubtest(
- "filebrowser_component", "remote.html#" + GetPathOnMountPoint(""),
+ SetupGDataFileSystemForTest();
+
+ EXPECT_CALL(*mock_documents_service_, GetAccountMetadata(_)).Times(1);
+
+ // First, file browser will try to create new directory.
+ scoped_ptr<base::Value> dir_value(LoadJSONFile(kTestDirectory));
+ EXPECT_CALL(*mock_documents_service_,
+ CreateDirectory(_, _, _))
+ .WillOnce(MockCreateDirectoryCallback(gdata::HTTP_SUCCESS, &dir_value));
+
+ // Then the test will try to read an existing file file.
+ // Remote filesystem should first request root feed from gdata server.
+ scoped_ptr<base::Value> documents_value(LoadJSONFile(kTestRootFeed));
+ EXPECT_CALL(*mock_documents_service_,
+ GetDocuments(_, _, _))
+ .WillOnce(MockGetDocumentsCallback(gdata::HTTP_SUCCESS,
+ &documents_value));
+
+ // When file browser tries to read the file, remote filesystem should detect
+ // that the cached file is not present on the disk and download it. Mocked
+ // download file will create file with the cached name and predetermined
+ // content. This is the file file browser will read content from.
+ // Later in the test, file handler will try to open the same file on gdata
+ // mount point. This time, DownloadFile should not be called because local
+ // copy is already present in the cache.
+ EXPECT_CALL(*mock_documents_service_,
+ DownloadFile(_, _, _, _))
+ .WillOnce(MockDownloadFileCallback(gdata::HTTP_SUCCESS));
+
+ // On exit, all operations in progress should be cancelled.
+ EXPECT_CALL(*mock_documents_service_, CancelAll());
+ // This one is called on exit, but we don't care much about it, as long as it
+ // retunrs something valid (i.e. not NULL).
+ EXPECT_CALL(*mock_documents_service_, operation_registry()).
+ WillOnce(Return(operation_registry_.get()));
+
+ // All is set... RUN THE TEST.
+ EXPECT_TRUE(RunExtensionTest("filesystem_handler")) << message_;
+ EXPECT_TRUE(RunExtensionSubtest("filebrowser_component", "remote.html",
kComponentFlags)) << message_;
}
diff --git a/chrome/browser/chromeos/gdata/gdata_file_system.cc b/chrome/browser/chromeos/gdata/gdata_file_system.cc
index 2b9de1f..f1c77b2 100644
--- a/chrome/browser/chromeos/gdata/gdata_file_system.cc
+++ b/chrome/browser/chromeos/gdata/gdata_file_system.cc
@@ -724,14 +724,7 @@ void GDataFileSystem::Initialize() {
chrome::GetUserCacheDirectory(profile_->GetPath(), &cache_base_path);
gdata_cache_path_ = cache_base_path.Append(chrome::kGDataCacheDirname);
gdata_cache_path_ = gdata_cache_path_.Append(kGDataCacheVersionDir);
- // Insert into |cache_paths_| in order defined in enum CacheSubDirectoryType.
- cache_paths_.push_back(gdata_cache_path_.Append(kGDataCacheMetaDir));
- cache_paths_.push_back(gdata_cache_path_.Append(kGDataCachePinnedDir));
- cache_paths_.push_back(gdata_cache_path_.Append(kGDataCacheOutgoingDir));
- cache_paths_.push_back(gdata_cache_path_.Append(kGDataCachePersistentDir));
- cache_paths_.push_back(gdata_cache_path_.Append(kGDataCacheTmpDir));
- cache_paths_.push_back(gdata_cache_path_.Append(kGDataCacheTmpDownloadsDir));
- cache_paths_.push_back(gdata_cache_path_.Append(kGDataCacheTmpDocumentsDir));
+ SetCachePaths(gdata_cache_path_);
documents_service_->Initialize(profile_);
@@ -744,6 +737,14 @@ void GDataFileSystem::Initialize() {
InitializePreferenceObserver();
}
+bool GDataFileSystem::SetCacheRootPathForTesting(const FilePath& root_path) {
+ if (cache_initialization_started_)
+ return false;
+ cache_paths_.clear();
+ SetCachePaths(root_path);
+ return true;
+}
+
GDataFileSystem::~GDataFileSystem() {
// This should be called from UI thread, from GDataSystemService shutdown.
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -1780,6 +1781,19 @@ void GDataFileSystem::StartDownloadFileIfEnoughSpace(
params));
}
+void GDataFileSystem::SetCachePaths(const FilePath& root_path) {
+ DCHECK(cache_paths_.empty() && !cache_initialization_started_);
+
+ // Insert into |cache_paths_| in order defined in enum CacheSubDirectoryType.
+ cache_paths_.push_back(root_path.Append(kGDataCacheMetaDir));
+ cache_paths_.push_back(root_path.Append(kGDataCachePinnedDir));
+ cache_paths_.push_back(root_path.Append(kGDataCacheOutgoingDir));
+ cache_paths_.push_back(root_path.Append(kGDataCachePersistentDir));
+ cache_paths_.push_back(root_path.Append(kGDataCacheTmpDir));
+ cache_paths_.push_back(root_path.Append(kGDataCacheTmpDownloadsDir));
+ cache_paths_.push_back(root_path.Append(kGDataCacheTmpDocumentsDir));
+}
+
void GDataFileSystem::InitiateUpload(
const std::string& file_name,
const std::string& content_type,
@@ -1849,7 +1863,6 @@ void GDataFileSystem::OnResumeUpload(
base::Bind(callback, response, base::Passed(&new_entry)));
}
-
void GDataFileSystem::UnsafeFindFileByPath(
const FilePath& file_path,
FindFileDelegate* delegate) {
diff --git a/chrome/browser/chromeos/gdata/gdata_file_system.h b/chrome/browser/chromeos/gdata/gdata_file_system.h
index 438f7d9..3316776 100644
--- a/chrome/browser/chromeos/gdata/gdata_file_system.h
+++ b/chrome/browser/chromeos/gdata/gdata_file_system.h
@@ -19,6 +19,7 @@
#include "base/message_loop.h"
#include "base/platform_file.h"
#include "base/synchronization/lock.h"
+#include "chrome/browser/chromeos/gdata/gdata_documents_service.h"
#include "chrome/browser/chromeos/gdata/gdata_files.h"
#include "chrome/browser/chromeos/gdata/gdata_operation_registry.h"
#include "chrome/browser/chromeos/gdata/gdata_params.h"
@@ -491,6 +492,16 @@ class GDataFileSystem : public GDataFileSystemInterface,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
+ // Used in tests to inject mock document service.
+ void SetDocumentsServiceForTesting(DocumentsServiceInterface*
+ new_document_service) {
+ documents_service_.reset(new_document_service);
+ }
+
+ // Used in tests to set cache root path to a test directory.
+ // It should be called before cache is initialized (it will fail otherwise).
+ bool SetCacheRootPathForTesting(const FilePath& root_path);
+
private:
friend class GDataUploader;
friend class GDataFileSystemTest;
@@ -593,6 +604,10 @@ class GDataFileSystem : public GDataFileSystemInterface,
// Returns NULL if it does not find the file.
GDataFileBase* GetGDataFileInfoFromPath(const FilePath& file_path);
+ // Inits cache directory paths in the provided root.
+ // Should be called before cache is initialized.
+ void SetCachePaths(const FilePath& root_path);
+
// Initiates upload operation of file defined with |file_name|,
// |content_type| and |content_length|. The operation will place the newly
// created file entity into |destination_directory|.
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 61440a1..94d88fe 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -2744,6 +2744,8 @@
'browser/chromeos/extensions/echo_private_apitest.cc',
'browser/chromeos/extensions/external_filesystem_apitest.cc',
'browser/chromeos/gdata/gdata_documents_service_browsertest.cc',
+ 'browser/chromeos/gdata/mock_gdata_documents_service.cc',
+ 'browser/chromeos/gdata/mock_gdata_documents_service.h',
'browser/chromeos/kiosk_mode/mock_kiosk_mode_settings.cc',
'browser/chromeos/kiosk_mode/mock_kiosk_mode_settings.h',
'browser/chromeos/login/enrollment/enterprise_enrollment_screen_browsertest.cc',
diff --git a/chrome/test/data/chromeos/gdata/remote_file_system_apitest_folder_entry.json b/chrome/test/data/chromeos/gdata/remote_file_system_apitest_folder_entry.json
new file mode 100644
index 0000000..f8424d9
--- /dev/null
+++ b/chrome/test/data/chromeos/gdata/remote_file_system_apitest_folder_entry.json
@@ -0,0 +1,89 @@
+{
+ "encoding": "UTF-8",
+ "entry": {
+ "app$edited": {
+ "$t": "2011-12-14T00:41:08.287Z",
+ "xmlns$app": "http://www.w3.org/2007/app"
+ },
+ "author": [ {
+ "email": {
+ "$t": "entry_tester@testing.com"
+ },
+ "name": {
+ "$t": "entry_tester"
+ }
+ } ],
+ "category": [ {
+ "label": "viewed",
+ "scheme": "http://schemas.google.com/g/2005/labels",
+ "term": "http://schemas.google.com/g/2005/labels#viewed"
+ }, {
+ "label": "folder",
+ "scheme": "http://schemas.google.com/g/2005#kind",
+ "term": "http://schemas.google.com/docs/2007#folder"
+ } ],
+ "content": {
+ "src": "https://3_folder_content_url",
+ "type": "application/atom+xml;type=feed"
+ },
+ "docs$writersCanInvite": {
+ "value": "true"
+ },
+ "gd$etag": "\"HhMOFgcNHSt7ImBr\"",
+ "gd$feedLink": [ {
+ "href": "https://3_folder_feed_linkurl",
+ "rel": "http://schemas.google.com/acl/2007#accessControlList"
+ } ],
+ "gd$lastModifiedBy": {
+ "email": {
+ "$t": "tester@testing.com"
+ },
+ "name": {
+ "$t": "tester"
+ }
+ },
+ "gd$lastViewed": {
+ "$t": "2011-11-02T04:37:38.469Z"
+ },
+ "gd$quotaBytesUsed": {
+ "$t": "0"
+ },
+ "gd$resourceId": {
+ "$t": "folder:3_new_folder_resource_id"
+ },
+ "id": {
+ "$t": "https://3_new_folder_resource_id"
+ },
+ "link": [ {
+ "href": "https://3_folder_alternate_link",
+ "rel": "alternate",
+ "type": "text/html"
+ }, {
+ "href": "https://3_folder_resumable_create_media_link",
+ "rel": "http://schemas.google.com/g/2005#resumable-create-media",
+ "type": "application/atom+xml"
+ }, {
+ "href": "https://3_folder_self_link/folder:3_folder_resource_id",
+ "rel": "self",
+ "type": "application/atom+xml"
+ }, {
+ "href": "https://3_edit_link",
+ "rel": "edit",
+ "type": "application/atom+xml"
+ } ],
+ "published": {
+ "$t": "2010-11-07T05:03:54.719Z"
+ },
+ "title": {
+ "$t": "FolderNew"
+ },
+ "updated": {
+ "$t": "2011-04-01T18:34:08.234Z"
+ },
+ "xmlns": "http://www.w3.org/2005/Atom",
+ "xmlns$batch": "http://schemas.google.com/gdata/batch",
+ "xmlns$docs": "http://schemas.google.com/docs/2007",
+ "xmlns$gd": "http://schemas.google.com/g/2005"
+ },
+ "version": "1.0"
+}
diff --git a/chrome/test/data/chromeos/gdata/remote_file_system_apitest_root_feed.json b/chrome/test/data/chromeos/gdata/remote_file_system_apitest_root_feed.json
new file mode 100644
index 0000000..ed80c51
--- /dev/null
+++ b/chrome/test/data/chromeos/gdata/remote_file_system_apitest_root_feed.json
@@ -0,0 +1,232 @@
+{
+ "encoding": "UTF-8",
+ "feed": {
+ "author": [ {
+ "email": {
+ "$t": "tester@testing.com"
+ },
+ "name": {
+ "$t": "tester"
+ }
+ } ],
+ "category": [ {
+ "label": "item",
+ "scheme": "http://schemas.google.com/g/2005#kind",
+ "term": "http://schemas.google.com/docs/2007#item"
+ } ],
+ "entry": [ {
+ "app$edited": {
+ "$t": "2011-12-14T00:41:08.287Z",
+ "xmlns$app": "http://www.w3.org/2007/app"
+ },
+ "author": [ {
+ "email": {
+ "$t": "entry_tester@testing.com"
+ },
+ "name": {
+ "$t": "entry_tester"
+ }
+ } ],
+ "category": [ {
+ "label": "viewed",
+ "scheme": "http://schemas.google.com/g/2005/labels",
+ "term": "http://schemas.google.com/g/2005/labels#viewed"
+ }, {
+ "label": "folder",
+ "scheme": "http://schemas.google.com/g/2005#kind",
+ "term": "http://schemas.google.com/docs/2007#folder"
+ } ],
+ "content": {
+ "src": "https://1_folder_content_url",
+ "type": "application/atom+xml;type=feed"
+ },
+ "docs$writersCanInvite": {
+ "value": "true"
+ },
+ "gd$etag": "\"HhMOFgcNHSt7ImBr\"",
+ "gd$feedLink": [ {
+ "href": "https://1_folder_feed_linkurl",
+ "rel": "http://schemas.google.com/acl/2007#accessControlList"
+ } ],
+ "gd$lastModifiedBy": {
+ "email": {
+ "$t": "tester@testing.com"
+ },
+ "name": {
+ "$t": "tester"
+ }
+ },
+ "gd$lastViewed": {
+ "$t": "2011-11-02T04:37:38.469Z"
+ },
+ "gd$quotaBytesUsed": {
+ "$t": "0"
+ },
+ "gd$resourceId": {
+ "$t": "folder:1_folder_resource_id"
+ },
+ "id": {
+ "$t": "https://1_folder_resource_id"
+ },
+ "link": [ {
+ "href": "https://1_folder_alternate_link",
+ "rel": "alternate",
+ "type": "text/html"
+ }, {
+ "href": "https://1_folder_self_link/folder:1_folder_resource_id",
+ "rel": "self",
+ "type": "application/atom+xml"
+ }, {
+ "href": "https://1_folder_self_link/folder:1_folder_resource_id",
+ "rel": "edit",
+ "type": "application/atom+xml"
+ } ],
+ "published": {
+ "$t": "2010-11-07T05:03:54.719Z"
+ },
+ "title": {
+ "$t": "Folder"
+ },
+ "updated": {
+ "$t": "2011-04-01T18:34:08.234Z"
+ }
+ }, {
+ "app$edited": {
+ "$t": "2011-12-14T00:40:57.162Z",
+ "xmlns$app": "http://www.w3.org/2007/app"
+ },
+ "author": [ {
+ "email": {
+ "$t": "tester@testing.com"
+ },
+ "name": {
+ "$t": "tester"
+ }
+ } ],
+ "category": [ {
+ "label": "audio/mpeg",
+ "scheme": "http://schemas.google.com/g/2005#kind",
+ "term": "http://schemas.google.com/docs/2007#file"
+ } ],
+ "content": {
+ "src": "https://file_content_url/",
+ "type": "audio/mpeg"
+ },
+ "docs$filename": {
+ "$t": "File.aBc"
+ },
+ "docs$md5Checksum": {
+ "$t": "3b4382ebefec6e743578c76bbd0575ce"
+ },
+ "docs$size": {
+ "$t": "892721"
+ },
+ "docs$suggestedFilename": {
+ "$t": "File.aBc"
+ },
+ "docs$writersCanInvite": {
+ "value": "true"
+ },
+ "gd$etag": "\"HhMOFgxXHit7ImBr\"",
+ "gd$feedLink": [ {
+ "href": "https://file_feed_link_url",
+ "rel": "http://schemas.google.com/docs/2007/revisions"
+ } ],
+ "gd$lastModifiedBy": {
+ "email": {
+ "$t": "tester@testing.com"
+ },
+ "name": {
+ "$t": "tester"
+ }
+ },
+ "gd$quotaBytesUsed": {
+ "$t": "892721"
+ },
+ "gd$resourceId": {
+ "$t": "file:1_file_resource_id"
+ },
+ "id": {
+ "$t": "2_file_resource_id"
+ },
+ "link": [ {
+ "href": "https://file_link_alternate",
+ "rel": "alternate",
+ "type": "text/html"
+ }, {
+ "href": "https://file_link_resumable_edit_media",
+ "rel": "http://schemas.google.com/g/2005#resumable-edit-media",
+ "type": "application/atom+xml"
+ }, {
+ "href": "https://file_link_self/file:2_file_resource_id",
+ "rel": "self",
+ "type": "application/atom+xml"
+ }, {
+ "href": "https://1_folder_self_link/folder:1_folder_resource_id",
+ "rel": "http://schemas.google.com/docs/2007#parent",
+ "type": "application/atom+xml"
+ }, {
+ "href": "https://file_link_self/file:2_file_resource_id",
+ "rel": "edit",
+ "type": "application/atom+xml"
+ } ],
+ "published": {
+ "$t": "2011-12-14T00:40:47.330Z"
+ },
+ "title": {
+ "$t": "File.aBc"
+ },
+ "updated": {
+ "$t": "2011-12-14T00:40:47.330Z"
+ }
+ }],
+ "gd$etag": "W/\"DkEEQH8-eSt7ImA9WhRQGE8.\"",
+ "id": {
+ "$t": "https://docs.google.com/feeds/default/private/full"
+ },
+ "link": [ {
+ "href": "http://alternate_link",
+ "rel": "alternate",
+ "type": "text/html"
+ }, {
+ "href": "https://resumable_create_media_link",
+ "rel": "http://schemas.google.com/g/2005#resumable-create-media",
+ "type": "application/atom+xml"
+ }, {
+ "href": "https://docs.google.com/feeds/default/private/full?v=3",
+ "rel": "http://schemas.google.com/g/2005#feed",
+ "type": "application/atom+xml"
+ }, {
+ "href": "https://docs.google.com/feeds/default/private/full?v=3",
+ "rel": "http://schemas.google.com/g/2005#post",
+ "type": "application/atom+xml"
+ }, {
+ "href": "https://docs.google.com/feeds/default/private/full/batch?v=3",
+ "rel": "http://schemas.google.com/g/2005#batch",
+ "type": "application/atom+xml"
+ }, {
+ "href": "https://self_link",
+ "rel": "self",
+ "type": "application/atom+xml"
+ } ],
+ "openSearch$itemsPerPage": {
+ "$t": "1000"
+ },
+ "openSearch$startIndex": {
+ "$t": "1"
+ },
+ "title": {
+ "$t": "Feed title"
+ },
+ "updated": {
+ "$t": "2011-12-14T01:03:21.151Z"
+ },
+ "xmlns": "http://www.w3.org/2005/Atom",
+ "xmlns$batch": "http://schemas.google.com/gdata/batch",
+ "xmlns$docs": "http://schemas.google.com/docs/2007",
+ "xmlns$gd": "http://schemas.google.com/g/2005",
+ "xmlns$openSearch": "http://a9.com/-/spec/opensearch/1.1/"
+ },
+ "version": "1.0"
+}
+
diff --git a/chrome/test/data/extensions/api_test/filebrowser_component/remote.js b/chrome/test/data/extensions/api_test/filebrowser_component/remote.js
index 321b939..9de6380 100644
--- a/chrome/test/data/extensions/api_test/filebrowser_component/remote.js
+++ b/chrome/test/data/extensions/api_test/filebrowser_component/remote.js
@@ -3,17 +3,23 @@
// found in the LICENSE file.
// This test file checks if we can read the expected contents
-// (kExpectedContents) from the target file (kFileName). What's
+// (kExpectedContents) from the target file (kFileName). We will try to read
+// the file directly, and using a filesystem handler
+// (chorme/test/data/extensions/api_test/filesystem_handler/). What's
// interesting is that we'll read the file via a remote mount point.
-// See extension_local_filesystem_apitest.cc for how this is set up.
+// See external_filesystem_apitest.cc for how this is set up.
-// These should match the counterparts in
-// extension_local_filesystem_apitest.cc.
-var kFileName = 'hello.txt';
-var kExpectedContents = 'hello, world';
+// These should match the counterparts in feeds used in
+// external_filesystem_apitest.cc.
+// The feeds are located in chrome/test/data/chromeos/gdata/.
+var kDirectoryPath = 'gdata/Folder';
+var kFileName = 'File.aBc';
+var kExpectedContents = 'hello, world\0';
+var kNewDirectoryPath = 'gdata/FolderNew';
-TestRunner.prototype.runTest = function() {
- // Get local FS, create dir with a file in it.
+// Gets local filesystem used in tests.
+TestRunner.prototype.init = function() {
+ // Get local FS.
console.log('Requesting local file system...');
chrome.fileBrowserPrivate.requestLocalFileSystem(
this.onFileSystemFetched_.bind(this));
@@ -21,31 +27,103 @@ TestRunner.prototype.runTest = function() {
TestRunner.prototype.onFileSystemFetched_ = function(fs) {
if (!fs) {
- this.errorCallback_(chrome.extensions.lastError);
+ this.errorCallback_(chrome.extensions.lastError,
+ 'Error getting file system: ');
return;
}
- this.fileCreator_.init(fs,
- this.onFileCreatorInit_.bind(this),
- this.errorCallback_.bind(this));
+ this.fileSystem_ = fs;
+ chrome.test.succeed();
+}
+
+TestRunner.prototype.runGetDirTest = function(dirPath, doCreate) {
+ self=this;
+ chrome.test.assertTrue(!!this.fileSystem_);
+ this.fileSystem_.root.getDirectory(dirPath, {create: doCreate},
+ function (entry) {
+ self.directoryEntry_ = entry;
+ chrome.test.succeed();
+ },
+ self.errorCallback_.bind(self, "Error creating directory: "));
+};
+
+TestRunner.prototype.runReadFileTest = function (fileName, expectedText) {
+ var self = this;
+ chrome.test.assertTrue(!!this.directoryEntry_);
+ this.directoryEntry_.getFile(fileName, {},
+ function(entry){
+ self.fileEntry_ = entry;
+ readFile(entry,
+ function(text) {
+ chrome.test.assertEq(expectedText, text);
+ chrome.test.succeed();
+ },
+ self.errorCallback_.bind(self, "Error reading file: "));
+ },
+ self.errorCallback_.bind(self, "Error opening file: "));
};
-TestRunner.prototype.onFileCreatorInit_ = function() {
+TestRunner.prototype.runExecuteReadTask = function() {
+ chrome.test.assertTrue(!!this.fileEntry_);
+
+ // Add listener to be invoked when filesystem handler extension sends us
+ // response.
+ this.listener_ = this.onHandlerRequest_.bind(this);
+ chrome.extension.onRequestExternal.addListener(this.listener_);
+
var self = this;
- this.fileCreator_.openFile(
- kFileName,
- function(file, text) {
- readFile(file,
- function(text) {
- chrome.test.assertEq(kExpectedContents, text);
- chrome.test.succeed();
- },
- self.errorCallback_.bind(self));
- },
- this.errorCallback_.bind(this));
+ var fileURL = this.fileEntry_.toURL();
+ chrome.fileBrowserPrivate.getFileTasks([fileURL],
+ function(tasks) {
+ if (!tasks || !tasks.length) {
+ self.errorCallback_({message: 'No tasks registered'},
+ "Error fetching tasks: ");
+ return;
+ }
+
+ // Execute one of the fetched tasks, and wait for the response from the
+ // file handler that will execute it.
+ chrome.fileBrowserPrivate.executeTask(tasks[0].taskId, [fileURL]);
+ });
+}
+
+// Processes the response from file handler for which file task was executed.
+TestRunner.prototype.onHandlerRequest_ =
+ function(request, sender, sendResponse) {
+ // We don't have to listen for a response anymore.
+ chrome.extension.onRequestExternal.removeListener(this.listener_);
+
+ this.verifyHandlerRequest(request,
+ chrome.test.succeed,
+ this.errorCallback_.bind(this, ""));
+}
+
+TestRunner.prototype.verifyHandlerRequest =
+ function(request, successCallback, errorCallback) {
+ if (!request) {
+ errorCallback({message: "Request from handler not defined."});
+ return;
+ }
+
+ if (!request.fileContent) {
+ var error = request.error || {message: "Undefined error."};
+ errorCallback(error);
+ return;
+ }
+
+ if (request.fileContent != kExpectedContents) {
+ var error = {message: 'Received content does not match. ' +
+ 'Expected "' + originalText + '", ' +
+ 'Got "' + request.fileContent + '".'};
+ errorCallback(error);
+ return;
+ }
+
+ successCallback();
};
-TestRunner.prototype.errorCallback_ = function(error) {
+
+TestRunner.prototype.errorCallback_ = function(error, messagePrefix) {
var msg = '';
if (!error.code) {
msg = error.message;
@@ -71,27 +149,40 @@ TestRunner.prototype.errorCallback_ = function(error) {
break;
};
}
- chrome.test.fail(msg);
+ chrome.test.fail(messagePrefix + msg);
};
-function getDirFromLocationHref() {
- var loc = window.location.href;
- console.log("Opening tab " + loc);
- if (loc.indexOf("#") == -1 ) {
- console.log("No params in url, faling back to default.");
- return "tmp";
- }
-
- loc = unescape(loc.substr(loc.indexOf("#") + 1));
- return (loc[0] == '/') ? loc.substring(1) : loc;
-}
-
function TestRunner() {
- this.fileCreator_ = new TestFileCreator(getDirFromLocationHref(),
- false /* shouldRandomize */);
-}
+ this.fileSystem_ = undefined;
+ this.directoryEntry_ = undefined;
+ this.fileEntry_ = undefined;
+ this.listener_ = undefined;
+};
+
+var testRunner = undefined;
-chrome.test.runTests([function tab() {
- var testRunner = new TestRunner();
- testRunner.runTest();
-}]);
+// TODO(tbarzic): Use test runner used in the tests for the local file system
+// once needed operations are supported.
+chrome.test.runTests([function initTests() {
+ testRunner = new TestRunner();
+ testRunner.init();
+ },
+ function readDirectory() {
+ // Opens a directory on the gdata mount point.
+ // Chrome side of the test will be mocked to think the directory exists.
+ testRunner.runGetDirTest(kDirectoryPath, false);
+ },
+ function readFile() {
+ // Opens a file in the directory opened in the previous test..
+ // Chrome side of the test will be mocked to think the file exists.
+ testRunner.runReadFileTest(kFileName, kExpectedContents);
+ },
+ function executeReadTask() {
+ // Invokes a handler that reads the file opened in the previous test.
+ testRunner.runExecuteReadTask();
+ },
+ function createDir() {
+ // Creates new directory.
+ testRunner.runGetDirTest(kNewDirectoryPath, true);
+ },
+]);