supervised_user_registration_utility_unittest.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
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 "base/bind.h"
6#include "base/message_loop/message_loop.h"
7#include "base/prefs/scoped_user_pref_update.h"
8#include "base/run_loop.h"
9#include "base/strings/utf_string_conversions.h"
10#include "base/threading/sequenced_worker_pool.h"
11#include "chrome/browser/supervised_user/supervised_user_refresh_token_fetcher.h"
12#include "chrome/browser/supervised_user/supervised_user_registration_utility.h"
13#include "chrome/browser/supervised_user/supervised_user_shared_settings_service.h"
14#include "chrome/browser/supervised_user/supervised_user_shared_settings_service_factory.h"
15#include "chrome/browser/supervised_user/supervised_user_sync_service.h"
16#include "chrome/browser/supervised_user/supervised_user_sync_service_factory.h"
17#include "chrome/common/pref_names.h"
18#include "chrome/test/base/testing_pref_service_syncable.h"
19#include "chrome/test/base/testing_profile.h"
20#include "content/public/browser/browser_thread.h"
21#include "google_apis/gaia/google_service_auth_error.h"
22#include "sync/api/attachments/attachment_id.h"
23#include "sync/api/attachments/attachment_service_proxy_for_test.h"
24#include "sync/api/sync_change.h"
25#include "sync/api/sync_error_factory_mock.h"
26#include "sync/protocol/sync.pb.h"
27#include "testing/gtest/include/gtest/gtest.h"
28
29using sync_pb::ManagedUserSpecifics;
30using syncer::SUPERVISED_USERS;
31using syncer::SyncChange;
32using syncer::SyncChangeList;
33using syncer::SyncChangeProcessor;
34using syncer::SyncData;
35using syncer::SyncDataList;
36using syncer::SyncError;
37using syncer::SyncErrorFactory;
38using syncer::SyncMergeResult;
39
40namespace {
41
42const char kSupervisedUserToken[] = "supervisedusertoken";
43
44class MockChangeProcessor : public SyncChangeProcessor {
45 public:
46  MockChangeProcessor() {}
47  virtual ~MockChangeProcessor() {}
48
49  // SyncChangeProcessor implementation:
50  virtual SyncError ProcessSyncChanges(
51      const tracked_objects::Location& from_here,
52      const SyncChangeList& change_list) OVERRIDE;
53
54  virtual SyncDataList GetAllSyncData(syncer::ModelType type) const
55      OVERRIDE {
56    return SyncDataList();
57  }
58
59  const SyncChangeList& changes() const { return change_list_; }
60
61 private:
62  SyncChangeList change_list_;
63};
64
65SyncError MockChangeProcessor::ProcessSyncChanges(
66    const tracked_objects::Location& from_here,
67    const SyncChangeList& change_list) {
68  change_list_ = change_list;
69  return SyncError();
70}
71
72class MockSupervisedUserRefreshTokenFetcher
73    : public SupervisedUserRefreshTokenFetcher {
74 public:
75  MockSupervisedUserRefreshTokenFetcher() {}
76  virtual ~MockSupervisedUserRefreshTokenFetcher() {}
77
78  // SupervisedUserRefreshTokenFetcher implementation:
79  virtual void Start(const std::string& supervised_user_id,
80                     const std::string& device_name,
81                     const TokenCallback& callback) OVERRIDE {
82    GoogleServiceAuthError error(GoogleServiceAuthError::NONE);
83    callback.Run(error, kSupervisedUserToken);
84  }
85};
86
87}  // namespace
88
89class SupervisedUserRegistrationUtilityTest : public ::testing::Test {
90 public:
91  SupervisedUserRegistrationUtilityTest();
92  virtual ~SupervisedUserRegistrationUtilityTest();
93
94  virtual void TearDown() OVERRIDE;
95
96 protected:
97  scoped_ptr<SyncChangeProcessor> CreateChangeProcessor();
98  scoped_ptr<SyncErrorFactory> CreateErrorFactory();
99  SyncData CreateRemoteData(const std::string& id, const std::string& name);
100
101  SyncMergeResult StartInitialSync();
102
103  SupervisedUserRegistrationUtility::RegistrationCallback
104      GetRegistrationCallback();
105
106  SupervisedUserRegistrationUtility* GetRegistrationUtility();
107
108  void Acknowledge();
109
110  PrefService* prefs() { return profile_.GetTestingPrefService(); }
111  SupervisedUserSyncService* service() { return service_; }
112  SupervisedUserSharedSettingsService* shared_settings_service() {
113    return shared_settings_service_;
114  }
115  MockChangeProcessor* change_processor() { return change_processor_; }
116
117  bool received_callback() const { return received_callback_; }
118  const GoogleServiceAuthError& error() const { return error_; }
119  const std::string& token() const { return token_; }
120
121 private:
122  void OnSupervisedUserRegistered(const GoogleServiceAuthError& error,
123                                  const std::string& token);
124
125  base::MessageLoop message_loop_;
126  base::RunLoop run_loop_;
127  TestingProfile profile_;
128  SupervisedUserSyncService* service_;
129  SupervisedUserSharedSettingsService* shared_settings_service_;
130  scoped_ptr<SupervisedUserRegistrationUtility> registration_utility_;
131
132  // Owned by the SupervisedUserSyncService.
133  MockChangeProcessor* change_processor_;
134
135  // A unique ID for creating "remote" Sync data.
136  int64 sync_data_id_;
137
138  // Whether OnSupervisedUserRegistered has been called.
139  bool received_callback_;
140
141  // Hold the registration result (either an error, or a token).
142  GoogleServiceAuthError error_;
143  std::string token_;
144
145  base::WeakPtrFactory<SupervisedUserRegistrationUtilityTest> weak_ptr_factory_;
146};
147
148SupervisedUserRegistrationUtilityTest::SupervisedUserRegistrationUtilityTest()
149    : change_processor_(NULL),
150      sync_data_id_(0),
151      received_callback_(false),
152      error_(GoogleServiceAuthError::NUM_STATES),
153      weak_ptr_factory_(this) {
154  service_ = SupervisedUserSyncServiceFactory::GetForProfile(&profile_);
155  shared_settings_service_ =
156      SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext(
157          &profile_);
158}
159
160SupervisedUserRegistrationUtilityTest::
161    ~SupervisedUserRegistrationUtilityTest() {
162  EXPECT_FALSE(weak_ptr_factory_.HasWeakPtrs());
163}
164
165void SupervisedUserRegistrationUtilityTest::TearDown() {
166  content::BrowserThread::GetBlockingPool()->FlushForTesting();
167  base::RunLoop().RunUntilIdle();
168}
169
170scoped_ptr<SyncChangeProcessor>
171SupervisedUserRegistrationUtilityTest::CreateChangeProcessor() {
172  EXPECT_FALSE(change_processor_);
173  change_processor_ = new MockChangeProcessor();
174  return scoped_ptr<SyncChangeProcessor>(change_processor_);
175}
176
177scoped_ptr<SyncErrorFactory>
178SupervisedUserRegistrationUtilityTest::CreateErrorFactory() {
179  return scoped_ptr<SyncErrorFactory>(new syncer::SyncErrorFactoryMock());
180}
181
182SyncMergeResult SupervisedUserRegistrationUtilityTest::StartInitialSync() {
183  SyncDataList initial_sync_data;
184  SyncMergeResult result =
185      service()->MergeDataAndStartSyncing(SUPERVISED_USERS,
186                                          initial_sync_data,
187                                          CreateChangeProcessor(),
188                                          CreateErrorFactory());
189  EXPECT_FALSE(result.error().IsSet());
190  return result;
191}
192
193SupervisedUserRegistrationUtility::RegistrationCallback
194SupervisedUserRegistrationUtilityTest::GetRegistrationCallback() {
195  return base::Bind(
196      &SupervisedUserRegistrationUtilityTest::OnSupervisedUserRegistered,
197      weak_ptr_factory_.GetWeakPtr());
198}
199
200SupervisedUserRegistrationUtility*
201SupervisedUserRegistrationUtilityTest::GetRegistrationUtility() {
202  if (registration_utility_.get())
203    return registration_utility_.get();
204
205  scoped_ptr<SupervisedUserRefreshTokenFetcher> token_fetcher(
206      new MockSupervisedUserRefreshTokenFetcher);
207  registration_utility_.reset(
208      SupervisedUserRegistrationUtility::CreateImpl(prefs(),
209                                                    token_fetcher.Pass(),
210                                                    service(),
211                                                    shared_settings_service()));
212  return registration_utility_.get();
213}
214
215void SupervisedUserRegistrationUtilityTest::Acknowledge() {
216  SyncChangeList new_changes;
217  const SyncChangeList& changes = change_processor()->changes();
218  for (SyncChangeList::const_iterator it = changes.begin(); it != changes.end();
219       ++it) {
220    EXPECT_EQ(SyncChange::ACTION_ADD, it->change_type());
221    ::sync_pb::EntitySpecifics specifics = it->sync_data().GetSpecifics();
222    EXPECT_FALSE(specifics.managed_user().acknowledged());
223    specifics.mutable_managed_user()->set_acknowledged(true);
224    new_changes.push_back(
225        SyncChange(FROM_HERE,
226                   SyncChange::ACTION_UPDATE,
227                   SyncData::CreateRemoteData(
228                       ++sync_data_id_,
229                       specifics,
230                       base::Time(),
231                       syncer::AttachmentIdList(),
232                       syncer::AttachmentServiceProxyForTest::Create())));
233  }
234  service()->ProcessSyncChanges(FROM_HERE, new_changes);
235
236  run_loop_.Run();
237}
238
239void SupervisedUserRegistrationUtilityTest::OnSupervisedUserRegistered(
240    const GoogleServiceAuthError& error,
241    const std::string& token) {
242  received_callback_ = true;
243  error_ = error;
244  token_ = token;
245  run_loop_.Quit();
246}
247
248TEST_F(SupervisedUserRegistrationUtilityTest, Register) {
249  StartInitialSync();
250  GetRegistrationUtility()->Register(
251      SupervisedUserRegistrationUtility::GenerateNewSupervisedUserId(),
252      SupervisedUserRegistrationInfo(base::ASCIIToUTF16("Dug"), 0),
253      GetRegistrationCallback());
254  EXPECT_EQ(1u, prefs()->GetDictionary(prefs::kSupervisedUsers)->size());
255  Acknowledge();
256
257  EXPECT_TRUE(received_callback());
258  EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
259  EXPECT_FALSE(token().empty());
260}
261
262TEST_F(SupervisedUserRegistrationUtilityTest, RegisterBeforeInitialSync) {
263  GetRegistrationUtility()->Register(
264      SupervisedUserRegistrationUtility::GenerateNewSupervisedUserId(),
265      SupervisedUserRegistrationInfo(base::ASCIIToUTF16("Nemo"), 5),
266      GetRegistrationCallback());
267  EXPECT_EQ(1u, prefs()->GetDictionary(prefs::kSupervisedUsers)->size());
268  StartInitialSync();
269  Acknowledge();
270
271  EXPECT_TRUE(received_callback());
272  EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
273  EXPECT_FALSE(token().empty());
274}
275
276TEST_F(SupervisedUserRegistrationUtilityTest,
277       SyncServiceShutdownBeforeRegFinish) {
278  StartInitialSync();
279  GetRegistrationUtility()->Register(
280      SupervisedUserRegistrationUtility::GenerateNewSupervisedUserId(),
281      SupervisedUserRegistrationInfo(base::ASCIIToUTF16("Remy"), 12),
282      GetRegistrationCallback());
283  EXPECT_EQ(1u, prefs()->GetDictionary(prefs::kSupervisedUsers)->size());
284  service()->Shutdown();
285  EXPECT_EQ(0u, prefs()->GetDictionary(prefs::kSupervisedUsers)->size());
286  EXPECT_TRUE(received_callback());
287  EXPECT_EQ(GoogleServiceAuthError::REQUEST_CANCELED, error().state());
288  EXPECT_EQ(std::string(), token());
289}
290
291TEST_F(SupervisedUserRegistrationUtilityTest, StopSyncingBeforeRegFinish) {
292  StartInitialSync();
293  GetRegistrationUtility()->Register(
294      SupervisedUserRegistrationUtility::GenerateNewSupervisedUserId(),
295      SupervisedUserRegistrationInfo(base::ASCIIToUTF16("Mike"), 17),
296      GetRegistrationCallback());
297  EXPECT_EQ(1u, prefs()->GetDictionary(prefs::kSupervisedUsers)->size());
298  service()->StopSyncing(SUPERVISED_USERS);
299  EXPECT_EQ(0u, prefs()->GetDictionary(prefs::kSupervisedUsers)->size());
300  EXPECT_TRUE(received_callback());
301  EXPECT_EQ(GoogleServiceAuthError::REQUEST_CANCELED, error().state());
302  EXPECT_EQ(std::string(), token());
303}
304