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/base/net_errors.h"
17 #include "net/url_request/url_request_status.h"
22 const uint64 kAndroidId
= 42UL;
23 const char kAppId
[] = "TestAppId";
24 const char kDeveloperId
[] = "Project1";
25 const char kLoginHeader
[] = "AidLogin";
26 const char kRegistrationURL
[] = "http://foo.bar/register";
27 const uint64 kSecurityToken
= 77UL;
28 const int kGCMVersion
= 40;
29 const char kInstanceId
[] = "IID1";
30 const char kScope
[] = "GCM";
34 class RegistrationRequestTest
: public GCMRequestTestBase
{
36 RegistrationRequestTest();
37 ~RegistrationRequestTest() override
;
39 void RegistrationCallback(RegistrationRequest::Status status
,
40 const std::string
& registration_id
);
42 void CompleteFetch() override
;
44 void set_max_retry_count(int max_retry_count
) {
45 max_retry_count_
= max_retry_count
;
50 RegistrationRequest::Status status_
;
51 std::string registration_id_
;
52 bool callback_called_
;
53 std::map
<std::string
, std::string
> extras_
;
54 scoped_ptr
<RegistrationRequest
> request_
;
55 FakeGCMStatsRecorder recorder_
;
58 RegistrationRequestTest::RegistrationRequestTest()
59 : max_retry_count_(2),
60 status_(RegistrationRequest::SUCCESS
),
61 callback_called_(false) {}
63 RegistrationRequestTest::~RegistrationRequestTest() {}
65 void RegistrationRequestTest::RegistrationCallback(
66 RegistrationRequest::Status status
,
67 const std::string
& registration_id
) {
69 registration_id_
= registration_id
;
70 callback_called_
= true;
73 void RegistrationRequestTest::CompleteFetch() {
74 registration_id_
.clear();
75 status_
= RegistrationRequest::SUCCESS
;
76 callback_called_
= false;
78 GCMRequestTestBase::CompleteFetch();
81 class GCMRegistrationRequestTest
: public RegistrationRequestTest
{
83 GCMRegistrationRequestTest();
84 ~GCMRegistrationRequestTest() override
;
86 void CreateRequest(const std::string
& sender_ids
);
89 GCMRegistrationRequestTest::GCMRegistrationRequestTest() {
92 GCMRegistrationRequestTest::~GCMRegistrationRequestTest() {
95 void GCMRegistrationRequestTest::CreateRequest(const std::string
& sender_ids
) {
96 RegistrationRequest::RequestInfo
request_info(
97 kAndroidId
, kSecurityToken
, kAppId
);
98 scoped_ptr
<GCMRegistrationRequestHandler
> request_handler(
99 new GCMRegistrationRequestHandler(sender_ids
));
100 request_
.reset(new RegistrationRequest(
101 GURL(kRegistrationURL
),
103 request_handler
.Pass(),
105 base::Bind(&RegistrationRequestTest::RegistrationCallback
,
106 base::Unretained(this)),
108 url_request_context_getter(),
113 TEST_F(GCMRegistrationRequestTest
, RequestSuccessful
) {
114 set_max_retry_count(0);
115 CreateRequest("sender1,sender2");
118 SetResponse(net::HTTP_OK
, "token=2501");
121 EXPECT_TRUE(callback_called_
);
122 EXPECT_EQ(RegistrationRequest::SUCCESS
, status_
);
123 EXPECT_EQ("2501", registration_id_
);
126 TEST_F(GCMRegistrationRequestTest
, RequestDataAndURL
) {
127 CreateRequest(kDeveloperId
);
130 // Get data sent by request.
131 net::TestURLFetcher
* fetcher
= GetFetcher();
132 ASSERT_TRUE(fetcher
);
134 EXPECT_EQ(GURL(kRegistrationURL
), fetcher
->GetOriginalURL());
136 // Verify that authorization header was put together properly.
137 net::HttpRequestHeaders headers
;
138 fetcher
->GetExtraRequestHeaders(&headers
);
139 std::string auth_header
;
140 headers
.GetHeader(net::HttpRequestHeaders::kAuthorization
, &auth_header
);
141 base::StringTokenizer
auth_tokenizer(auth_header
, " :");
142 ASSERT_TRUE(auth_tokenizer
.GetNext());
143 EXPECT_EQ(kLoginHeader
, auth_tokenizer
.token());
144 ASSERT_TRUE(auth_tokenizer
.GetNext());
145 EXPECT_EQ(base::Uint64ToString(kAndroidId
), auth_tokenizer
.token());
146 ASSERT_TRUE(auth_tokenizer
.GetNext());
147 EXPECT_EQ(base::Uint64ToString(kSecurityToken
), auth_tokenizer
.token());
149 std::map
<std::string
, std::string
> expected_pairs
;
150 expected_pairs
["app"] = kAppId
;
151 expected_pairs
["sender"] = kDeveloperId
;
152 expected_pairs
["device"] = base::Uint64ToString(kAndroidId
);
154 // Verify data was formatted properly.
155 std::string upload_data
= fetcher
->upload_data();
156 base::StringTokenizer
data_tokenizer(upload_data
, "&=");
157 while (data_tokenizer
.GetNext()) {
158 std::map
<std::string
, std::string
>::iterator iter
=
159 expected_pairs
.find(data_tokenizer
.token());
160 ASSERT_TRUE(iter
!= expected_pairs
.end());
161 ASSERT_TRUE(data_tokenizer
.GetNext());
162 EXPECT_EQ(iter
->second
, data_tokenizer
.token());
163 // Ensure that none of the keys appears twice.
164 expected_pairs
.erase(iter
);
167 EXPECT_EQ(0UL, expected_pairs
.size());
170 TEST_F(GCMRegistrationRequestTest
, RequestRegistrationWithMultipleSenderIds
) {
171 CreateRequest("sender1,sender2@gmail.com");
174 net::TestURLFetcher
* fetcher
= GetFetcher();
175 ASSERT_TRUE(fetcher
);
177 // Verify data was formatted properly.
178 std::string upload_data
= fetcher
->upload_data();
179 base::StringTokenizer
data_tokenizer(upload_data
, "&=");
181 // Skip all tokens until you hit entry for senders.
182 while (data_tokenizer
.GetNext() && data_tokenizer
.token() != "sender")
185 ASSERT_TRUE(data_tokenizer
.GetNext());
186 std::string
senders(net::UnescapeURLComponent(data_tokenizer
.token(),
187 net::UnescapeRule::URL_SPECIAL_CHARS
));
188 base::StringTokenizer
sender_tokenizer(senders
, ",");
189 ASSERT_TRUE(sender_tokenizer
.GetNext());
190 EXPECT_EQ("sender1", sender_tokenizer
.token());
191 ASSERT_TRUE(sender_tokenizer
.GetNext());
192 EXPECT_EQ("sender2@gmail.com", sender_tokenizer
.token());
195 TEST_F(GCMRegistrationRequestTest
, ResponseParsing
) {
196 CreateRequest("sender1,sender2");
199 SetResponse(net::HTTP_OK
, "token=2501");
202 EXPECT_TRUE(callback_called_
);
203 EXPECT_EQ(RegistrationRequest::SUCCESS
, status_
);
204 EXPECT_EQ("2501", registration_id_
);
207 TEST_F(GCMRegistrationRequestTest
, ResponseHttpStatusNotOK
) {
208 CreateRequest("sender1,sender2");
211 SetResponse(net::HTTP_UNAUTHORIZED
, "token=2501");
214 EXPECT_FALSE(callback_called_
);
216 SetResponse(net::HTTP_OK
, "token=2501");
219 EXPECT_TRUE(callback_called_
);
220 EXPECT_EQ(RegistrationRequest::SUCCESS
, status_
);
221 EXPECT_EQ("2501", registration_id_
);
224 TEST_F(GCMRegistrationRequestTest
, ResponseMissingRegistrationId
) {
225 CreateRequest("sender1,sender2");
228 SetResponse(net::HTTP_OK
, "");
231 EXPECT_FALSE(callback_called_
);
233 SetResponse(net::HTTP_OK
, "some error in response");
236 EXPECT_FALSE(callback_called_
);
238 // Ensuring a retry happened and succeeds.
239 SetResponse(net::HTTP_OK
, "token=2501");
242 EXPECT_TRUE(callback_called_
);
243 EXPECT_EQ(RegistrationRequest::SUCCESS
, status_
);
244 EXPECT_EQ("2501", registration_id_
);
247 TEST_F(GCMRegistrationRequestTest
, ResponseDeviceRegistrationError
) {
248 CreateRequest("sender1,sender2");
251 SetResponse(net::HTTP_OK
, "Error=PHONE_REGISTRATION_ERROR");
254 EXPECT_FALSE(callback_called_
);
256 // Ensuring a retry happened and succeeds.
257 SetResponse(net::HTTP_OK
, "token=2501");
260 EXPECT_TRUE(callback_called_
);
261 EXPECT_EQ(RegistrationRequest::SUCCESS
, status_
);
262 EXPECT_EQ("2501", registration_id_
);
265 TEST_F(GCMRegistrationRequestTest
, ResponseAuthenticationError
) {
266 CreateRequest("sender1,sender2");
269 SetResponse(net::HTTP_UNAUTHORIZED
,
270 "Error=AUTHENTICATION_FAILED");
273 EXPECT_FALSE(callback_called_
);
275 // Ensuring a retry happened and succeeds.
276 SetResponse(net::HTTP_OK
, "token=2501");
279 EXPECT_TRUE(callback_called_
);
280 EXPECT_EQ(RegistrationRequest::SUCCESS
, status_
);
281 EXPECT_EQ("2501", registration_id_
);
284 TEST_F(GCMRegistrationRequestTest
, ResponseInvalidParameters
) {
285 CreateRequest("sender1,sender2");
288 SetResponse(net::HTTP_OK
, "Error=INVALID_PARAMETERS");
291 EXPECT_TRUE(callback_called_
);
292 EXPECT_EQ(RegistrationRequest::INVALID_PARAMETERS
, status_
);
293 EXPECT_EQ(std::string(), registration_id_
);
296 TEST_F(GCMRegistrationRequestTest
, ResponseInvalidSender
) {
297 CreateRequest("sender1,sender2");
300 SetResponse(net::HTTP_OK
, "Error=INVALID_SENDER");
303 EXPECT_TRUE(callback_called_
);
304 EXPECT_EQ(RegistrationRequest::INVALID_SENDER
, status_
);
305 EXPECT_EQ(std::string(), registration_id_
);
308 TEST_F(GCMRegistrationRequestTest
, ResponseInvalidSenderBadRequest
) {
309 CreateRequest("sender1");
312 SetResponse(net::HTTP_BAD_REQUEST
, "Error=INVALID_SENDER");
315 EXPECT_TRUE(callback_called_
);
316 EXPECT_EQ(RegistrationRequest::INVALID_SENDER
, status_
);
317 EXPECT_EQ(std::string(), registration_id_
);
320 TEST_F(GCMRegistrationRequestTest
, RequestNotSuccessful
) {
321 CreateRequest("sender1,sender2");
324 SetResponse(net::HTTP_OK
, "token=2501");
326 net::TestURLFetcher
* fetcher
= GetFetcher();
327 ASSERT_TRUE(fetcher
);
328 GetFetcher()->set_status(net::URLRequestStatus::FromError(net::ERR_FAILED
));
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_
);