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

Side by Side Diff: chrome/browser/signin/account_service_flag_fetcher_unittest.cc

Issue 284763004: Create AccountServiceFlagFetcher which downloads an account's Gaia service flags. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Cleanup Created 6 years, 6 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 | « no previous file | chrome/browser/signin/fake_profile_oauth2_token_service.h » ('j') | 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 "components/signin/core/browser/account_service_flag_fetcher.h"
Bernhard Bauer 2014/05/28 16:32:43 This isn't really necessary. The point of this is
Marc Treib 2014/06/02 09:14:41 True. I did this for consistency, since most other
6
7 #include <string>
8 #include <vector>
9
10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/message_loop/message_loop_proxy.h"
13 #include "base/strings/string_util.h"
14 #include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
15 #include "google_apis/gaia/gaia_urls.h"
16 #include "net/url_request/test_url_fetcher_factory.h"
17 #include "net/url_request/url_request_test_util.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 const char kAccountId[] = "user@gmail.com";
22 const char kDifferentAccountId[] = "some_other_user@gmail.com";
23
24 // TODO(treib): This class should really live in components/signin/ next to the
25 // AccountServiceFlagFetcher, but it uses the FakePO2TS which lives in
26 // chrome/browser/ (because it uses the AndroidPO2TS which depends on stuff from
27 // chrome/browser/). So when the AndroidPO2TS is componentized, then this should
28 // move as well.
Bernhard Bauer 2014/05/28 16:32:43 Yeah, the whole class hierarchy is a bit weird the
29 class AccountServiceFlagFetcherTest : public testing::Test {
30 public:
31 virtual void SetUp() OVERRIDE {
32 token_service_.reset(new FakeProfileOAuth2TokenService());
33 request_context_ = new net::TestURLRequestContextGetter(
34 base::MessageLoopProxy::current());
35 url_fetcher_factory_.reset(new net::FakeURLFetcherFactory(NULL));
Andrew T Wilson (Slow) 2014/05/30 06:51:44 nit: Does this need to be dynamically allocated? C
Marc Treib 2014/06/02 09:14:41 The TestURLRequestContextGetter can't, because it
Bernhard Bauer 2014/06/02 10:25:42 (Because it's refcounted).
Marc Treib 2014/06/02 16:19:56 Huh, so it is. Yep, in that case I can move everyt
36 service_flags_.clear();
37 service_flags_.push_back("some_flag");
38 service_flags_.push_back("another_flag");
39 service_flags_.push_back("andonemore");
40 }
41
42 MOCK_METHOD2(OnFlagsFetched,
43 void(AccountServiceFlagFetcher::ResultCode result,
44 const std::vector<std::string>& flags));
45
46 protected:
47 void SetValidLoginResponse() {
48 url_fetcher_factory_->SetFakeResponse(
49 GaiaUrls::GetInstance()->oauth1_login_url(),
50 "SID=sid\nLSID=lsid\nAuth=auth\n",
51 net::HTTP_OK,
52 net::URLRequestStatus::SUCCESS);
53 }
54
55 void SetFailedLoginResponse() {
56 url_fetcher_factory_->SetFakeResponse(
57 GaiaUrls::GetInstance()->oauth1_login_url(),
58 "",
Bernhard Bauer 2014/05/28 16:32:43 Use std::string() instead of the implicit construc
Marc Treib 2014/06/02 09:14:41 Done.
59 net::HTTP_OK,
60 net::URLRequestStatus::CANCELED);
61 }
62
63 void SetValidGetUserInfoResponse() {
64 url_fetcher_factory_->SetFakeResponse(
65 GaiaUrls::GetInstance()->get_user_info_url(),
66 BuildGetUserInfoResponse(),
67 net::HTTP_OK,
68 net::URLRequestStatus::SUCCESS);
69 }
70
71 void SetInvalidGetUserInfoResponse() {
72 url_fetcher_factory_->SetFakeResponse(
73 GaiaUrls::GetInstance()->get_user_info_url(),
74 "allServicesIsMissing=true",
75 net::HTTP_OK,
76 net::URLRequestStatus::SUCCESS);
77 }
78
79 void SetFailedGetUserInfoResponse() {
80 url_fetcher_factory_->SetFakeResponse(
81 GaiaUrls::GetInstance()->get_user_info_url(),
82 "",
83 net::HTTP_OK,
84 net::URLRequestStatus::CANCELED);
85 }
86
87 std::string BuildGetUserInfoResponse() const {
88 return "allServices=" + JoinString(service_flags_, ',');
89 }
90
91 base::MessageLoop message_loop_;
92 scoped_ptr<FakeProfileOAuth2TokenService> token_service_;
93 scoped_refptr<net::TestURLRequestContextGetter> request_context_;
94 scoped_ptr<net::FakeURLFetcherFactory> url_fetcher_factory_;
95 net::ResponseCookies cookies_;
96 std::vector<std::string> service_flags_;
97 };
98
99 TEST_F(AccountServiceFlagFetcherTest, Success) {
100 token_service_->UpdateCredentials(kAccountId, "refresh_token");
101 SetValidLoginResponse();
102 SetValidGetUserInfoResponse();
103
104 AccountServiceFlagFetcher fetcher(
105 kAccountId,
106 token_service_.get(),
107 request_context_.get(),
108 base::Bind(&AccountServiceFlagFetcherTest::OnFlagsFetched,
109 base::Unretained(this)));
110
111 // Since a refresh token is already available, we should immediately get a
112 // request for an access token.
113 EXPECT_EQ(token_service_->GetPendingRequests().size(), 1U);
114
115 token_service_->IssueAllTokensForAccount(
116 kAccountId,
117 "access_token",
118 base::Time::Now() + base::TimeDelta::FromHours(1));
119
120 EXPECT_CALL(*this, OnFlagsFetched(AccountServiceFlagFetcher::SUCCESS,
121 service_flags_));
122 message_loop_.RunUntilIdle();
Bernhard Bauer 2014/05/28 16:32:43 Running a message loop directly is somewhat discou
Marc Treib 2014/06/02 09:14:41 Okay, I'm using RunLoop::RunUntilIdle now. I don't
123 }
124
125 TEST_F(AccountServiceFlagFetcherTest, SuccessAfterWaitingForRefreshToken) {
126 SetValidLoginResponse();
127 SetValidGetUserInfoResponse();
128
129 AccountServiceFlagFetcher fetcher(
130 kAccountId,
131 token_service_.get(),
132 request_context_.get(),
133 base::Bind(&AccountServiceFlagFetcherTest::OnFlagsFetched,
134 base::Unretained(this)));
135
136 // Since there is no refresh token yet, we should not get a request for an
137 // access token at this point.
138 EXPECT_EQ(token_service_->GetPendingRequests().size(), 0U);
139
140 token_service_->UpdateCredentials(kAccountId, "refresh_token");
141
142 // Now there is a refresh token and we should have got a request for an
143 // access token.
144 EXPECT_EQ(token_service_->GetPendingRequests().size(), 1U);
145
146 token_service_->IssueAllTokensForAccount(
147 kAccountId,
148 "access_token",
149 base::Time::Now() + base::TimeDelta::FromHours(1));
150
151 EXPECT_CALL(*this, OnFlagsFetched(AccountServiceFlagFetcher::SUCCESS,
152 service_flags_));
153 message_loop_.RunUntilIdle();
154 }
155
156 TEST_F(AccountServiceFlagFetcherTest, NoRefreshToken) {
157 AccountServiceFlagFetcher fetcher(
158 kAccountId,
159 token_service_.get(),
160 request_context_.get(),
161 base::Bind(&AccountServiceFlagFetcherTest::OnFlagsFetched,
162 base::Unretained(this)));
163
164 token_service_->UpdateCredentials(kDifferentAccountId, "refresh_token");
165
166 // Credentials for a different user should be ignored, i.e. not result in a
167 // request for an access token.
168 EXPECT_EQ(token_service_->GetPendingRequests().size(), 0U);
Bernhard Bauer 2014/05/28 16:32:43 Put the expected value first, for nicer error mess
Marc Treib 2014/06/02 09:14:41 Done.
169
170 // After all refresh tokens have been loaded, there is still no token for our
171 // user, so we expect a token error.
172 EXPECT_CALL(*this, OnFlagsFetched(AccountServiceFlagFetcher::TOKEN_ERROR,
173 std::vector<std::string>()));
174 token_service_->IssueAllRefreshTokensLoaded();
175 }
176
177 TEST_F(AccountServiceFlagFetcherTest, GetTokenFailure) {
178 token_service_->UpdateCredentials(kAccountId, "refresh_token");
179
180 AccountServiceFlagFetcher fetcher(
181 kAccountId,
182 token_service_.get(),
183 request_context_.get(),
184 base::Bind(&AccountServiceFlagFetcherTest::OnFlagsFetched,
185 base::Unretained(this)));
186
187 // On failure to get an access token we expect a token error.
188 EXPECT_CALL(*this, OnFlagsFetched(AccountServiceFlagFetcher::TOKEN_ERROR,
189 std::vector<std::string>()));
190 token_service_->IssueErrorForAllPendingRequestsForAccount(
191 kAccountId,
192 GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
193 }
194
195 TEST_F(AccountServiceFlagFetcherTest, ClientLoginFailure) {
196 token_service_->UpdateCredentials(kAccountId, "refresh_token");
197 SetFailedLoginResponse();
198
199 AccountServiceFlagFetcher fetcher(
200 kAccountId,
201 token_service_.get(),
202 request_context_.get(),
203 base::Bind(&AccountServiceFlagFetcherTest::OnFlagsFetched,
204 base::Unretained(this)));
205
206 token_service_->IssueAllTokensForAccount(
207 kAccountId,
208 "access_token",
209 base::Time::Now() + base::TimeDelta::FromHours(1));
210
211 // Login failure should result in a service error.
212 EXPECT_CALL(*this, OnFlagsFetched(AccountServiceFlagFetcher::SERVICE_ERROR,
213 std::vector<std::string>()));
214 message_loop_.RunUntilIdle();
215 }
216
217 TEST_F(AccountServiceFlagFetcherTest, GetUserInfoInvalidResponse) {
218 token_service_->UpdateCredentials(kAccountId, "refresh_token");
219 SetValidLoginResponse();
220 SetInvalidGetUserInfoResponse();
221
222 AccountServiceFlagFetcher fetcher(
223 kAccountId,
224 token_service_.get(),
225 request_context_.get(),
226 base::Bind(&AccountServiceFlagFetcherTest::OnFlagsFetched,
227 base::Unretained(this)));
228
229 token_service_->IssueAllTokensForAccount(
230 kAccountId,
231 "access_token",
232 base::Time::Now() + base::TimeDelta::FromHours(1));
233
234 // Invalid response data from GetUserInfo should result in a service error.
235 EXPECT_CALL(*this, OnFlagsFetched(AccountServiceFlagFetcher::SERVICE_ERROR,
236 std::vector<std::string>()));
237 message_loop_.RunUntilIdle();
238 }
239
240 TEST_F(AccountServiceFlagFetcherTest, GetUserInfoFailure) {
241 token_service_->UpdateCredentials(kAccountId, "refresh_token");
242 SetValidLoginResponse();
243 SetFailedGetUserInfoResponse();
244
245 AccountServiceFlagFetcher fetcher(
246 kAccountId,
247 token_service_.get(),
248 request_context_.get(),
249 base::Bind(&AccountServiceFlagFetcherTest::OnFlagsFetched,
250 base::Unretained(this)));
251
252 token_service_->IssueAllTokensForAccount(
253 kAccountId,
254 "access_token",
255 base::Time::Now() + base::TimeDelta::FromHours(1));
256
257 // Failed GetUserInfo call should result in a service error.
258 EXPECT_CALL(*this, OnFlagsFetched(AccountServiceFlagFetcher::SERVICE_ERROR,
259 std::vector<std::string>()));
260 message_loop_.RunUntilIdle();
261 }
Bernhard Bauer 2014/05/28 16:32:43 Would it also make sense to add a test that checks
Marc Treib 2014/06/02 09:14:41 I've added a test for that. Is there more to it th
Bernhard Bauer 2014/06/02 10:25:42 Yes and no. *In principle* you can do it with .Tim
Marc Treib 2014/06/02 16:19:56 As discussed offline: The URLFetcher is now stubbe
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/signin/fake_profile_oauth2_token_service.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698