Improve the logic for hiding the multi-window resize handle
[chromium-blink-merge.git] / google_apis / gaia / oauth2_mint_token_flow_unittest.cc
blobc60ad31c948f1b26b5d8de472499161f02c1924c
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.
7 #include <string>
8 #include <vector>
10 #include "base/json/json_reader.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/values.h"
14 #include "google_apis/gaia/google_service_auth_error.h"
15 #include "google_apis/gaia/oauth2_mint_token_flow.h"
16 #include "net/url_request/test_url_fetcher_factory.h"
17 #include "net/url_request/url_request_status.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
21 using net::TestURLFetcher;
22 using net::URLFetcher;
23 using net::URLRequestStatus;
24 using testing::_;
25 using testing::StrictMock;
27 namespace {
29 static const char kValidTokenResponse[] =
30 "{"
31 " \"token\": \"at1\","
32 " \"issueAdvice\": \"Auto\","
33 " \"expiresIn\": \"3600\""
34 "}";
35 static const char kTokenResponseNoAccessToken[] =
36 "{"
37 " \"issueAdvice\": \"Auto\""
38 "}";
40 static const char kValidIssueAdviceResponse[] =
41 "{"
42 " \"issueAdvice\": \"consent\","
43 " \"consent\": {"
44 " \"oauthClient\": {"
45 " \"name\": \"Test app\","
46 " \"iconUri\": \"\","
47 " \"developerEmail\": \"munjal@chromium.org\""
48 " },"
49 " \"scopes\": ["
50 " {"
51 " \"description\": \"Manage your calendars\","
52 " \"detail\": \"\nView and manage your calendars\n\""
53 " },"
54 " {"
55 " \"description\": \"Manage your documents\","
56 " \"detail\": \"\nView your documents\nUpload new documents\n\""
57 " }"
58 " ]"
59 " }"
60 "}";
62 static const char kIssueAdviceResponseNoDescription[] =
63 "{"
64 " \"issueAdvice\": \"consent\","
65 " \"consent\": {"
66 " \"oauthClient\": {"
67 " \"name\": \"Test app\","
68 " \"iconUri\": \"\","
69 " \"developerEmail\": \"munjal@chromium.org\""
70 " },"
71 " \"scopes\": ["
72 " {"
73 " \"description\": \"Manage your calendars\","
74 " \"detail\": \"\nView and manage your calendars\n\""
75 " },"
76 " {"
77 " \"detail\": \"\nView your documents\nUpload new documents\n\""
78 " }"
79 " ]"
80 " }"
81 "}";
83 static const char kIssueAdviceResponseNoDetail[] =
84 "{"
85 " \"issueAdvice\": \"consent\","
86 " \"consent\": {"
87 " \"oauthClient\": {"
88 " \"name\": \"Test app\","
89 " \"iconUri\": \"\","
90 " \"developerEmail\": \"munjal@chromium.org\""
91 " },"
92 " \"scopes\": ["
93 " {"
94 " \"description\": \"Manage your calendars\","
95 " \"detail\": \"\nView and manage your calendars\n\""
96 " },"
97 " {"
98 " \"description\": \"Manage your documents\""
99 " }"
100 " ]"
101 " }"
102 "}";
104 std::vector<std::string> CreateTestScopes() {
105 std::vector<std::string> scopes;
106 scopes.push_back("http://scope1");
107 scopes.push_back("http://scope2");
108 return scopes;
111 static IssueAdviceInfo CreateIssueAdvice() {
112 IssueAdviceInfo ia;
113 IssueAdviceInfoEntry e1;
114 e1.description = base::ASCIIToUTF16("Manage your calendars");
115 e1.details.push_back(base::ASCIIToUTF16("View and manage your calendars"));
116 ia.push_back(e1);
117 IssueAdviceInfoEntry e2;
118 e2.description = base::ASCIIToUTF16("Manage your documents");
119 e2.details.push_back(base::ASCIIToUTF16("View your documents"));
120 e2.details.push_back(base::ASCIIToUTF16("Upload new documents"));
121 ia.push_back(e2);
122 return ia;
125 class MockDelegate : public OAuth2MintTokenFlow::Delegate {
126 public:
127 MockDelegate() {}
128 ~MockDelegate() {}
130 MOCK_METHOD2(OnMintTokenSuccess, void(const std::string& access_token,
131 int time_to_live));
132 MOCK_METHOD1(OnIssueAdviceSuccess,
133 void (const IssueAdviceInfo& issue_advice));
134 MOCK_METHOD1(OnMintTokenFailure,
135 void(const GoogleServiceAuthError& error));
138 class MockMintTokenFlow : public OAuth2MintTokenFlow {
139 public:
140 explicit MockMintTokenFlow(MockDelegate* delegate,
141 const OAuth2MintTokenFlow::Parameters& parameters)
142 : OAuth2MintTokenFlow(delegate, parameters) {}
143 ~MockMintTokenFlow() {}
145 MOCK_METHOD0(CreateAccessTokenFetcher, OAuth2AccessTokenFetcher*());
148 } // namespace
150 class OAuth2MintTokenFlowTest : public testing::Test {
151 public:
152 OAuth2MintTokenFlowTest() {}
153 virtual ~OAuth2MintTokenFlowTest() { }
155 protected:
156 void CreateFlow(OAuth2MintTokenFlow::Mode mode) {
157 return CreateFlow(&delegate_, mode, "");
160 void CreateFlowWithDeviceId(const std::string& device_id) {
161 return CreateFlow(&delegate_, OAuth2MintTokenFlow::MODE_ISSUE_ADVICE,
162 device_id);
165 void CreateFlow(MockDelegate* delegate,
166 OAuth2MintTokenFlow::Mode mode,
167 const std::string& device_id) {
168 std::string ext_id = "ext1";
169 std::string client_id = "client1";
170 std::vector<std::string> scopes(CreateTestScopes());
171 flow_.reset(new MockMintTokenFlow(
172 delegate, OAuth2MintTokenFlow::Parameters(ext_id, client_id, scopes,
173 device_id, mode)));
176 // Helper to parse the given string to DictionaryValue.
177 static base::DictionaryValue* ParseJson(const std::string& str) {
178 scoped_ptr<base::Value> value(base::JSONReader::Read(str));
179 EXPECT_TRUE(value.get());
180 EXPECT_EQ(base::Value::TYPE_DICTIONARY, value->GetType());
181 return static_cast<base::DictionaryValue*>(value.release());
184 scoped_ptr<MockMintTokenFlow> flow_;
185 StrictMock<MockDelegate> delegate_;
188 TEST_F(OAuth2MintTokenFlowTest, CreateApiCallBody) {
189 { // Issue advice mode.
190 CreateFlow(OAuth2MintTokenFlow::MODE_ISSUE_ADVICE);
191 std::string body = flow_->CreateApiCallBody();
192 std::string expected_body(
193 "force=false"
194 "&response_type=none"
195 "&scope=http://scope1+http://scope2"
196 "&client_id=client1"
197 "&origin=ext1");
198 EXPECT_EQ(expected_body, body);
200 { // Record grant mode.
201 CreateFlow(OAuth2MintTokenFlow::MODE_RECORD_GRANT);
202 std::string body = flow_->CreateApiCallBody();
203 std::string expected_body(
204 "force=true"
205 "&response_type=none"
206 "&scope=http://scope1+http://scope2"
207 "&client_id=client1"
208 "&origin=ext1");
209 EXPECT_EQ(expected_body, body);
211 { // Mint token no force mode.
212 CreateFlow(OAuth2MintTokenFlow::MODE_MINT_TOKEN_NO_FORCE);
213 std::string body = flow_->CreateApiCallBody();
214 std::string expected_body(
215 "force=false"
216 "&response_type=token"
217 "&scope=http://scope1+http://scope2"
218 "&client_id=client1"
219 "&origin=ext1");
220 EXPECT_EQ(expected_body, body);
222 { // Mint token force mode.
223 CreateFlow(OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE);
224 std::string body = flow_->CreateApiCallBody();
225 std::string expected_body(
226 "force=true"
227 "&response_type=token"
228 "&scope=http://scope1+http://scope2"
229 "&client_id=client1"
230 "&origin=ext1");
231 EXPECT_EQ(expected_body, body);
233 { // Mint token with device_id.
234 CreateFlowWithDeviceId("device_id1");
235 std::string body = flow_->CreateApiCallBody();
236 std::string expected_body(
237 "force=false"
238 "&response_type=none"
239 "&scope=http://scope1+http://scope2"
240 "&client_id=client1"
241 "&origin=ext1"
242 "&device_id=device_id1"
243 "&device_type=chrome");
244 EXPECT_EQ(expected_body, body);
248 TEST_F(OAuth2MintTokenFlowTest, ParseMintTokenResponse) {
249 { // Access token missing.
250 scoped_ptr<base::DictionaryValue> json(
251 ParseJson(kTokenResponseNoAccessToken));
252 std::string at;
253 int ttl;
254 EXPECT_FALSE(OAuth2MintTokenFlow::ParseMintTokenResponse(json.get(), &at,
255 &ttl));
256 EXPECT_TRUE(at.empty());
258 { // All good.
259 scoped_ptr<base::DictionaryValue> json(ParseJson(kValidTokenResponse));
260 std::string at;
261 int ttl;
262 EXPECT_TRUE(OAuth2MintTokenFlow::ParseMintTokenResponse(json.get(), &at,
263 &ttl));
264 EXPECT_EQ("at1", at);
265 EXPECT_EQ(3600, ttl);
269 TEST_F(OAuth2MintTokenFlowTest, ParseIssueAdviceResponse) {
270 { // Description missing.
271 scoped_ptr<base::DictionaryValue> json(
272 ParseJson(kIssueAdviceResponseNoDescription));
273 IssueAdviceInfo ia;
274 EXPECT_FALSE(OAuth2MintTokenFlow::ParseIssueAdviceResponse(
275 json.get(), &ia));
276 EXPECT_TRUE(ia.empty());
278 { // Detail missing.
279 scoped_ptr<base::DictionaryValue> json(
280 ParseJson(kIssueAdviceResponseNoDetail));
281 IssueAdviceInfo ia;
282 EXPECT_FALSE(OAuth2MintTokenFlow::ParseIssueAdviceResponse(
283 json.get(), &ia));
284 EXPECT_TRUE(ia.empty());
286 { // All good.
287 scoped_ptr<base::DictionaryValue> json(
288 ParseJson(kValidIssueAdviceResponse));
289 IssueAdviceInfo ia;
290 EXPECT_TRUE(OAuth2MintTokenFlow::ParseIssueAdviceResponse(
291 json.get(), &ia));
292 IssueAdviceInfo ia_expected(CreateIssueAdvice());
293 EXPECT_EQ(ia_expected, ia);
297 TEST_F(OAuth2MintTokenFlowTest, ProcessApiCallSuccess) {
298 { // No body.
299 TestURLFetcher url_fetcher(1, GURL("http://www.google.com"), NULL);
300 url_fetcher.SetResponseString(std::string());
301 CreateFlow(OAuth2MintTokenFlow::MODE_MINT_TOKEN_NO_FORCE);
302 EXPECT_CALL(delegate_, OnMintTokenFailure(_));
303 flow_->ProcessApiCallSuccess(&url_fetcher);
305 { // Bad json.
306 TestURLFetcher url_fetcher(1, GURL("http://www.google.com"), NULL);
307 url_fetcher.SetResponseString("foo");
308 CreateFlow(OAuth2MintTokenFlow::MODE_MINT_TOKEN_NO_FORCE);
309 EXPECT_CALL(delegate_, OnMintTokenFailure(_));
310 flow_->ProcessApiCallSuccess(&url_fetcher);
312 { // Valid json: no access token.
313 TestURLFetcher url_fetcher(1, GURL("http://www.google.com"), NULL);
314 url_fetcher.SetResponseString(kTokenResponseNoAccessToken);
315 CreateFlow(OAuth2MintTokenFlow::MODE_MINT_TOKEN_NO_FORCE);
316 EXPECT_CALL(delegate_, OnMintTokenFailure(_));
317 flow_->ProcessApiCallSuccess(&url_fetcher);
319 { // Valid json: good token response.
320 TestURLFetcher url_fetcher(1, GURL("http://www.google.com"), NULL);
321 url_fetcher.SetResponseString(kValidTokenResponse);
322 CreateFlow(OAuth2MintTokenFlow::MODE_MINT_TOKEN_NO_FORCE);
323 EXPECT_CALL(delegate_, OnMintTokenSuccess("at1", 3600));
324 flow_->ProcessApiCallSuccess(&url_fetcher);
326 { // Valid json: no description.
327 TestURLFetcher url_fetcher(1, GURL("http://www.google.com"), NULL);
328 url_fetcher.SetResponseString(kIssueAdviceResponseNoDescription);
329 CreateFlow(OAuth2MintTokenFlow::MODE_ISSUE_ADVICE);
330 EXPECT_CALL(delegate_, OnMintTokenFailure(_));
331 flow_->ProcessApiCallSuccess(&url_fetcher);
333 { // Valid json: no detail.
334 TestURLFetcher url_fetcher(1, GURL("http://www.google.com"), NULL);
335 url_fetcher.SetResponseString(kIssueAdviceResponseNoDetail);
336 CreateFlow(OAuth2MintTokenFlow::MODE_ISSUE_ADVICE);
337 EXPECT_CALL(delegate_, OnMintTokenFailure(_));
338 flow_->ProcessApiCallSuccess(&url_fetcher);
340 { // Valid json: good issue advice response.
341 TestURLFetcher url_fetcher(1, GURL("http://www.google.com"), NULL);
342 url_fetcher.SetResponseString(kValidIssueAdviceResponse);
343 CreateFlow(OAuth2MintTokenFlow::MODE_ISSUE_ADVICE);
344 IssueAdviceInfo ia(CreateIssueAdvice());
345 EXPECT_CALL(delegate_, OnIssueAdviceSuccess(ia));
346 flow_->ProcessApiCallSuccess(&url_fetcher);
350 TEST_F(OAuth2MintTokenFlowTest, ProcessApiCallFailure) {
351 { // Null delegate should work fine.
352 TestURLFetcher url_fetcher(1, GURL("http://www.google.com"), NULL);
353 url_fetcher.set_status(URLRequestStatus(URLRequestStatus::FAILED, 101));
354 CreateFlow(NULL, OAuth2MintTokenFlow::MODE_MINT_TOKEN_NO_FORCE, "");
355 flow_->ProcessApiCallFailure(&url_fetcher);
358 { // Non-null delegate.
359 TestURLFetcher url_fetcher(1, GURL("http://www.google.com"), NULL);
360 url_fetcher.set_status(URLRequestStatus(URLRequestStatus::FAILED, 101));
361 CreateFlow(OAuth2MintTokenFlow::MODE_MINT_TOKEN_NO_FORCE);
362 EXPECT_CALL(delegate_, OnMintTokenFailure(_));
363 flow_->ProcessApiCallFailure(&url_fetcher);