OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 // A complete set of unit tests for OAuth2MintTokenFlow. | |
6 | |
7 #include <string> | |
8 #include <vector> | |
9 | |
10 #include "base/memory/scoped_ptr.h" | |
11 #include "base/time.h" | |
12 #include "chrome/common/net/gaia/gaia_urls.h" | |
13 #include "chrome/common/net/gaia/google_service_auth_error.h" | |
14 #include "chrome/common/net/gaia/oauth2_access_token_consumer.h" | |
15 #include "chrome/common/net/gaia/oauth2_access_token_fetcher.h" | |
16 #include "chrome/common/net/gaia/oauth2_api_call_flow.h" | |
17 #include "chrome/test/base/testing_profile.h" | |
18 #include "net/http/http_request_headers.h" | |
19 #include "net/http/http_status_code.h" | |
20 #include "net/url_request/test_url_fetcher_factory.h" | |
21 #include "net/url_request/url_fetcher.h" | |
22 #include "net/url_request/url_fetcher_delegate.h" | |
23 #include "net/url_request/url_fetcher_factory.h" | |
24 #include "net/url_request/url_request.h" | |
25 #include "net/url_request/url_request_status.h" | |
26 #include "testing/gmock/include/gmock/gmock.h" | |
27 #include "testing/gtest/include/gtest/gtest.h" | |
28 | |
29 using net::HttpRequestHeaders; | |
30 using net::ScopedURLFetcherFactory; | |
31 using net::TestURLFetcher; | |
32 using net::URLFetcher; | |
33 using net::URLFetcherDelegate; | |
34 using net::URLFetcherFactory; | |
35 using net::URLRequestStatus; | |
36 using testing::_; | |
37 using testing::Return; | |
38 | |
39 namespace { | |
40 | |
41 static std::string CreateBody() { | |
42 return "some body"; | |
43 } | |
44 | |
45 static GURL CreateApiUrl() { | |
46 return GURL("https://www.googleapis.com/someapi"); | |
47 } | |
48 | |
49 static std::vector<std::string> CreateTestScopes() { | |
50 std::vector<std::string> scopes; | |
51 scopes.push_back("scope1"); | |
52 scopes.push_back("scope2"); | |
53 return scopes; | |
54 } | |
55 | |
56 class MockUrlFetcherFactory : public ScopedURLFetcherFactory, | |
57 public URLFetcherFactory { | |
58 public: | |
59 MockUrlFetcherFactory() | |
60 : ScopedURLFetcherFactory(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | |
61 } | |
62 virtual ~MockUrlFetcherFactory() {} | |
63 | |
64 MOCK_METHOD4( | |
65 CreateURLFetcher, | |
66 URLFetcher* (int id, | |
67 const GURL& url, | |
68 URLFetcher::RequestType request_type, | |
69 URLFetcherDelegate* d)); | |
70 }; | |
71 | |
72 class MockAccessTokenFetcher : public OAuth2AccessTokenFetcher { | |
73 public: | |
74 MockAccessTokenFetcher(OAuth2AccessTokenConsumer* consumer, | |
75 net::URLRequestContextGetter* getter) | |
76 : OAuth2AccessTokenFetcher(consumer, getter) {} | |
77 ~MockAccessTokenFetcher() {} | |
78 | |
79 MOCK_METHOD4(Start, | |
80 void (const std::string& client_id, | |
81 const std::string& client_secret, | |
82 const std::string& refresh_token, | |
83 const std::vector<std::string>& scopes)); | |
84 }; | |
85 | |
86 class MockApiCallFlow : public OAuth2ApiCallFlow { | |
87 public: | |
88 MockApiCallFlow(net::URLRequestContextGetter* context, | |
89 const std::string& refresh_token, | |
90 const std::string& access_token, | |
91 const std::vector<std::string>& scopes) | |
92 : OAuth2ApiCallFlow(context, refresh_token, access_token, scopes) {} | |
93 ~MockApiCallFlow() {} | |
94 | |
95 MOCK_METHOD0(CreateApiCallUrl, GURL ()); | |
96 MOCK_METHOD0(CreateApiCallBody, std::string ()); | |
97 MOCK_METHOD1(ProcessApiCallSuccess, | |
98 void (const URLFetcher* source)); | |
99 MOCK_METHOD1(ProcessApiCallFailure, | |
100 void (const URLFetcher* source)); | |
101 MOCK_METHOD1(ProcessNewAccessToken, | |
102 void (const std::string& access_token)); | |
103 MOCK_METHOD1(ProcessMintAccessTokenFailure, | |
104 void (const GoogleServiceAuthError& error)); | |
105 MOCK_METHOD0(CreateAccessTokenFetcher, OAuth2AccessTokenFetcher* ()); | |
106 }; | |
107 | |
108 } // namespace | |
109 | |
110 class OAuth2ApiCallFlowTest : public testing::Test { | |
111 public: | |
112 OAuth2ApiCallFlowTest() {} | |
113 virtual ~OAuth2ApiCallFlowTest() {} | |
114 | |
115 protected: | |
116 void SetupAccessTokenFetcher( | |
117 const std::string& rt, const std::vector<std::string>& scopes) { | |
118 EXPECT_CALL(*access_token_fetcher_, | |
119 Start(GaiaUrls::GetInstance()->oauth2_chrome_client_id(), | |
120 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(), | |
121 rt, scopes)) | |
122 .Times(1); | |
123 EXPECT_CALL(*flow_, CreateAccessTokenFetcher()) | |
124 .WillOnce(Return(access_token_fetcher_.release())); | |
125 } | |
126 | |
127 TestURLFetcher* CreateURLFetcher( | |
128 const GURL& url, bool fetch_succeeds, | |
129 int response_code, const std::string& body) { | |
130 TestURLFetcher* url_fetcher = new TestURLFetcher(0, url, flow_.get()); | |
131 URLRequestStatus::Status status = | |
132 fetch_succeeds ? URLRequestStatus::SUCCESS : URLRequestStatus::FAILED; | |
133 url_fetcher->set_status(URLRequestStatus(status, 0)); | |
134 | |
135 if (response_code != 0) | |
136 url_fetcher->set_response_code(response_code); | |
137 | |
138 if (!body.empty()) | |
139 url_fetcher->SetResponseString(body); | |
140 | |
141 return url_fetcher; | |
142 } | |
143 | |
144 void CreateFlow(const std::string& refresh_token, | |
145 const std::string& access_token, | |
146 const std::vector<std::string>& scopes) { | |
147 flow_.reset(new MockApiCallFlow( | |
148 profile_.GetRequestContext(), | |
149 refresh_token, | |
150 access_token, | |
151 scopes)); | |
152 access_token_fetcher_.reset(new MockAccessTokenFetcher( | |
153 flow_.get(), profile_.GetRequestContext())); | |
154 } | |
155 | |
156 TestURLFetcher* SetupApiCall(bool succeeds, net::HttpStatusCode status) { | |
157 std::string body(CreateBody()); | |
158 GURL url(CreateApiUrl()); | |
159 EXPECT_CALL(*flow_, CreateApiCallBody()).WillOnce(Return(body)); | |
160 EXPECT_CALL(*flow_, CreateApiCallUrl()).WillOnce(Return(url)); | |
161 TestURLFetcher* url_fetcher = CreateURLFetcher( | |
162 url, succeeds, status, ""); | |
163 EXPECT_CALL(factory_, CreateURLFetcher(_, url, _, _)) | |
164 .WillOnce(Return(url_fetcher)); | |
165 return url_fetcher; | |
166 } | |
167 | |
168 MockUrlFetcherFactory factory_; | |
169 scoped_ptr<MockApiCallFlow> flow_; | |
170 scoped_ptr<MockAccessTokenFetcher> access_token_fetcher_; | |
171 TestingProfile profile_; | |
172 }; | |
173 | |
174 TEST_F(OAuth2ApiCallFlowTest, FirstApiCallSucceeds) { | |
175 std::string rt = "refresh_token"; | |
176 std::string at = "access_token"; | |
177 std::vector<std::string> scopes(CreateTestScopes()); | |
178 | |
179 CreateFlow(rt, at, scopes); | |
180 TestURLFetcher* url_fetcher = SetupApiCall(true, net::HTTP_OK); | |
181 EXPECT_CALL(*flow_, ProcessApiCallSuccess(url_fetcher)); | |
182 flow_->Start(); | |
183 flow_->OnURLFetchComplete(url_fetcher); | |
184 } | |
185 | |
186 TEST_F(OAuth2ApiCallFlowTest, SecondApiCallSucceeds) { | |
187 std::string rt = "refresh_token"; | |
188 std::string at = "access_token"; | |
189 std::vector<std::string> scopes(CreateTestScopes()); | |
190 | |
191 CreateFlow(rt, at, scopes); | |
192 TestURLFetcher* url_fetcher1 = SetupApiCall(true, net::HTTP_UNAUTHORIZED); | |
193 flow_->Start(); | |
194 SetupAccessTokenFetcher(rt, scopes); | |
195 flow_->OnURLFetchComplete(url_fetcher1); | |
196 TestURLFetcher* url_fetcher2 = SetupApiCall(true, net::HTTP_OK); | |
197 EXPECT_CALL(*flow_, ProcessApiCallSuccess(url_fetcher2)); | |
198 flow_->OnGetTokenSuccess( | |
199 at, | |
200 base::Time::Now() + base::TimeDelta::FromMinutes(3600)); | |
201 flow_->OnURLFetchComplete(url_fetcher2); | |
202 } | |
203 | |
204 TEST_F(OAuth2ApiCallFlowTest, SecondApiCallFails) { | |
205 std::string rt = "refresh_token"; | |
206 std::string at = "access_token"; | |
207 std::vector<std::string> scopes(CreateTestScopes()); | |
208 | |
209 CreateFlow(rt, at, scopes); | |
210 TestURLFetcher* url_fetcher1 = SetupApiCall(true, net::HTTP_UNAUTHORIZED); | |
211 flow_->Start(); | |
212 SetupAccessTokenFetcher(rt, scopes); | |
213 flow_->OnURLFetchComplete(url_fetcher1); | |
214 TestURLFetcher* url_fetcher2 = SetupApiCall(false, net::HTTP_UNAUTHORIZED); | |
215 EXPECT_CALL(*flow_, ProcessApiCallFailure(url_fetcher2)); | |
216 flow_->OnGetTokenSuccess( | |
217 at, | |
218 base::Time::Now() + base::TimeDelta::FromMinutes(3600)); | |
219 flow_->OnURLFetchComplete(url_fetcher2); | |
220 } | |
221 | |
222 TEST_F(OAuth2ApiCallFlowTest, NewTokenGenerationFails) { | |
223 std::string rt = "refresh_token"; | |
224 std::string at = "access_token"; | |
225 std::vector<std::string> scopes(CreateTestScopes()); | |
226 | |
227 CreateFlow(rt, at, scopes); | |
228 TestURLFetcher* url_fetcher = SetupApiCall(true, net::HTTP_UNAUTHORIZED); | |
229 flow_->Start(); | |
230 SetupAccessTokenFetcher(rt, scopes); | |
231 flow_->OnURLFetchComplete(url_fetcher); | |
232 GoogleServiceAuthError error( | |
233 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); | |
234 EXPECT_CALL(*flow_, ProcessMintAccessTokenFailure(error)); | |
235 flow_->OnGetTokenFailure(error); | |
236 } | |
237 | |
238 TEST_F(OAuth2ApiCallFlowTest, EmptyAccessTokenFirstApiCallSucceeds) { | |
239 std::string rt = "refresh_token"; | |
240 std::string at = "access_token"; | |
241 std::vector<std::string> scopes(CreateTestScopes()); | |
242 | |
243 CreateFlow(rt, "", scopes); | |
244 SetupAccessTokenFetcher(rt, scopes); | |
245 TestURLFetcher* url_fetcher = SetupApiCall(true, net::HTTP_OK); | |
246 EXPECT_CALL(*flow_, ProcessApiCallSuccess(url_fetcher)); | |
247 flow_->Start(); | |
248 flow_->OnGetTokenSuccess( | |
249 at, | |
250 base::Time::Now() + base::TimeDelta::FromMinutes(3600)); | |
251 flow_->OnURLFetchComplete(url_fetcher); | |
252 } | |
253 | |
254 TEST_F(OAuth2ApiCallFlowTest, EmptyAccessTokenApiCallFails) { | |
255 std::string rt = "refresh_token"; | |
256 std::string at = "access_token"; | |
257 std::vector<std::string> scopes(CreateTestScopes()); | |
258 | |
259 CreateFlow(rt, "", scopes); | |
260 SetupAccessTokenFetcher(rt, scopes); | |
261 TestURLFetcher* url_fetcher = SetupApiCall(false, net::HTTP_BAD_GATEWAY); | |
262 EXPECT_CALL(*flow_, ProcessApiCallFailure(url_fetcher)); | |
263 flow_->Start(); | |
264 flow_->OnGetTokenSuccess( | |
265 at, | |
266 base::Time::Now() + base::TimeDelta::FromMinutes(3600)); | |
267 flow_->OnURLFetchComplete(url_fetcher); | |
268 } | |
269 | |
270 TEST_F(OAuth2ApiCallFlowTest, EmptyAccessTokenNewTokenGenerationFails) { | |
271 std::string rt = "refresh_token"; | |
272 std::string at = "access_token"; | |
273 std::vector<std::string> scopes(CreateTestScopes()); | |
274 | |
275 CreateFlow(rt, "", scopes); | |
276 SetupAccessTokenFetcher(rt, scopes); | |
277 GoogleServiceAuthError error( | |
278 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); | |
279 EXPECT_CALL(*flow_, ProcessMintAccessTokenFailure(error)); | |
280 flow_->Start(); | |
281 flow_->OnGetTokenFailure(error); | |
282 } | |
283 | |
284 TEST_F(OAuth2ApiCallFlowTest, CreateURLFetcher) { | |
285 std::string rt = "refresh_token"; | |
286 std::string at = "access_token"; | |
287 std::vector<std::string> scopes(CreateTestScopes()); | |
288 std::string body = CreateBody(); | |
289 GURL url(CreateApiUrl()); | |
290 | |
291 CreateFlow(rt, at, scopes); | |
292 scoped_ptr<TestURLFetcher> url_fetcher(SetupApiCall(true, net::HTTP_OK)); | |
293 flow_->CreateURLFetcher(); | |
294 HttpRequestHeaders headers; | |
295 url_fetcher->GetExtraRequestHeaders(&headers); | |
296 std::string auth_header; | |
297 EXPECT_TRUE(headers.GetHeader("Authorization", &auth_header)); | |
298 EXPECT_EQ("Bearer access_token", auth_header); | |
299 EXPECT_EQ(url, url_fetcher->GetOriginalURL()); | |
300 EXPECT_EQ(body, url_fetcher->upload_data()); | |
301 } | |
OLD | NEW |