Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(521)

Side by Side Diff: components/signin/core/browser/account_tracker_service_unittest.cc

Issue 425823002: Create a new AccountTrackerService (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « components/signin/core/browser/account_tracker_service.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 <algorithm>
6 #include <vector>
7
8 #include "base/message_loop/message_loop.h"
9 #include "base/prefs/pref_registry_simple.h"
10 #include "base/prefs/testing_pref_service.h"
11 #include "base/strings/stringprintf.h"
12 #include "components/signin/core/browser/account_tracker_service.h"
13 #include "google_apis/gaia/fake_oauth2_token_service.h"
14 #include "google_apis/gaia/gaia_oauth_client.h"
15 #include "net/http/http_status_code.h"
16 #include "net/url_request/test_url_fetcher_factory.h"
17 #include "net/url_request/url_fetcher_delegate.h"
18 #include "net/url_request/url_request_test_util.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 namespace {
22
23 enum TrackingEventType {
24 UPDATED,
25 REMOVED,
26 };
27
28 std::string AccountIdToEmail(const std::string account_id) {
29 return account_id + "@gmail.com";
30 }
31
32 std::string AccountIdToGaiaId(const std::string account_id) {
33 return "gaia-" + account_id;
34 }
35
36 class TrackingEvent {
37 public:
38 TrackingEvent(TrackingEventType type,
39 const std::string& account_id,
40 const std::string& gaia_id)
41 : type_(type),
42 account_id_(account_id),
43 gaia_id_(gaia_id) {}
44
45 TrackingEvent(TrackingEventType type,
46 const std::string& account_id)
47 : type_(type),
48 account_id_(account_id),
49 gaia_id_(AccountIdToGaiaId(account_id)) {}
50
51 bool operator==(const TrackingEvent& event) const {
52 return type_ == event.type_ && account_id_ == event.account_id_ &&
53 gaia_id_ == event.gaia_id_;
54 }
55
56 std::string ToString() const {
57 const char * typestr = "INVALID";
58 switch (type_) {
59 case UPDATED:
60 typestr = "UPD";
61 break;
62 case REMOVED:
63 typestr = "REM";
64 break;
65 }
66 return base::StringPrintf("{ type: %s, account_id: %s, gaia: %s }",
67 typestr,
68 account_id_.c_str(),
69 gaia_id_.c_str());
70 }
71
72 private:
73 friend bool CompareByUser(TrackingEvent a, TrackingEvent b);
74
75 TrackingEventType type_;
76 std::string account_id_;
77 std::string gaia_id_;
78 };
79
80 bool CompareByUser(TrackingEvent a, TrackingEvent b) {
81 return a.account_id_ < b.account_id_;
82 }
83
84 std::string Str(const std::vector<TrackingEvent>& events) {
85 std::string str = "[";
86 bool needs_comma = false;
87 for (std::vector<TrackingEvent>::const_iterator it =
88 events.begin(); it != events.end(); ++it) {
89 if (needs_comma)
90 str += ",\n ";
91 needs_comma = true;
92 str += it->ToString();
93 }
94 str += "]";
95 return str;
96 }
97
98 class AccountTrackerObserver : public AccountTrackerService::Observer {
99 public:
100 AccountTrackerObserver() {}
101 virtual ~AccountTrackerObserver() {}
102
103 void Clear();
104 void SortEventsByUser();
105
106 testing::AssertionResult CheckEvents();
107 testing::AssertionResult CheckEvents(const TrackingEvent& e1);
108 testing::AssertionResult CheckEvents(const TrackingEvent& e1,
109 const TrackingEvent& e2);
110 testing::AssertionResult CheckEvents(const TrackingEvent& e1,
111 const TrackingEvent& e2,
112 const TrackingEvent& e3);
113
114 private:
115 // AccountTrackerService::Observer implementation
116 virtual void OnAccountUpdated(
117 const AccountTrackerService::AccountInfo& ids) OVERRIDE;
118 virtual void OnAccountRemoved(
119 const AccountTrackerService::AccountInfo& ids) OVERRIDE;
120
121 testing::AssertionResult CheckEvents(
122 const std::vector<TrackingEvent>& events);
123
124 std::vector<TrackingEvent> events_;
125 };
126
127 void AccountTrackerObserver::OnAccountUpdated(
128 const AccountTrackerService::AccountInfo& ids) {
129 events_.push_back(TrackingEvent(UPDATED, ids.account_id, ids.gaia));
130 }
131
132 void AccountTrackerObserver::OnAccountRemoved(
133 const AccountTrackerService::AccountInfo& ids) {
134 events_.push_back(TrackingEvent(REMOVED, ids.account_id, ids.gaia));
135 }
136
137 void AccountTrackerObserver::Clear() {
138 events_.clear();
139 }
140
141 void AccountTrackerObserver::SortEventsByUser() {
142 std::stable_sort(events_.begin(), events_.end(), CompareByUser);
143 }
144
145 testing::AssertionResult AccountTrackerObserver::CheckEvents() {
146 std::vector<TrackingEvent> events;
147 return CheckEvents(events);
148 }
149
150 testing::AssertionResult AccountTrackerObserver::CheckEvents(
151 const TrackingEvent& e1) {
152 std::vector<TrackingEvent> events;
153 events.push_back(e1);
154 return CheckEvents(events);
155 }
156
157 testing::AssertionResult AccountTrackerObserver::CheckEvents(
158 const TrackingEvent& e1,
159 const TrackingEvent& e2) {
160 std::vector<TrackingEvent> events;
161 events.push_back(e1);
162 events.push_back(e2);
163 return CheckEvents(events);
164 }
165
166 testing::AssertionResult AccountTrackerObserver::CheckEvents(
167 const TrackingEvent& e1,
168 const TrackingEvent& e2,
169 const TrackingEvent& e3) {
170 std::vector<TrackingEvent> events;
171 events.push_back(e1);
172 events.push_back(e2);
173 events.push_back(e3);
174 return CheckEvents(events);
175 }
176
177 testing::AssertionResult AccountTrackerObserver::CheckEvents(
178 const std::vector<TrackingEvent>& events) {
179 std::string maybe_newline = (events.size() + events_.size()) > 2 ? "\n" : "";
180 testing::AssertionResult result(
181 (events_ == events)
182 ? testing::AssertionSuccess()
183 : (testing::AssertionFailure()
184 << "Expected " << maybe_newline << Str(events) << ", "
185 << maybe_newline << "Got " << maybe_newline << Str(events_)));
186 events_.clear();
187 return result;
188 }
189
190 } // namespace
191
192 class AccountTrackerServiceTest : public testing::Test {
193 public:
194 AccountTrackerServiceTest() {}
195
196 virtual ~AccountTrackerServiceTest() {}
197
198 virtual void SetUp() OVERRIDE {
199 fake_oauth2_token_service_.reset(new FakeOAuth2TokenService());
200
201 pref_service_.registry()->RegisterListPref(
202 AccountTrackerService::kAccountInfoPref);
203
204 account_tracker_.reset(new AccountTrackerService());
205 account_tracker_->Initialize(fake_oauth2_token_service_.get(),
206 &pref_service_,
207 new net::TestURLRequestContextGetter(
208 message_loop_.message_loop_proxy()));
209 account_tracker_->AddObserver(&observer_);
210 }
211
212 virtual void TearDown() OVERRIDE {
213 account_tracker_->RemoveObserver(&observer_);
214 account_tracker_->Shutdown();
215 }
216
217 void SimulateTokenAvailable(const std::string& account_id) {
218 fake_oauth2_token_service_->AddAccount(account_id);
219 }
220
221 void SimulateTokenRevoked(const std::string& account_id) {
222 fake_oauth2_token_service_->RemoveAccount(account_id);
223 }
224
225 // Helpers to fake access token and user info fetching
226 void IssueAccessToken(const std::string& account_id) {
227 fake_oauth2_token_service_->IssueAllTokensForAccount(
228 account_id, "access_token-" + account_id, base::Time::Max());
229 }
230
231 std::string GenerateValidTokenInfoResponse(const std::string& account_id) {
232 return base::StringPrintf("{\"id\": \"%s\", \"email\": \"%s\"}",
233 AccountIdToGaiaId(account_id).c_str(),
234 AccountIdToEmail(account_id).c_str());
235 }
236
237 void ReturnOAuthUrlFetchSuccess(const std::string& account_id);
238 void ReturnOAuthUrlFetchFailure(const std::string& account_id);
239
240 base::MessageLoopForIO* message_loop() { return &message_loop_; }
241 AccountTrackerService* account_tracker() { return account_tracker_.get(); }
242 AccountTrackerObserver* observer() { return &observer_; }
243 OAuth2TokenService* token_service() {
244 return fake_oauth2_token_service_.get();
245 }
246 TestingPrefServiceSimple* pref_service() { return &pref_service_; }
247
248 private:
249 void ReturnOAuthUrlFetchResults(int fetcher_id,
250 net::HttpStatusCode response_code,
251 const std::string& response_string);
252
253 base::MessageLoopForIO message_loop_;
254 net::TestURLFetcherFactory test_fetcher_factory_;
255 scoped_ptr<FakeOAuth2TokenService> fake_oauth2_token_service_;
256 TestingPrefServiceSimple pref_service_;
257 scoped_ptr<AccountTrackerService> account_tracker_;
258 AccountTrackerObserver observer_;
259 };
260
261 void AccountTrackerServiceTest::ReturnOAuthUrlFetchResults(
262 int fetcher_id,
263 net::HttpStatusCode response_code,
264 const std::string& response_string) {
265 net::TestURLFetcher* fetcher =
266 test_fetcher_factory_.GetFetcherByID(fetcher_id);
267 ASSERT_TRUE(fetcher);
268 fetcher->set_response_code(response_code);
269 fetcher->SetResponseString(response_string);
270 fetcher->delegate()->OnURLFetchComplete(fetcher);
271 }
272
273 void AccountTrackerServiceTest::ReturnOAuthUrlFetchSuccess(
274 const std::string& account_id) {
275 IssueAccessToken(account_id);
276 ReturnOAuthUrlFetchResults(gaia::GaiaOAuthClient::kUrlFetcherId,
277 net::HTTP_OK,
278 GenerateValidTokenInfoResponse(account_id));
279 }
280
281 void AccountTrackerServiceTest::ReturnOAuthUrlFetchFailure(
282 const std::string& account_id) {
283 IssueAccessToken(account_id);
284 ReturnOAuthUrlFetchResults(
285 gaia::GaiaOAuthClient::kUrlFetcherId, net::HTTP_BAD_REQUEST, "");
286 }
287
288 TEST_F(AccountTrackerServiceTest, Basic) {
289 }
290
291 TEST_F(AccountTrackerServiceTest, TokenAvailable) {
292 SimulateTokenAvailable("alpha");
293 ASSERT_FALSE(account_tracker()->IsAllUserInfoFetched());
294 ASSERT_TRUE(observer()->CheckEvents());
295 }
296
297 TEST_F(AccountTrackerServiceTest, TokenAvailable_Revoked) {
298 SimulateTokenAvailable("alpha");
299 SimulateTokenRevoked("alpha");
300 ASSERT_TRUE(account_tracker()->IsAllUserInfoFetched());
301 ASSERT_TRUE(observer()->CheckEvents());
302 }
303
304 TEST_F(AccountTrackerServiceTest, TokenAvailable_UserInfo) {
305 SimulateTokenAvailable("alpha");
306 ReturnOAuthUrlFetchSuccess("alpha");
307 ASSERT_TRUE(account_tracker()->IsAllUserInfoFetched());
308 ASSERT_TRUE(observer()->CheckEvents(TrackingEvent(UPDATED, "alpha")));
309 }
310
311 TEST_F(AccountTrackerServiceTest, TokenAvailable_UserInfo_Revoked) {
312 SimulateTokenAvailable("alpha");
313 ReturnOAuthUrlFetchSuccess("alpha");
314 ASSERT_TRUE(account_tracker()->IsAllUserInfoFetched());
315 ASSERT_TRUE(observer()->CheckEvents(TrackingEvent(UPDATED, "alpha")));
316 SimulateTokenRevoked("alpha");
317 ASSERT_TRUE(observer()->CheckEvents(TrackingEvent(REMOVED, "alpha")));
318 }
319
320 TEST_F(AccountTrackerServiceTest, TokenAvailable_UserInfoFailed) {
321 SimulateTokenAvailable("alpha");
322 ReturnOAuthUrlFetchFailure("alpha");
323 ASSERT_TRUE(account_tracker()->IsAllUserInfoFetched());
324 ASSERT_TRUE(observer()->CheckEvents());
325 }
326
327 TEST_F(AccountTrackerServiceTest, TokenAlreadyExists) {
328 SimulateTokenAvailable("alpha");
329 AccountTrackerService tracker;
330 AccountTrackerObserver observer;
331 tracker.AddObserver(&observer);
332 tracker.Initialize(token_service(),
333 pref_service(),
334 new net::TestURLRequestContextGetter(
335 message_loop()->message_loop_proxy()));
336 ASSERT_FALSE(tracker.IsAllUserInfoFetched());
337 ASSERT_TRUE(observer.CheckEvents());
338 tracker.RemoveObserver(&observer);
339 tracker.Shutdown();
340 }
341
342 TEST_F(AccountTrackerServiceTest, TwoTokenAvailable_TwoUserInfo) {
343 SimulateTokenAvailable("alpha");
344 SimulateTokenAvailable("beta");
345 ReturnOAuthUrlFetchSuccess("alpha");
346 ReturnOAuthUrlFetchSuccess("beta");
347 ASSERT_TRUE(account_tracker()->IsAllUserInfoFetched());
348 ASSERT_TRUE(observer()->CheckEvents(TrackingEvent(UPDATED, "alpha"),
349 TrackingEvent(UPDATED, "beta")));
350 }
351
352 TEST_F(AccountTrackerServiceTest, TwoTokenAvailable_OneUserInfo) {
353 SimulateTokenAvailable("alpha");
354 SimulateTokenAvailable("beta");
355 ReturnOAuthUrlFetchSuccess("beta");
356 ASSERT_FALSE(account_tracker()->IsAllUserInfoFetched());
357 ASSERT_TRUE(observer()->CheckEvents(TrackingEvent(UPDATED, "beta")));
358 ReturnOAuthUrlFetchSuccess("alpha");
359 ASSERT_TRUE(account_tracker()->IsAllUserInfoFetched());
360 ASSERT_TRUE(observer()->CheckEvents(TrackingEvent(UPDATED, "alpha")));
361 }
362
363 TEST_F(AccountTrackerServiceTest, GetAccounts) {
364 SimulateTokenAvailable("alpha");
365 SimulateTokenAvailable("beta");
366 SimulateTokenAvailable("gamma");
367 ReturnOAuthUrlFetchSuccess("alpha");
368 ReturnOAuthUrlFetchSuccess("beta");
369 ReturnOAuthUrlFetchSuccess("gamma");
370
371 std::vector<AccountTrackerService::AccountInfo> infos =
372 account_tracker()->GetAccounts();
373
374 EXPECT_EQ(3u, infos.size());
375 EXPECT_EQ("alpha", infos[0].account_id);
376 EXPECT_EQ(AccountIdToGaiaId("alpha"), infos[0].gaia);
377 EXPECT_EQ(AccountIdToEmail("alpha"), infos[0].email);
378 EXPECT_EQ("beta", infos[1].account_id);
379 EXPECT_EQ(AccountIdToGaiaId("beta"), infos[1].gaia);
380 EXPECT_EQ(AccountIdToEmail("beta"), infos[1].email);
381 EXPECT_EQ("gamma", infos[2].account_id);
382 EXPECT_EQ(AccountIdToGaiaId("gamma"), infos[2].gaia);
383 EXPECT_EQ(AccountIdToEmail("gamma"), infos[2].email);
384 }
385
386 TEST_F(AccountTrackerServiceTest, GetAccountInfo_Empty) {
387 AccountTrackerService::AccountInfo info =
388 account_tracker()->GetAccountInfo("alpha");
389 ASSERT_EQ("", info.account_id);
390 }
391
392 TEST_F(AccountTrackerServiceTest, GetAccountInfo_TokenAvailable) {
393 SimulateTokenAvailable("alpha");
394 AccountTrackerService::AccountInfo info =
395 account_tracker()->GetAccountInfo("alpha");
396 ASSERT_EQ("alpha", info.account_id);
397 ASSERT_EQ("", info.gaia);
398 ASSERT_EQ("", info.email);
399 }
400
401 TEST_F(AccountTrackerServiceTest, GetAccountInfo_TokenAvailable_UserInfo) {
402 SimulateTokenAvailable("alpha");
403 ReturnOAuthUrlFetchSuccess("alpha");
404 AccountTrackerService::AccountInfo info =
405 account_tracker()->GetAccountInfo("alpha");
406 ASSERT_EQ("alpha", info.account_id);
407 ASSERT_EQ(AccountIdToGaiaId("alpha"), info.gaia);
408 ASSERT_EQ(AccountIdToEmail("alpha"), info.email);
409 }
410
411 TEST_F(AccountTrackerServiceTest, FindAccountInfoByGaiaId) {
412 SimulateTokenAvailable("alpha");
413 ReturnOAuthUrlFetchSuccess("alpha");
414
415 std::string gaia_id = AccountIdToGaiaId("alpha");
416 AccountTrackerService::AccountInfo info =
417 account_tracker()->FindAccountInfoByGaiaId(gaia_id);
418 ASSERT_EQ("alpha", info.account_id);
419 ASSERT_EQ(gaia_id, info.gaia);
420
421 gaia_id = AccountIdToGaiaId("beta");
422 info = account_tracker()->FindAccountInfoByGaiaId(gaia_id);
423 ASSERT_EQ("", info.account_id);
424 }
425
426 TEST_F(AccountTrackerServiceTest, FindAccountInfoByEmail) {
427 SimulateTokenAvailable("alpha");
428 ReturnOAuthUrlFetchSuccess("alpha");
429
430 std::string email = AccountIdToEmail("alpha");
431 AccountTrackerService::AccountInfo info =
432 account_tracker()->FindAccountInfoByEmail(email);
433 ASSERT_EQ("alpha", info.account_id);
434 ASSERT_EQ(email, info.email);
435
436 // Should also work with "canonically-equal" email addresses.
437 info = account_tracker()->FindAccountInfoByEmail("Alpha@Gmail.COM");
438 ASSERT_EQ("alpha", info.account_id);
439 ASSERT_EQ(email, info.email);
440 info = account_tracker()->FindAccountInfoByEmail("al.pha@gmail.com");
441 ASSERT_EQ("alpha", info.account_id);
442 ASSERT_EQ(email, info.email);
443
444 email = AccountIdToEmail("beta");
445 info = account_tracker()->FindAccountInfoByEmail(email);
446 ASSERT_EQ("", info.account_id);
447 }
448
449 TEST_F(AccountTrackerServiceTest, Persistence) {
450 // Create a tracker and add two accounts. This should cause the accounts
451 // to be saved to persistence.
452 {
453 AccountTrackerService tracker;
454 tracker.Initialize(token_service(),
455 pref_service(),
456 new net::TestURLRequestContextGetter(
457 message_loop()->message_loop_proxy()));
458 SimulateTokenAvailable("alpha");
459 ReturnOAuthUrlFetchSuccess("alpha");
460 SimulateTokenAvailable("beta");
461 ReturnOAuthUrlFetchSuccess("beta");
462 tracker.Shutdown();
463 }
464
465 // Create a new tracker and make sure it loads the accounts corectly from
466 // persistence.
467 {
468 AccountTrackerService tracker;
469 tracker.AddObserver(observer());
470 tracker.Initialize(token_service(),
471 pref_service(),
472 new net::TestURLRequestContextGetter(
473 message_loop()->message_loop_proxy()));
474 ASSERT_TRUE(observer()->CheckEvents(TrackingEvent(UPDATED, "alpha"),
475 TrackingEvent(UPDATED, "beta")));
476
477 std::vector<AccountTrackerService::AccountInfo> infos =
478 tracker.GetAccounts();
479 ASSERT_EQ(2u, infos.size());
480 EXPECT_EQ(AccountIdToGaiaId("alpha"), infos[0].gaia);
481 EXPECT_EQ(AccountIdToEmail("alpha"), infos[0].email);
482 EXPECT_EQ("beta", infos[1].account_id);
483 EXPECT_EQ(AccountIdToGaiaId("beta"), infos[1].gaia);
484 EXPECT_EQ(AccountIdToEmail("beta"), infos[1].email);
485
486 // Remove account.
487 SimulateTokenRevoked("alpha");
488 tracker.RemoveObserver(observer());
489 tracker.Shutdown();
490 }
491
492 // Create a new tracker and make sure it loads the single account from
493 // persistence.
494 {
495 AccountTrackerService tracker;
496 tracker.Initialize(token_service(),
497 pref_service(),
498 new net::TestURLRequestContextGetter(
499 message_loop()->message_loop_proxy()));
500
501 std::vector<AccountTrackerService::AccountInfo> infos =
502 tracker.GetAccounts();
503 ASSERT_EQ(1u, infos.size());
504 EXPECT_EQ("beta", infos[0].account_id);
505 EXPECT_EQ(AccountIdToGaiaId("beta"), infos[0].gaia);
506 EXPECT_EQ(AccountIdToEmail("beta"), infos[0].email);
507 tracker.Shutdown();
508 }
509 }
OLDNEW
« no previous file with comments | « components/signin/core/browser/account_tracker_service.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698