Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / components / signin / core / browser / mutable_profile_oauth2_token_service_unittest.cc
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 "components/signin/core/browser/mutable_profile_oauth2_token_service.h"
6
7 #include "base/run_loop.h"
8 #include "components/signin/core/browser/profile_oauth2_token_service.h"
9 #include "components/signin/core/browser/signin_error_controller.h"
10 #include "components/signin/core/browser/test_signin_client.h"
11 #include "components/signin/core/browser/webdata/token_web_data.h"
12 #include "google_apis/gaia/gaia_constants.h"
13 #include "google_apis/gaia/gaia_urls.h"
14 #include "google_apis/gaia/oauth2_token_service_test_util.h"
15 #include "net/http/http_status_code.h"
16 #include "net/url_request/test_url_fetcher_factory.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 #if defined(OS_MACOSX)
20 #include "components/os_crypt/os_crypt.h"
21 #endif
22
23 // Defining constant here to handle backward compatiblity tests, but this
24 // constant is no longer used in current versions of chrome.
25 static const char kLSOService[] = "lso";
26 static const char kEmail[] = "user@gmail.com";
27
28 class MutableProfileOAuth2TokenServiceTest
29     : public testing::Test,
30       public OAuth2TokenService::Observer {
31  public:
32   MutableProfileOAuth2TokenServiceTest()
33       : factory_(NULL),
34         token_available_count_(0),
35         token_revoked_count_(0),
36         tokens_loaded_count_(0),
37         start_batch_changes_(0),
38         end_batch_changes_(0) {}
39
40   virtual void SetUp() OVERRIDE {
41 #if defined(OS_MACOSX)
42     OSCrypt::UseMockKeychain(true);
43 #endif
44
45     factory_.SetFakeResponse(GaiaUrls::GetInstance()->oauth2_revoke_url(),
46                              "",
47                              net::HTTP_OK,
48                              net::URLRequestStatus::SUCCESS);
49     oauth2_service_.Initialize(&client_);
50     // Make sure PO2TS has a chance to load itself before continuing.
51     base::RunLoop().RunUntilIdle();
52     oauth2_service_.AddObserver(this);
53   }
54
55   virtual void TearDown() OVERRIDE {
56     oauth2_service_.RemoveObserver(this);
57     oauth2_service_.Shutdown();
58   }
59
60   void AddAuthTokenManually(const std::string& service,
61                             const std::string& value) {
62     scoped_refptr<TokenWebData> token_web_data = client_.GetDatabase();
63     if (token_web_data.get())
64       token_web_data->SetTokenForService(service, value);
65   }
66
67   // OAuth2TokenService::Observer implementation.
68   virtual void OnRefreshTokenAvailable(const std::string& account_id) OVERRIDE {
69     ++token_available_count_;
70   }
71   virtual void OnRefreshTokenRevoked(const std::string& account_id) OVERRIDE {
72     ++token_revoked_count_;
73   }
74   virtual void OnRefreshTokensLoaded() OVERRIDE { ++tokens_loaded_count_; }
75
76   virtual void OnStartBatchChanges() OVERRIDE {
77     ++start_batch_changes_;
78   }
79
80   virtual void OnEndBatchChanges() OVERRIDE {
81     ++end_batch_changes_;
82   }
83
84   void ResetObserverCounts() {
85     token_available_count_ = 0;
86     token_revoked_count_ = 0;
87     tokens_loaded_count_ = 0;
88     start_batch_changes_ = 0;
89     end_batch_changes_ = 0;
90   }
91
92   void ExpectNoNotifications() {
93     EXPECT_EQ(0, token_available_count_);
94     EXPECT_EQ(0, token_revoked_count_);
95     EXPECT_EQ(0, tokens_loaded_count_);
96     ResetObserverCounts();
97   }
98
99   void ExpectOneTokenAvailableNotification() {
100     EXPECT_EQ(1, token_available_count_);
101     EXPECT_EQ(0, token_revoked_count_);
102     EXPECT_EQ(0, tokens_loaded_count_);
103     ResetObserverCounts();
104   }
105
106   void ExpectOneTokenRevokedNotification() {
107     EXPECT_EQ(0, token_available_count_);
108     EXPECT_EQ(1, token_revoked_count_);
109     EXPECT_EQ(0, tokens_loaded_count_);
110     ResetObserverCounts();
111   }
112
113   void ExpectOneTokensLoadedNotification() {
114     EXPECT_EQ(0, token_available_count_);
115     EXPECT_EQ(0, token_revoked_count_);
116     EXPECT_EQ(1, tokens_loaded_count_);
117     ResetObserverCounts();
118   }
119
120  protected:
121   base::MessageLoop message_loop_;
122   net::FakeURLFetcherFactory factory_;
123   TestSigninClient client_;
124   MutableProfileOAuth2TokenService oauth2_service_;
125   TestingOAuth2TokenServiceConsumer consumer_;
126   int token_available_count_;
127   int token_revoked_count_;
128   int tokens_loaded_count_;
129   int start_batch_changes_;
130   int end_batch_changes_;
131 };
132
133 TEST_F(MutableProfileOAuth2TokenServiceTest, PersistenceDBUpgrade) {
134   std::string main_account_id(kEmail);
135   std::string main_refresh_token("old_refresh_token");
136
137   // Populate DB with legacy tokens.
138   AddAuthTokenManually(GaiaConstants::kSyncService, "syncServiceToken");
139   AddAuthTokenManually(kLSOService, "lsoToken");
140   AddAuthTokenManually(GaiaConstants::kGaiaOAuth2LoginRefreshToken,
141                        main_refresh_token);
142
143   // Force LoadCredentials.
144   oauth2_service_.LoadCredentials(main_account_id);
145   base::RunLoop().RunUntilIdle();
146
147   // Legacy tokens get discarded, but the old refresh token is kept.
148   EXPECT_EQ(1, tokens_loaded_count_);
149   EXPECT_EQ(1, token_available_count_);
150   EXPECT_EQ(1, start_batch_changes_);
151   EXPECT_EQ(1, end_batch_changes_);
152   EXPECT_TRUE(oauth2_service_.RefreshTokenIsAvailable(main_account_id));
153   EXPECT_EQ(1U, oauth2_service_.refresh_tokens().size());
154   EXPECT_EQ(main_refresh_token,
155             oauth2_service_.refresh_tokens()[main_account_id]->refresh_token());
156
157   // Add an old legacy token to the DB, to ensure it will not overwrite existing
158   // credentials for main account.
159   AddAuthTokenManually(GaiaConstants::kGaiaOAuth2LoginRefreshToken,
160                        "secondOldRefreshToken");
161   // Add some other legacy token. (Expected to get discarded).
162   AddAuthTokenManually(kLSOService, "lsoToken");
163   // Also add a token using PO2TS.UpdateCredentials and make sure upgrade does
164   // not wipe it.
165   std::string other_account_id("other_account_id");
166   std::string other_refresh_token("other_refresh_token");
167   oauth2_service_.UpdateCredentials(other_account_id, other_refresh_token);
168   ResetObserverCounts();
169
170   // Force LoadCredentials.
171   oauth2_service_.LoadCredentials(main_account_id);
172   base::RunLoop().RunUntilIdle();
173
174   // Again legacy tokens get discarded, but since the main porfile account
175   // token is present it is not overwritten.
176   EXPECT_EQ(2, token_available_count_);
177   EXPECT_EQ(1, tokens_loaded_count_);
178   EXPECT_EQ(1, start_batch_changes_);
179   EXPECT_EQ(1, end_batch_changes_);
180   EXPECT_TRUE(oauth2_service_.RefreshTokenIsAvailable(main_account_id));
181   // TODO(fgorski): cover both using RefreshTokenIsAvailable() and then get the
182   // tokens using GetRefreshToken()
183   EXPECT_EQ(2U, oauth2_service_.refresh_tokens().size());
184   EXPECT_EQ(main_refresh_token,
185             oauth2_service_.refresh_tokens()[main_account_id]->refresh_token());
186   EXPECT_EQ(
187       other_refresh_token,
188       oauth2_service_.refresh_tokens()[other_account_id]->refresh_token());
189
190   oauth2_service_.RevokeAllCredentials();
191   EXPECT_EQ(2, start_batch_changes_);
192   EXPECT_EQ(2, end_batch_changes_);
193 }
194
195 TEST_F(MutableProfileOAuth2TokenServiceTest, PersistenceRevokeCredentials) {
196   std::string account_id_1 = "account_id_1";
197   std::string refresh_token_1 = "refresh_token_1";
198   std::string account_id_2 = "account_id_2";
199   std::string refresh_token_2 = "refresh_token_2";
200
201   // TODO(fgorski): Enable below when implemented:
202   // EXPECT_FALSE(oauth2_servive_->RefreshTokenIsAvailable(account_id_1));
203   // EXPECT_FALSE(oauth2_servive_->RefreshTokenIsAvailable(account_id_2));
204
205   oauth2_service_.UpdateCredentials(account_id_1, refresh_token_1);
206   oauth2_service_.UpdateCredentials(account_id_2, refresh_token_2);
207   EXPECT_EQ(2, start_batch_changes_);
208   EXPECT_EQ(2, end_batch_changes_);
209
210   // TODO(fgorski): Enable below when implemented:
211   // EXPECT_TRUE(oauth2_servive_->RefreshTokenIsAvailable(account_id_1));
212   // EXPECT_TRUE(oauth2_service_.RefreshTokenIsAvailable(account_id_2));
213
214   ResetObserverCounts();
215   oauth2_service_.RevokeCredentials(account_id_1);
216   EXPECT_EQ(1, start_batch_changes_);
217   EXPECT_EQ(1, end_batch_changes_);
218   ExpectOneTokenRevokedNotification();
219
220   // TODO(fgorski): Enable below when implemented:
221   // EXPECT_FALSE(oauth2_servive_->RefreshTokenIsAvailable(account_id_1));
222   // EXPECT_TRUE(oauth2_service_.RefreshTokenIsAvailable(account_id_2));
223
224   oauth2_service_.RevokeAllCredentials();
225   EXPECT_EQ(0, token_available_count_);
226   EXPECT_EQ(1, token_revoked_count_);
227   EXPECT_EQ(0, tokens_loaded_count_);
228   EXPECT_EQ(1, start_batch_changes_);
229   EXPECT_EQ(1, end_batch_changes_);
230   ResetObserverCounts();
231 }
232
233 TEST_F(MutableProfileOAuth2TokenServiceTest, PersistenceLoadCredentials) {
234   // Ensure DB is clean.
235   oauth2_service_.RevokeAllCredentials();
236   ResetObserverCounts();
237   // Perform a load from an empty DB.
238   oauth2_service_.LoadCredentials("account_id");
239   base::RunLoop().RunUntilIdle();
240   EXPECT_EQ(1, start_batch_changes_);
241   EXPECT_EQ(1, end_batch_changes_);
242   ExpectOneTokensLoadedNotification();
243   // LoadCredentials() guarantees that the account given to it as argument
244   // is in the refresh_token map.
245   EXPECT_EQ(1U, oauth2_service_.refresh_tokens().size());
246   EXPECT_TRUE(
247       oauth2_service_.refresh_tokens()["account_id"]->refresh_token().empty());
248   // Setup a DB with tokens that don't require upgrade and clear memory.
249   oauth2_service_.UpdateCredentials("account_id", "refresh_token");
250   oauth2_service_.UpdateCredentials("account_id2", "refresh_token2");
251   oauth2_service_.refresh_tokens().clear();
252   EXPECT_EQ(2, start_batch_changes_);
253   EXPECT_EQ(2, end_batch_changes_);
254   ResetObserverCounts();
255
256   oauth2_service_.LoadCredentials("account_id");
257   base::RunLoop().RunUntilIdle();
258   EXPECT_EQ(2, token_available_count_);
259   EXPECT_EQ(0, token_revoked_count_);
260   EXPECT_EQ(1, tokens_loaded_count_);
261   EXPECT_EQ(1, start_batch_changes_);
262   EXPECT_EQ(1, end_batch_changes_);
263   ResetObserverCounts();
264
265   // TODO(fgorski): Enable below when implemented:
266   // EXPECT_TRUE(oauth2_servive_->RefreshTokenIsAvailable("account_id"));
267   // EXPECT_TRUE(oauth2_service_.RefreshTokenIsAvailable("account_id2"));
268
269   oauth2_service_.RevokeAllCredentials();
270   EXPECT_EQ(0, token_available_count_);
271   EXPECT_EQ(2, token_revoked_count_);
272   EXPECT_EQ(0, tokens_loaded_count_);
273   EXPECT_EQ(1, start_batch_changes_);
274   EXPECT_EQ(1, end_batch_changes_);
275   ResetObserverCounts();
276 }
277
278 TEST_F(MutableProfileOAuth2TokenServiceTest, PersistanceNotifications) {
279   EXPECT_EQ(0, oauth2_service_.cache_size_for_testing());
280   oauth2_service_.UpdateCredentials("account_id", "refresh_token");
281   ExpectOneTokenAvailableNotification();
282
283   oauth2_service_.UpdateCredentials("account_id", "refresh_token");
284   ExpectNoNotifications();
285
286   oauth2_service_.UpdateCredentials("account_id", "refresh_token2");
287   ExpectOneTokenAvailableNotification();
288
289   oauth2_service_.RevokeCredentials("account_id");
290   ExpectOneTokenRevokedNotification();
291
292   oauth2_service_.UpdateCredentials("account_id", "refresh_token2");
293   ExpectOneTokenAvailableNotification();
294
295   oauth2_service_.RevokeAllCredentials();
296   ResetObserverCounts();
297 }
298
299 TEST_F(MutableProfileOAuth2TokenServiceTest, GetAccounts) {
300   EXPECT_TRUE(oauth2_service_.GetAccounts().empty());
301   oauth2_service_.UpdateCredentials("account_id1", "refresh_token1");
302   oauth2_service_.UpdateCredentials("account_id2", "refresh_token2");
303   std::vector<std::string> accounts = oauth2_service_.GetAccounts();
304   EXPECT_EQ(2u, accounts.size());
305   EXPECT_EQ(1, count(accounts.begin(), accounts.end(), "account_id1"));
306   EXPECT_EQ(1, count(accounts.begin(), accounts.end(), "account_id2"));
307   oauth2_service_.RevokeCredentials("account_id2");
308   accounts = oauth2_service_.GetAccounts();
309   EXPECT_EQ(1u, oauth2_service_.GetAccounts().size());
310   EXPECT_EQ(1, count(accounts.begin(), accounts.end(), "account_id1"));
311 }
312
313 TEST_F(MutableProfileOAuth2TokenServiceTest, TokenServiceUpdateClearsCache) {
314   EXPECT_EQ(0, oauth2_service_.cache_size_for_testing());
315   std::set<std::string> scope_list;
316   scope_list.insert("scope");
317   oauth2_service_.UpdateCredentials(kEmail, "refreshToken");
318   ExpectOneTokenAvailableNotification();
319   factory_.SetFakeResponse(GaiaUrls::GetInstance()->oauth2_token_url(),
320                            GetValidTokenResponse("token", 3600),
321                            net::HTTP_OK,
322                            net::URLRequestStatus::SUCCESS);
323
324   scoped_ptr<OAuth2TokenService::Request> request(
325       oauth2_service_.StartRequest(kEmail, scope_list, &consumer_));
326   base::RunLoop().RunUntilIdle();
327   EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
328   EXPECT_EQ(0, consumer_.number_of_errors_);
329   EXPECT_EQ("token", consumer_.last_token_);
330   EXPECT_EQ(1, oauth2_service_.cache_size_for_testing());
331
332   // Signs out and signs in
333   oauth2_service_.RevokeCredentials(kEmail);
334   ExpectOneTokenRevokedNotification();
335
336   EXPECT_EQ(0, oauth2_service_.cache_size_for_testing());
337   oauth2_service_.UpdateCredentials(kEmail, "refreshToken");
338   ExpectOneTokenAvailableNotification();
339   factory_.SetFakeResponse(GaiaUrls::GetInstance()->oauth2_token_url(),
340                            GetValidTokenResponse("another token", 3600),
341                            net::HTTP_OK,
342                            net::URLRequestStatus::SUCCESS);
343
344   request = oauth2_service_.StartRequest(kEmail, scope_list, &consumer_);
345   base::RunLoop().RunUntilIdle();
346   EXPECT_EQ(2, consumer_.number_of_successful_tokens_);
347   EXPECT_EQ(0, consumer_.number_of_errors_);
348   EXPECT_EQ("another token", consumer_.last_token_);
349   EXPECT_EQ(1, oauth2_service_.cache_size_for_testing());
350 }
351
352 TEST_F(MutableProfileOAuth2TokenServiceTest, FetchTransientError) {
353   factory_.SetFakeResponse(GaiaUrls::GetInstance()->oauth2_token_url(),
354                            "",
355                            net::HTTP_FORBIDDEN,
356                            net::URLRequestStatus::FAILED);
357
358   EXPECT_EQ(0, oauth2_service_.cache_size_for_testing());
359   std::set<std::string> scope_list;
360   scope_list.insert("scope");
361   oauth2_service_.set_max_authorization_token_fetch_retries_for_testing(0);
362   oauth2_service_.UpdateCredentials(kEmail, "refreshToken");
363   ExpectOneTokenAvailableNotification();
364
365   scoped_ptr<OAuth2TokenService::Request> request(
366       oauth2_service_.StartRequest(kEmail, scope_list, &consumer_));
367   base::RunLoop().RunUntilIdle();
368   EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(),
369             oauth2_service_.signin_error_controller()->auth_error());
370 }