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.
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/string_tokenizer.h"
11 #include "google_apis/gcm/engine/gcm_registration_request_handler.h"
12 #include "google_apis/gcm/engine/gcm_request_test_base.h"
13 #include "google_apis/gcm/engine/instance_id_get_token_request_handler.h"
14 #include "google_apis/gcm/monitoring/fake_gcm_stats_recorder.h"
15 #include "net/base/load_flags.h"
16 #include "net/url_request/url_request_status.h"
21 const uint64 kAndroidId
= 42UL;
22 const char kAppId
[] = "TestAppId";
23 const char kDeveloperId
[] = "Project1";
24 const char kLoginHeader
[] = "AidLogin";
25 const char kRegistrationURL
[] = "http://foo.bar/register";
26 const uint64 kSecurityToken
= 77UL;
27 const int kGCMVersion
= 40;
28 const char kInstanceId
[] = "IID1";
29 const char kScope
[] = "GCM";
33 class RegistrationRequestTest
: public GCMRequestTestBase
{
35 RegistrationRequestTest();
36 ~RegistrationRequestTest() override
;
38 void RegistrationCallback(RegistrationRequest::Status status
,
39 const std::string
& registration_id
);
41 void CompleteFetch() override
;
43 void set_max_retry_count(int max_retry_count
) {
44 max_retry_count_
= max_retry_count
;
49 RegistrationRequest::Status status_
;
50 std::string registration_id_
;
51 bool callback_called_
;
52 std::map
<std::string
, std::string
> extras_
;
53 scoped_ptr
<RegistrationRequest
> request_
;
54 FakeGCMStatsRecorder recorder_
;
57 RegistrationRequestTest::RegistrationRequestTest()
58 : max_retry_count_(2),
59 status_(RegistrationRequest::SUCCESS
),
60 callback_called_(false) {}
62 RegistrationRequestTest::~RegistrationRequestTest() {}
64 void RegistrationRequestTest::RegistrationCallback(
65 RegistrationRequest::Status status
,
66 const std::string
& registration_id
) {
68 registration_id_
= registration_id
;
69 callback_called_
= true;
72 void RegistrationRequestTest::CompleteFetch() {
73 registration_id_
.clear();
74 status_
= RegistrationRequest::SUCCESS
;
75 callback_called_
= false;
77 GCMRequestTestBase::CompleteFetch();
80 class GCMRegistrationRequestTest
: public RegistrationRequestTest
{
82 GCMRegistrationRequestTest();
83 ~GCMRegistrationRequestTest() override
;
85 void CreateRequest(const std::string
& sender_ids
);
88 GCMRegistrationRequestTest::GCMRegistrationRequestTest() {
91 GCMRegistrationRequestTest::~GCMRegistrationRequestTest() {
94 void GCMRegistrationRequestTest::CreateRequest(const std::string
& sender_ids
) {
95 RegistrationRequest::RequestInfo
request_info(
96 kAndroidId
, kSecurityToken
, kAppId
);
97 scoped_ptr
<GCMRegistrationRequestHandler
> request_handler(
98 new GCMRegistrationRequestHandler(sender_ids
));
99 request_
.reset(new RegistrationRequest(
100 GURL(kRegistrationURL
),
102 request_handler
.Pass(),
104 base::Bind(&RegistrationRequestTest::RegistrationCallback
,
105 base::Unretained(this)),
107 url_request_context_getter(),
112 TEST_F(GCMRegistrationRequestTest
, RequestSuccessful
) {
113 set_max_retry_count(0);
114 CreateRequest("sender1,sender2");
117 SetResponse(net::HTTP_OK
, "token=2501");
120 EXPECT_TRUE(callback_called_
);
121 EXPECT_EQ(RegistrationRequest::SUCCESS
, status_
);
122 EXPECT_EQ("2501", registration_id_
);
125 TEST_F(GCMRegistrationRequestTest
, RequestDataAndURL
) {
126 CreateRequest(kDeveloperId
);
129 // Get data sent by request.
130 net::TestURLFetcher
* fetcher
= GetFetcher();
131 ASSERT_TRUE(fetcher
);
133 EXPECT_EQ(GURL(kRegistrationURL
), fetcher
->GetOriginalURL());
135 // Verify that authorization header was put together properly.
136 net::HttpRequestHeaders headers
;
137 fetcher
->GetExtraRequestHeaders(&headers
);
138 std::string auth_header
;
139 headers
.GetHeader(net::HttpRequestHeaders::kAuthorization
, &auth_header
);
140 base::StringTokenizer
auth_tokenizer(auth_header
, " :");
141 ASSERT_TRUE(auth_tokenizer
.GetNext());
142 EXPECT_EQ(kLoginHeader
, auth_tokenizer
.token());
143 ASSERT_TRUE(auth_tokenizer
.GetNext());
144 EXPECT_EQ(base::Uint64ToString(kAndroidId
), auth_tokenizer
.token());
145 ASSERT_TRUE(auth_tokenizer
.GetNext());
146 EXPECT_EQ(base::Uint64ToString(kSecurityToken
), auth_tokenizer
.token());
148 std::map
<std::string
, std::string
> expected_pairs
;
149 expected_pairs
["app"] = kAppId
;
150 expected_pairs
["sender"] = kDeveloperId
;
151 expected_pairs
["device"] = base::Uint64ToString(kAndroidId
);
153 // Verify data was formatted properly.
154 std::string upload_data
= fetcher
->upload_data();
155 base::StringTokenizer
data_tokenizer(upload_data
, "&=");
156 while (data_tokenizer
.GetNext()) {
157 std::map
<std::string
, std::string
>::iterator iter
=
158 expected_pairs
.find(data_tokenizer
.token());
159 ASSERT_TRUE(iter
!= expected_pairs
.end());
160 ASSERT_TRUE(data_tokenizer
.GetNext());
161 EXPECT_EQ(iter
->second
, data_tokenizer
.token());
162 // Ensure that none of the keys appears twice.
163 expected_pairs
.erase(iter
);
166 EXPECT_EQ(0UL, expected_pairs
.size());
169 TEST_F(GCMRegistrationRequestTest
, RequestRegistrationWithMultipleSenderIds
) {
170 CreateRequest("sender1,sender2@gmail.com");
173 net::TestURLFetcher
* fetcher
= GetFetcher();
174 ASSERT_TRUE(fetcher
);
176 // Verify data was formatted properly.
177 std::string upload_data
= fetcher
->upload_data();
178 base::StringTokenizer
data_tokenizer(upload_data
, "&=");
180 // Skip all tokens until you hit entry for senders.
181 while (data_tokenizer
.GetNext() && data_tokenizer
.token() != "sender")
184 ASSERT_TRUE(data_tokenizer
.GetNext());
185 std::string
senders(net::UnescapeURLComponent(data_tokenizer
.token(),
186 net::UnescapeRule::URL_SPECIAL_CHARS
));
187 base::StringTokenizer
sender_tokenizer(senders
, ",");
188 ASSERT_TRUE(sender_tokenizer
.GetNext());
189 EXPECT_EQ("sender1", sender_tokenizer
.token());
190 ASSERT_TRUE(sender_tokenizer
.GetNext());
191 EXPECT_EQ("sender2@gmail.com", sender_tokenizer
.token());
194 TEST_F(GCMRegistrationRequestTest
, ResponseParsing
) {
195 CreateRequest("sender1,sender2");
198 SetResponse(net::HTTP_OK
, "token=2501");
201 EXPECT_TRUE(callback_called_
);
202 EXPECT_EQ(RegistrationRequest::SUCCESS
, status_
);
203 EXPECT_EQ("2501", registration_id_
);
206 TEST_F(GCMRegistrationRequestTest
, ResponseHttpStatusNotOK
) {
207 CreateRequest("sender1,sender2");
210 SetResponse(net::HTTP_UNAUTHORIZED
, "token=2501");
213 EXPECT_FALSE(callback_called_
);
215 SetResponse(net::HTTP_OK
, "token=2501");
218 EXPECT_TRUE(callback_called_
);
219 EXPECT_EQ(RegistrationRequest::SUCCESS
, status_
);
220 EXPECT_EQ("2501", registration_id_
);
223 TEST_F(GCMRegistrationRequestTest
, ResponseMissingRegistrationId
) {
224 CreateRequest("sender1,sender2");
227 SetResponse(net::HTTP_OK
, "");
230 EXPECT_FALSE(callback_called_
);
232 SetResponse(net::HTTP_OK
, "some error in response");
235 EXPECT_FALSE(callback_called_
);
237 // Ensuring a retry happened and succeeds.
238 SetResponse(net::HTTP_OK
, "token=2501");
241 EXPECT_TRUE(callback_called_
);
242 EXPECT_EQ(RegistrationRequest::SUCCESS
, status_
);
243 EXPECT_EQ("2501", registration_id_
);
246 TEST_F(GCMRegistrationRequestTest
, ResponseDeviceRegistrationError
) {
247 CreateRequest("sender1,sender2");
250 SetResponse(net::HTTP_OK
, "Error=PHONE_REGISTRATION_ERROR");
253 EXPECT_FALSE(callback_called_
);
255 // Ensuring a retry happened and succeeds.
256 SetResponse(net::HTTP_OK
, "token=2501");
259 EXPECT_TRUE(callback_called_
);
260 EXPECT_EQ(RegistrationRequest::SUCCESS
, status_
);
261 EXPECT_EQ("2501", registration_id_
);
264 TEST_F(GCMRegistrationRequestTest
, ResponseAuthenticationError
) {
265 CreateRequest("sender1,sender2");
268 SetResponse(net::HTTP_UNAUTHORIZED
,
269 "Error=AUTHENTICATION_FAILED");
272 EXPECT_FALSE(callback_called_
);
274 // Ensuring a retry happened and succeeds.
275 SetResponse(net::HTTP_OK
, "token=2501");
278 EXPECT_TRUE(callback_called_
);
279 EXPECT_EQ(RegistrationRequest::SUCCESS
, status_
);
280 EXPECT_EQ("2501", registration_id_
);
283 TEST_F(GCMRegistrationRequestTest
, ResponseInvalidParameters
) {
284 CreateRequest("sender1,sender2");
287 SetResponse(net::HTTP_OK
, "Error=INVALID_PARAMETERS");
290 EXPECT_TRUE(callback_called_
);
291 EXPECT_EQ(RegistrationRequest::INVALID_PARAMETERS
, status_
);
292 EXPECT_EQ(std::string(), registration_id_
);
295 TEST_F(GCMRegistrationRequestTest
, ResponseInvalidSender
) {
296 CreateRequest("sender1,sender2");
299 SetResponse(net::HTTP_OK
, "Error=INVALID_SENDER");
302 EXPECT_TRUE(callback_called_
);
303 EXPECT_EQ(RegistrationRequest::INVALID_SENDER
, status_
);
304 EXPECT_EQ(std::string(), registration_id_
);
307 TEST_F(GCMRegistrationRequestTest
, ResponseInvalidSenderBadRequest
) {
308 CreateRequest("sender1");
311 SetResponse(net::HTTP_BAD_REQUEST
, "Error=INVALID_SENDER");
314 EXPECT_TRUE(callback_called_
);
315 EXPECT_EQ(RegistrationRequest::INVALID_SENDER
, status_
);
316 EXPECT_EQ(std::string(), registration_id_
);
319 TEST_F(GCMRegistrationRequestTest
, RequestNotSuccessful
) {
320 CreateRequest("sender1,sender2");
323 net::URLRequestStatus
request_status(net::URLRequestStatus::FAILED
, 1);
324 SetResponse(net::HTTP_OK
, "token=2501");
326 net::TestURLFetcher
* fetcher
= GetFetcher();
327 ASSERT_TRUE(fetcher
);
328 GetFetcher()->set_status(request_status
);
332 EXPECT_FALSE(callback_called_
);
334 // Ensuring a retry happened and succeeded.
335 SetResponse(net::HTTP_OK
, "token=2501");
338 EXPECT_TRUE(callback_called_
);
339 EXPECT_EQ(RegistrationRequest::SUCCESS
, status_
);
340 EXPECT_EQ("2501", registration_id_
);
343 TEST_F(GCMRegistrationRequestTest
, ResponseHttpNotOk
) {
344 CreateRequest("sender1,sender2");
347 SetResponse(net::HTTP_GATEWAY_TIMEOUT
, "token=2501");
350 EXPECT_FALSE(callback_called_
);
352 // Ensuring a retry happened and succeeded.
353 SetResponse(net::HTTP_OK
, "token=2501");
356 EXPECT_TRUE(callback_called_
);
357 EXPECT_EQ(RegistrationRequest::SUCCESS
, status_
);
358 EXPECT_EQ("2501", registration_id_
);
361 TEST_F(GCMRegistrationRequestTest
, MaximumAttemptsReachedWithZeroRetries
) {
362 set_max_retry_count(0);
363 CreateRequest("sender1,sender2");
366 SetResponse(net::HTTP_GATEWAY_TIMEOUT
, "token=2501");
369 EXPECT_TRUE(callback_called_
);
370 EXPECT_EQ(RegistrationRequest::REACHED_MAX_RETRIES
, status_
);
371 EXPECT_EQ(std::string(), registration_id_
);
374 TEST_F(GCMRegistrationRequestTest
, MaximumAttemptsReached
) {
375 CreateRequest("sender1,sender2");
378 SetResponse(net::HTTP_GATEWAY_TIMEOUT
, "token=2501");
381 EXPECT_FALSE(callback_called_
);
383 SetResponse(net::HTTP_GATEWAY_TIMEOUT
, "token=2501");
386 EXPECT_FALSE(callback_called_
);
388 SetResponse(net::HTTP_GATEWAY_TIMEOUT
, "token=2501");
391 EXPECT_TRUE(callback_called_
);
392 EXPECT_EQ(RegistrationRequest::REACHED_MAX_RETRIES
, status_
);
393 EXPECT_EQ(std::string(), registration_id_
);
396 class InstanceIDGetTokenRequestTest
: public RegistrationRequestTest
{
398 InstanceIDGetTokenRequestTest();
399 ~InstanceIDGetTokenRequestTest() override
;
401 void CreateRequest(const std::string
& instance_id
,
402 const std::string
& authorized_entity
,
403 const std::string
& scope
,
404 const std::map
<std::string
, std::string
>& options
);
407 InstanceIDGetTokenRequestTest::InstanceIDGetTokenRequestTest() {
410 InstanceIDGetTokenRequestTest::~InstanceIDGetTokenRequestTest() {
413 void InstanceIDGetTokenRequestTest::CreateRequest(
414 const std::string
& instance_id
,
415 const std::string
& authorized_entity
,
416 const std::string
& scope
,
417 const std::map
<std::string
, std::string
>& options
) {
418 RegistrationRequest::RequestInfo
request_info(
419 kAndroidId
, kSecurityToken
, kAppId
);
420 scoped_ptr
<InstanceIDGetTokenRequestHandler
> request_handler(
421 new InstanceIDGetTokenRequestHandler(
422 instance_id
, authorized_entity
, scope
, kGCMVersion
, options
));
423 request_
.reset(new RegistrationRequest(
424 GURL(kRegistrationURL
),
426 request_handler
.Pass(),
428 base::Bind(&RegistrationRequestTest::RegistrationCallback
,
429 base::Unretained(this)),
431 url_request_context_getter(),
436 TEST_F(InstanceIDGetTokenRequestTest
, RequestSuccessful
) {
437 std::map
<std::string
, std::string
> options
;
438 options
["Foo"] = "Bar";
440 set_max_retry_count(0);
441 CreateRequest(kInstanceId
, kDeveloperId
, kScope
, options
);
444 SetResponse(net::HTTP_OK
, "token=2501");
447 EXPECT_TRUE(callback_called_
);
448 EXPECT_EQ(RegistrationRequest::SUCCESS
, status_
);
449 EXPECT_EQ("2501", registration_id_
);
452 TEST_F(InstanceIDGetTokenRequestTest
, RequestDataAndURL
) {
453 std::map
<std::string
, std::string
> options
;
454 options
["Foo"] = "Bar";
455 CreateRequest(kInstanceId
, kDeveloperId
, kScope
, options
);
458 // Get data sent by request.
459 net::TestURLFetcher
* fetcher
= GetFetcher();
460 ASSERT_TRUE(fetcher
);
462 EXPECT_EQ(GURL(kRegistrationURL
), fetcher
->GetOriginalURL());
464 // Verify that the no-cookie flag is set.
465 int flags
= fetcher
->GetLoadFlags();
466 EXPECT_TRUE(flags
& net::LOAD_DO_NOT_SEND_COOKIES
);
467 EXPECT_TRUE(flags
& net::LOAD_DO_NOT_SAVE_COOKIES
);
469 // Verify that authorization header was put together properly.
470 net::HttpRequestHeaders headers
;
471 fetcher
->GetExtraRequestHeaders(&headers
);
472 std::string auth_header
;
473 headers
.GetHeader(net::HttpRequestHeaders::kAuthorization
, &auth_header
);
474 base::StringTokenizer
auth_tokenizer(auth_header
, " :");
475 ASSERT_TRUE(auth_tokenizer
.GetNext());
476 EXPECT_EQ(kLoginHeader
, auth_tokenizer
.token());
477 ASSERT_TRUE(auth_tokenizer
.GetNext());
478 EXPECT_EQ(base::Uint64ToString(kAndroidId
), auth_tokenizer
.token());
479 ASSERT_TRUE(auth_tokenizer
.GetNext());
480 EXPECT_EQ(base::Uint64ToString(kSecurityToken
), auth_tokenizer
.token());
482 std::map
<std::string
, std::string
> expected_pairs
;
483 expected_pairs
["gmsv"] = base::IntToString(kGCMVersion
);
484 expected_pairs
["app"] = kAppId
;
485 expected_pairs
["sender"] = kDeveloperId
;
486 expected_pairs
["X-subtype"] = kDeveloperId
;
487 expected_pairs
["device"] = base::Uint64ToString(kAndroidId
);
488 expected_pairs
["appid"] = kInstanceId
;
489 expected_pairs
["scope"] = kScope
;
490 expected_pairs
["X-scope"] = kScope
;
491 expected_pairs
["X-Foo"] = "Bar";
493 // Verify data was formatted properly.
494 std::string upload_data
= fetcher
->upload_data();
495 base::StringTokenizer
data_tokenizer(upload_data
, "&=");
496 while (data_tokenizer
.GetNext()) {
497 std::map
<std::string
, std::string
>::iterator iter
=
498 expected_pairs
.find(data_tokenizer
.token());
499 ASSERT_TRUE(iter
!= expected_pairs
.end());
500 ASSERT_TRUE(data_tokenizer
.GetNext());
501 EXPECT_EQ(iter
->second
, data_tokenizer
.token());
502 // Ensure that none of the keys appears twice.
503 expected_pairs
.erase(iter
);
506 EXPECT_EQ(0UL, expected_pairs
.size());
509 TEST_F(InstanceIDGetTokenRequestTest
, ResponseHttpStatusNotOK
) {
510 std::map
<std::string
, std::string
> options
;
511 CreateRequest(kInstanceId
, kDeveloperId
, kScope
, options
);
514 SetResponse(net::HTTP_UNAUTHORIZED
, "token=2501");
517 EXPECT_FALSE(callback_called_
);
519 SetResponse(net::HTTP_OK
, "token=2501");
522 EXPECT_TRUE(callback_called_
);
523 EXPECT_EQ(RegistrationRequest::SUCCESS
, status_
);
524 EXPECT_EQ("2501", registration_id_
);