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
3// found in the LICENSE file.
4
5#include "base/bind.h"
6#include "base/command_line.h"
7#include "base/path_service.h"
8#include "base/run_loop.h"
9#include "chrome/browser/extensions/extension_apitest.h"
10#include "chrome/browser/sync_file_system/file_status_observer.h"
11#include "chrome/browser/sync_file_system/local_change_processor.h"
12#include "chrome/browser/sync_file_system/mock_remote_file_sync_service.h"
13#include "chrome/browser/sync_file_system/sync_file_system_service.h"
14#include "chrome/browser/sync_file_system/sync_file_system_service_factory.h"
15#include "chrome/browser/sync_file_system/sync_status_code.h"
16#include "chrome/browser/sync_file_system/syncable_file_system_util.h"
17#include "chrome/common/chrome_version_info.h"
18#include "chrome/test/base/test_switches.h"
19#include "storage/browser/fileapi/file_system_url.h"
20#include "storage/browser/quota/quota_manager.h"
21#include "testing/gmock/include/gmock/gmock.h"
22#include "testing/gtest/include/gtest/gtest.h"
23
24using ::testing::_;
25using ::testing::Eq;
26using ::testing::Ne;
27using ::testing::Property;
28using ::testing::Return;
29using storage::FileSystemURL;
30using sync_file_system::MockRemoteFileSyncService;
31using sync_file_system::RemoteFileSyncService;
32using sync_file_system::SyncFileSystemServiceFactory;
33
34namespace {
35
36class SyncFileSystemApiTest : public ExtensionApiTest {
37 public:
38  SyncFileSystemApiTest()
39      : mock_remote_service_(NULL),
40        real_minimum_preserved_space_(0),
41        real_default_quota_(0) {}
42
43  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
44    ExtensionApiTest::SetUpInProcessBrowserTestFixture();
45
46    real_minimum_preserved_space_ =
47        storage::QuotaManager::kMinimumPreserveForSystem;
48    storage::QuotaManager::kMinimumPreserveForSystem = 0;
49
50    // TODO(calvinlo): Update test code after default quota is made const
51    // (http://crbug.com/155488).
52    real_default_quota_ =
53        storage::QuotaManager::kSyncableStorageDefaultHostQuota;
54    storage::QuotaManager::kSyncableStorageDefaultHostQuota = 123456;
55  }
56
57  virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
58    storage::QuotaManager::kMinimumPreserveForSystem =
59        real_minimum_preserved_space_;
60    storage::QuotaManager::kSyncableStorageDefaultHostQuota =
61        real_default_quota_;
62    ExtensionApiTest::TearDownInProcessBrowserTestFixture();
63  }
64
65  virtual void SetUpOnMainThread() OVERRIDE {
66    // Must happen after the browser process is created because instantiating
67    // the factory will instantiate ExtensionSystemFactory which depends on
68    // ExtensionsBrowserClient setup in BrowserProcessImpl.
69    mock_remote_service_ = new ::testing::NiceMock<MockRemoteFileSyncService>;
70    SyncFileSystemServiceFactory::GetInstance()->set_mock_remote_file_service(
71        scoped_ptr<RemoteFileSyncService>(mock_remote_service_));
72    ExtensionApiTest::SetUpOnMainThread();
73  }
74
75  ::testing::NiceMock<MockRemoteFileSyncService>* mock_remote_service() {
76    return mock_remote_service_;
77  }
78
79 private:
80  ::testing::NiceMock<MockRemoteFileSyncService>* mock_remote_service_;
81  int64 real_minimum_preserved_space_;
82  int64 real_default_quota_;
83};
84
85ACTION_P(NotifyOkStateAndCallback, mock_remote_service) {
86  mock_remote_service->NotifyRemoteServiceStateUpdated(
87      sync_file_system::REMOTE_SERVICE_OK, "Test event description.");
88  base::MessageLoopProxy::current()->PostTask(
89      FROM_HERE, base::Bind(arg1, sync_file_system::SYNC_STATUS_OK));
90}
91
92ACTION_P2(UpdateRemoteChangeQueue, origin, mock_remote_service) {
93  *origin = arg0;
94  mock_remote_service->NotifyRemoteChangeQueueUpdated(1);
95}
96
97ACTION_P5(ReturnWithFakeFileAddedStatus,
98          origin,
99          mock_remote_service,
100          sync_direction,
101          sync_file_status,
102          sync_action_taken) {
103  FileSystemURL mock_url = sync_file_system::CreateSyncableFileSystemURL(
104      *origin,
105      base::FilePath(FILE_PATH_LITERAL("foo.txt")));
106  mock_remote_service->NotifyRemoteChangeQueueUpdated(0);
107  base::MessageLoopProxy::current()->PostTask(
108      FROM_HERE, base::Bind(arg0,
109                            sync_file_system::SYNC_STATUS_OK,
110                            mock_url));
111  mock_remote_service->NotifyFileStatusChanged(
112      mock_url, sync_direction, sync_file_status, sync_action_taken);
113}
114
115}  // namespace
116
117IN_PROC_BROWSER_TEST_F(SyncFileSystemApiTest, GetFileStatus) {
118  ASSERT_TRUE(RunPlatformAppTest("sync_file_system/get_file_status"))
119      << message_;
120}
121
122IN_PROC_BROWSER_TEST_F(SyncFileSystemApiTest, GetFileStatuses) {
123  // Mocking to return IsConflicting() == true only for the path "Conflicting".
124  base::FilePath conflicting = base::FilePath::FromUTF8Unsafe("Conflicting");
125  ASSERT_TRUE(RunPlatformAppTest("sync_file_system/get_file_statuses"))
126      << message_;
127}
128
129IN_PROC_BROWSER_TEST_F(SyncFileSystemApiTest, GetUsageAndQuota) {
130  ASSERT_TRUE(RunExtensionTest("sync_file_system/get_usage_and_quota"))
131      << message_;
132}
133
134IN_PROC_BROWSER_TEST_F(SyncFileSystemApiTest, OnFileStatusChanged) {
135  // Mock a pending remote change to be synced.
136  GURL origin;
137  EXPECT_CALL(*mock_remote_service(), RegisterOrigin(_, _))
138      .WillOnce(UpdateRemoteChangeQueue(&origin, mock_remote_service()));
139  EXPECT_CALL(*mock_remote_service(), ProcessRemoteChange(_))
140      .WillOnce(ReturnWithFakeFileAddedStatus(
141          &origin,
142          mock_remote_service(),
143          sync_file_system::SYNC_FILE_STATUS_SYNCED,
144          sync_file_system::SYNC_ACTION_ADDED,
145          sync_file_system::SYNC_DIRECTION_REMOTE_TO_LOCAL));
146  ASSERT_TRUE(RunPlatformAppTest("sync_file_system/on_file_status_changed"))
147      << message_;
148}
149
150IN_PROC_BROWSER_TEST_F(SyncFileSystemApiTest, OnFileStatusChangedDeleted) {
151  // Mock a pending remote change to be synced.
152  GURL origin;
153  EXPECT_CALL(*mock_remote_service(), RegisterOrigin(_, _))
154      .WillOnce(UpdateRemoteChangeQueue(&origin, mock_remote_service()));
155  EXPECT_CALL(*mock_remote_service(), ProcessRemoteChange(_))
156      .WillOnce(ReturnWithFakeFileAddedStatus(
157          &origin,
158          mock_remote_service(),
159          sync_file_system::SYNC_FILE_STATUS_SYNCED,
160          sync_file_system::SYNC_ACTION_DELETED,
161          sync_file_system::SYNC_DIRECTION_REMOTE_TO_LOCAL));
162  ASSERT_TRUE(RunPlatformAppTest(
163      "sync_file_system/on_file_status_changed_deleted"))
164      << message_;
165}
166
167IN_PROC_BROWSER_TEST_F(SyncFileSystemApiTest, OnServiceStatusChanged) {
168  EXPECT_CALL(*mock_remote_service(), RegisterOrigin(_, _))
169      .WillOnce(NotifyOkStateAndCallback(mock_remote_service()));
170  ASSERT_TRUE(RunPlatformAppTest("sync_file_system/on_service_status_changed"))
171      << message_;
172}
173
174IN_PROC_BROWSER_TEST_F(SyncFileSystemApiTest, RequestFileSystem) {
175  EXPECT_CALL(*mock_remote_service(), RegisterOrigin(_, _)).Times(1);
176  ASSERT_TRUE(RunPlatformAppTest("sync_file_system/request_file_system"))
177      << message_;
178}
179
180IN_PROC_BROWSER_TEST_F(SyncFileSystemApiTest, WriteFileThenGetUsage) {
181  ASSERT_TRUE(RunPlatformAppTest("sync_file_system/write_file_then_get_usage"))
182      << message_;
183}
184
185IN_PROC_BROWSER_TEST_F(SyncFileSystemApiTest, ConflictResolutionPolicy) {
186  ASSERT_TRUE(RunPlatformAppTest("sync_file_system/conflict_resolution_policy"))
187      << message_;
188}
189
190IN_PROC_BROWSER_TEST_F(SyncFileSystemApiTest, GetServiceStatus) {
191  mock_remote_service()->SetServiceState(
192      sync_file_system::REMOTE_SERVICE_AUTHENTICATION_REQUIRED);
193  ASSERT_TRUE(RunPlatformAppTest("sync_file_system/get_service_status"))
194      << message_;
195}
196