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