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_request_test_base.h"
12 #include "google_apis/gcm/engine/gcm_unregistration_request_handler.h"
13 #include "google_apis/gcm/engine/instance_id_delete_token_request_handler.h"
14 #include "google_apis/gcm/monitoring/fake_gcm_stats_recorder.h"
15 #include "net/base/load_flags.h"
20 const int kMaxRetries
= 2;
21 const uint64 kAndroidId
= 42UL;
22 const char kLoginHeader
[] = "AidLogin";
23 const char kAppId
[] = "TestAppId";
24 const char kDeletedAppId
[] = "deleted=TestAppId";
25 const char kDeletedToken
[] = "token=SomeToken";
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 kDeveloperId
[] = "Project1";
31 const char kScope
[] = "GCM";
35 class UnregistrationRequestTest
: public GCMRequestTestBase
{
37 UnregistrationRequestTest();
38 ~UnregistrationRequestTest() override
;
40 void UnregistrationCallback(UnregistrationRequest::Status status
);
42 void CompleteFetch() override
;
44 int max_retry_count() const { return max_retry_count_
; }
45 void set_max_retry_count(int max_retry_count
) {
46 max_retry_count_
= max_retry_count
;
51 bool callback_called_
;
52 UnregistrationRequest::Status status_
;
53 scoped_ptr
<UnregistrationRequest
> request_
;
54 FakeGCMStatsRecorder recorder_
;
57 UnregistrationRequestTest::UnregistrationRequestTest()
58 : max_retry_count_(kMaxRetries
),
59 callback_called_(false),
60 status_(UnregistrationRequest::UNREGISTRATION_STATUS_COUNT
) {}
62 UnregistrationRequestTest::~UnregistrationRequestTest() {}
64 void UnregistrationRequestTest::UnregistrationCallback(
65 UnregistrationRequest::Status status
) {
66 callback_called_
= true;
70 void UnregistrationRequestTest::CompleteFetch() {
71 status_
= UnregistrationRequest::UNREGISTRATION_STATUS_COUNT
;
72 callback_called_
= false;
74 GCMRequestTestBase::CompleteFetch();
77 class GCMUnregistrationRequestTest
: public UnregistrationRequestTest
{
79 GCMUnregistrationRequestTest();
80 ~GCMUnregistrationRequestTest() override
;
85 GCMUnregistrationRequestTest::GCMUnregistrationRequestTest() {
88 GCMUnregistrationRequestTest::~GCMUnregistrationRequestTest() {
91 void GCMUnregistrationRequestTest::CreateRequest() {
92 UnregistrationRequest::RequestInfo
request_info(
93 kAndroidId
, kSecurityToken
, kAppId
);
94 scoped_ptr
<GCMUnregistrationRequestHandler
> request_handler(
95 new GCMUnregistrationRequestHandler(kAppId
));
96 request_
.reset(new UnregistrationRequest(
97 GURL(kRegistrationURL
),
99 request_handler
.Pass(),
101 base::Bind(&UnregistrationRequestTest::UnregistrationCallback
,
102 base::Unretained(this)),
104 url_request_context_getter(),
109 TEST_F(GCMUnregistrationRequestTest
, RequestDataPassedToFetcher
) {
113 // Get data sent by request.
114 net::TestURLFetcher
* fetcher
= GetFetcher();
115 ASSERT_TRUE(fetcher
);
117 EXPECT_EQ(GURL(kRegistrationURL
), fetcher
->GetOriginalURL());
119 int flags
= fetcher
->GetLoadFlags();
120 EXPECT_TRUE(flags
& net::LOAD_DO_NOT_SEND_COOKIES
);
121 EXPECT_TRUE(flags
& net::LOAD_DO_NOT_SAVE_COOKIES
);
123 // Verify that authorization header was put together properly.
124 net::HttpRequestHeaders headers
;
125 fetcher
->GetExtraRequestHeaders(&headers
);
126 std::string auth_header
;
127 headers
.GetHeader(net::HttpRequestHeaders::kAuthorization
, &auth_header
);
128 base::StringTokenizer
auth_tokenizer(auth_header
, " :");
129 ASSERT_TRUE(auth_tokenizer
.GetNext());
130 EXPECT_EQ(kLoginHeader
, auth_tokenizer
.token());
131 ASSERT_TRUE(auth_tokenizer
.GetNext());
132 EXPECT_EQ(base::Uint64ToString(kAndroidId
), auth_tokenizer
.token());
133 ASSERT_TRUE(auth_tokenizer
.GetNext());
134 EXPECT_EQ(base::Uint64ToString(kSecurityToken
), auth_tokenizer
.token());
135 std::string app_id_header
;
136 headers
.GetHeader("app", &app_id_header
);
137 EXPECT_EQ(kAppId
, app_id_header
);
139 std::map
<std::string
, std::string
> expected_pairs
;
140 expected_pairs
["app"] = kAppId
;
141 expected_pairs
["device"] = base::Uint64ToString(kAndroidId
);
142 expected_pairs
["delete"] = "true";
143 expected_pairs
["gcm_unreg_caller"] = "false";
145 // Verify data was formatted properly.
146 std::string upload_data
= fetcher
->upload_data();
147 base::StringTokenizer
data_tokenizer(upload_data
, "&=");
148 while (data_tokenizer
.GetNext()) {
149 std::map
<std::string
, std::string
>::iterator iter
=
150 expected_pairs
.find(data_tokenizer
.token());
151 ASSERT_TRUE(iter
!= expected_pairs
.end()) << data_tokenizer
.token();
152 ASSERT_TRUE(data_tokenizer
.GetNext()) << data_tokenizer
.token();
153 EXPECT_EQ(iter
->second
, data_tokenizer
.token());
154 // Ensure that none of the keys appears twice.
155 expected_pairs
.erase(iter
);
158 EXPECT_EQ(0UL, expected_pairs
.size());
161 TEST_F(GCMUnregistrationRequestTest
, SuccessfulUnregistration
) {
162 set_max_retry_count(0);
166 SetResponse(net::HTTP_OK
, kDeletedAppId
);
169 EXPECT_TRUE(callback_called_
);
170 EXPECT_EQ(UnregistrationRequest::SUCCESS
, status_
);
173 TEST_F(GCMUnregistrationRequestTest
, ResponseHttpStatusNotOK
) {
177 SetResponse(net::HTTP_UNAUTHORIZED
, "");
180 EXPECT_FALSE(callback_called_
);
182 SetResponse(net::HTTP_OK
, kDeletedAppId
);
185 EXPECT_TRUE(callback_called_
);
186 EXPECT_EQ(UnregistrationRequest::SUCCESS
, status_
);
189 TEST_F(GCMUnregistrationRequestTest
, ResponseEmpty
) {
193 SetResponse(net::HTTP_OK
, "");
196 EXPECT_FALSE(callback_called_
);
198 SetResponse(net::HTTP_OK
, kDeletedAppId
);
201 EXPECT_TRUE(callback_called_
);
202 EXPECT_EQ(UnregistrationRequest::SUCCESS
, status_
);
205 TEST_F(GCMUnregistrationRequestTest
, InvalidParametersError
) {
209 SetResponse(net::HTTP_OK
, "Error=INVALID_PARAMETERS");
212 EXPECT_TRUE(callback_called_
);
213 EXPECT_EQ(UnregistrationRequest::INVALID_PARAMETERS
, status_
);
216 TEST_F(GCMUnregistrationRequestTest
, UnkwnownError
) {
220 SetResponse(net::HTTP_OK
, "Error=XXX");
223 EXPECT_TRUE(callback_called_
);
224 EXPECT_EQ(UnregistrationRequest::UNKNOWN_ERROR
, status_
);
227 TEST_F(GCMUnregistrationRequestTest
, ServiceUnavailable
) {
231 SetResponse(net::HTTP_SERVICE_UNAVAILABLE
, "");
234 EXPECT_FALSE(callback_called_
);
236 SetResponse(net::HTTP_OK
, kDeletedAppId
);
239 EXPECT_TRUE(callback_called_
);
240 EXPECT_EQ(UnregistrationRequest::SUCCESS
, status_
);
243 TEST_F(GCMUnregistrationRequestTest
, InternalServerError
) {
247 SetResponse(net::HTTP_INTERNAL_SERVER_ERROR
, "");
250 EXPECT_FALSE(callback_called_
);
252 SetResponse(net::HTTP_OK
, kDeletedAppId
);
255 EXPECT_TRUE(callback_called_
);
256 EXPECT_EQ(UnregistrationRequest::SUCCESS
, status_
);
259 TEST_F(GCMUnregistrationRequestTest
, IncorrectAppId
) {
263 SetResponse(net::HTTP_OK
, "deleted=OtherTestAppId");
266 EXPECT_FALSE(callback_called_
);
268 SetResponse(net::HTTP_OK
, kDeletedAppId
);
271 EXPECT_TRUE(callback_called_
);
272 EXPECT_EQ(UnregistrationRequest::SUCCESS
, status_
);
275 TEST_F(GCMUnregistrationRequestTest
, ResponseParsingFailed
) {
279 SetResponse(net::HTTP_OK
, "some malformed response");
282 EXPECT_FALSE(callback_called_
);
284 SetResponse(net::HTTP_OK
, kDeletedAppId
);
287 EXPECT_TRUE(callback_called_
);
288 EXPECT_EQ(UnregistrationRequest::SUCCESS
, status_
);
291 TEST_F(GCMUnregistrationRequestTest
, MaximumAttemptsReachedWithZeroRetries
) {
292 set_max_retry_count(0);
296 SetResponse(net::HTTP_GATEWAY_TIMEOUT
, "bad response");
299 EXPECT_TRUE(callback_called_
);
300 EXPECT_EQ(UnregistrationRequest::REACHED_MAX_RETRIES
, status_
);
303 TEST_F(GCMUnregistrationRequestTest
, MaximumAttemptsReached
) {
307 SetResponse(net::HTTP_GATEWAY_TIMEOUT
, "bad response");
310 EXPECT_FALSE(callback_called_
);
312 SetResponse(net::HTTP_GATEWAY_TIMEOUT
, "bad response");
315 EXPECT_FALSE(callback_called_
);
317 SetResponse(net::HTTP_GATEWAY_TIMEOUT
, "bad response");
320 EXPECT_TRUE(callback_called_
);
321 EXPECT_EQ(UnregistrationRequest::REACHED_MAX_RETRIES
, status_
);
324 class InstaceIDDeleteTokenRequestTest
: public UnregistrationRequestTest
{
326 InstaceIDDeleteTokenRequestTest();
327 ~InstaceIDDeleteTokenRequestTest() override
;
329 void CreateRequest(const std::string
& instance_id
,
330 const std::string
& authorized_entity
,
331 const std::string
& scope
);
334 InstaceIDDeleteTokenRequestTest::InstaceIDDeleteTokenRequestTest() {
337 InstaceIDDeleteTokenRequestTest::~InstaceIDDeleteTokenRequestTest() {
340 void InstaceIDDeleteTokenRequestTest::CreateRequest(
341 const std::string
& instance_id
,
342 const std::string
& authorized_entity
,
343 const std::string
& scope
) {
344 UnregistrationRequest::RequestInfo
request_info(
345 kAndroidId
, kSecurityToken
, kAppId
);
346 scoped_ptr
<InstanceIDDeleteTokenRequestHandler
> request_handler(
347 new InstanceIDDeleteTokenRequestHandler(
348 instance_id
, authorized_entity
, scope
, kGCMVersion
));
349 request_
.reset(new UnregistrationRequest(
350 GURL(kRegistrationURL
),
352 request_handler
.Pass(),
354 base::Bind(&UnregistrationRequestTest::UnregistrationCallback
,
355 base::Unretained(this)),
357 url_request_context_getter(),
362 TEST_F(InstaceIDDeleteTokenRequestTest
, RequestDataPassedToFetcher
) {
363 CreateRequest(kInstanceId
, kDeveloperId
, kScope
);
366 // Get data sent by request.
367 net::TestURLFetcher
* fetcher
= GetFetcher();
368 ASSERT_TRUE(fetcher
);
370 EXPECT_EQ(GURL(kRegistrationURL
), fetcher
->GetOriginalURL());
372 // Verify that authorization header was put together properly.
373 net::HttpRequestHeaders headers
;
374 fetcher
->GetExtraRequestHeaders(&headers
);
375 std::string auth_header
;
376 headers
.GetHeader(net::HttpRequestHeaders::kAuthorization
, &auth_header
);
377 base::StringTokenizer
auth_tokenizer(auth_header
, " :");
378 ASSERT_TRUE(auth_tokenizer
.GetNext());
379 EXPECT_EQ(kLoginHeader
, auth_tokenizer
.token());
380 ASSERT_TRUE(auth_tokenizer
.GetNext());
381 EXPECT_EQ(base::Uint64ToString(kAndroidId
), auth_tokenizer
.token());
382 ASSERT_TRUE(auth_tokenizer
.GetNext());
383 EXPECT_EQ(base::Uint64ToString(kSecurityToken
), auth_tokenizer
.token());
384 std::string app_id_header
;
385 headers
.GetHeader("app", &app_id_header
);
386 EXPECT_EQ(kAppId
, app_id_header
);
388 std::map
<std::string
, std::string
> expected_pairs
;
389 expected_pairs
["gmsv"] = base::IntToString(kGCMVersion
);
390 expected_pairs
["app"] = kAppId
;
391 expected_pairs
["device"] = base::Uint64ToString(kAndroidId
);
392 expected_pairs
["delete"] = "true";
393 expected_pairs
["appid"] = kInstanceId
;
394 expected_pairs
["sender"] = kDeveloperId
;
395 expected_pairs
["X-subtype"] = kDeveloperId
;
396 expected_pairs
["scope"] = kScope
;
397 expected_pairs
["X-scope"] = kScope
;
399 // Verify data was formatted properly.
400 std::string upload_data
= fetcher
->upload_data();
401 base::StringTokenizer
data_tokenizer(upload_data
, "&=");
402 while (data_tokenizer
.GetNext()) {
403 std::map
<std::string
, std::string
>::iterator iter
=
404 expected_pairs
.find(data_tokenizer
.token());
405 ASSERT_TRUE(iter
!= expected_pairs
.end()) << data_tokenizer
.token();
406 ASSERT_TRUE(data_tokenizer
.GetNext()) << data_tokenizer
.token();
407 EXPECT_EQ(iter
->second
, data_tokenizer
.token());
408 // Ensure that none of the keys appears twice.
409 expected_pairs
.erase(iter
);
412 EXPECT_EQ(0UL, expected_pairs
.size());
415 TEST_F(InstaceIDDeleteTokenRequestTest
, SuccessfulUnregistration
) {
416 CreateRequest(kInstanceId
, kDeveloperId
, kScope
);
419 SetResponse(net::HTTP_OK
, kDeletedToken
);
422 EXPECT_TRUE(callback_called_
);
423 EXPECT_EQ(UnregistrationRequest::SUCCESS
, status_
);
426 TEST_F(InstaceIDDeleteTokenRequestTest
, ResponseHttpStatusNotOK
) {
427 CreateRequest(kInstanceId
, kDeveloperId
, kScope
);
430 SetResponse(net::HTTP_UNAUTHORIZED
, "");
433 EXPECT_FALSE(callback_called_
);
435 SetResponse(net::HTTP_OK
, kDeletedToken
);
438 EXPECT_TRUE(callback_called_
);
439 EXPECT_EQ(UnregistrationRequest::SUCCESS
, status_
);
442 TEST_F(InstaceIDDeleteTokenRequestTest
, InvalidParametersError
) {
443 CreateRequest(kInstanceId
, kDeveloperId
, kScope
);
446 SetResponse(net::HTTP_OK
, "Error=INVALID_PARAMETERS");
449 EXPECT_TRUE(callback_called_
);
450 EXPECT_EQ(UnregistrationRequest::INVALID_PARAMETERS
, status_
);
453 TEST_F(InstaceIDDeleteTokenRequestTest
, UnkwnownError
) {
454 CreateRequest(kInstanceId
, kDeveloperId
, kScope
);
457 SetResponse(net::HTTP_OK
, "Error=XXX");
460 EXPECT_TRUE(callback_called_
);
461 EXPECT_EQ(UnregistrationRequest::UNKNOWN_ERROR
, status_
);