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