Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / google_apis / gcm / engine / unregistration_request_unittest.cc
blobe6ca23d2d6b4777d6443351e9945984ca8cd564e
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.
5 #include <map>
6 #include <string>
7 #include <vector>
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"
17 namespace gcm {
19 namespace {
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";
33 } // namespace
35 class UnregistrationRequestTest : public GCMRequestTestBase {
36 public:
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;
49 protected:
50 int 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;
67 status_ = status;
70 void UnregistrationRequestTest::CompleteFetch() {
71 status_ = UnregistrationRequest::UNREGISTRATION_STATUS_COUNT;
72 callback_called_ = false;
74 GCMRequestTestBase::CompleteFetch();
77 class GCMUnregistrationRequestTest : public UnregistrationRequestTest {
78 public:
79 GCMUnregistrationRequestTest();
80 ~GCMUnregistrationRequestTest() override;
82 void CreateRequest();
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),
98 request_info,
99 request_handler.Pass(),
100 GetBackoffPolicy(),
101 base::Bind(&UnregistrationRequestTest::UnregistrationCallback,
102 base::Unretained(this)),
103 max_retry_count_,
104 url_request_context_getter(),
105 &recorder_,
106 std::string()));
109 TEST_F(GCMUnregistrationRequestTest, RequestDataPassedToFetcher) {
110 CreateRequest();
111 request_->Start();
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);
163 CreateRequest();
164 request_->Start();
166 SetResponse(net::HTTP_OK, kDeletedAppId);
167 CompleteFetch();
169 EXPECT_TRUE(callback_called_);
170 EXPECT_EQ(UnregistrationRequest::SUCCESS, status_);
173 TEST_F(GCMUnregistrationRequestTest, ResponseHttpStatusNotOK) {
174 CreateRequest();
175 request_->Start();
177 SetResponse(net::HTTP_UNAUTHORIZED, "");
178 CompleteFetch();
180 EXPECT_FALSE(callback_called_);
182 SetResponse(net::HTTP_OK, kDeletedAppId);
183 CompleteFetch();
185 EXPECT_TRUE(callback_called_);
186 EXPECT_EQ(UnregistrationRequest::SUCCESS, status_);
189 TEST_F(GCMUnregistrationRequestTest, ResponseEmpty) {
190 CreateRequest();
191 request_->Start();
193 SetResponse(net::HTTP_OK, "");
194 CompleteFetch();
196 EXPECT_FALSE(callback_called_);
198 SetResponse(net::HTTP_OK, kDeletedAppId);
199 CompleteFetch();
201 EXPECT_TRUE(callback_called_);
202 EXPECT_EQ(UnregistrationRequest::SUCCESS, status_);
205 TEST_F(GCMUnregistrationRequestTest, InvalidParametersError) {
206 CreateRequest();
207 request_->Start();
209 SetResponse(net::HTTP_OK, "Error=INVALID_PARAMETERS");
210 CompleteFetch();
212 EXPECT_TRUE(callback_called_);
213 EXPECT_EQ(UnregistrationRequest::INVALID_PARAMETERS, status_);
216 TEST_F(GCMUnregistrationRequestTest, UnkwnownError) {
217 CreateRequest();
218 request_->Start();
220 SetResponse(net::HTTP_OK, "Error=XXX");
221 CompleteFetch();
223 EXPECT_TRUE(callback_called_);
224 EXPECT_EQ(UnregistrationRequest::UNKNOWN_ERROR, status_);
227 TEST_F(GCMUnregistrationRequestTest, ServiceUnavailable) {
228 CreateRequest();
229 request_->Start();
231 SetResponse(net::HTTP_SERVICE_UNAVAILABLE, "");
232 CompleteFetch();
234 EXPECT_FALSE(callback_called_);
236 SetResponse(net::HTTP_OK, kDeletedAppId);
237 CompleteFetch();
239 EXPECT_TRUE(callback_called_);
240 EXPECT_EQ(UnregistrationRequest::SUCCESS, status_);
243 TEST_F(GCMUnregistrationRequestTest, InternalServerError) {
244 CreateRequest();
245 request_->Start();
247 SetResponse(net::HTTP_INTERNAL_SERVER_ERROR, "");
248 CompleteFetch();
250 EXPECT_FALSE(callback_called_);
252 SetResponse(net::HTTP_OK, kDeletedAppId);
253 CompleteFetch();
255 EXPECT_TRUE(callback_called_);
256 EXPECT_EQ(UnregistrationRequest::SUCCESS, status_);
259 TEST_F(GCMUnregistrationRequestTest, IncorrectAppId) {
260 CreateRequest();
261 request_->Start();
263 SetResponse(net::HTTP_OK, "deleted=OtherTestAppId");
264 CompleteFetch();
266 EXPECT_FALSE(callback_called_);
268 SetResponse(net::HTTP_OK, kDeletedAppId);
269 CompleteFetch();
271 EXPECT_TRUE(callback_called_);
272 EXPECT_EQ(UnregistrationRequest::SUCCESS, status_);
275 TEST_F(GCMUnregistrationRequestTest, ResponseParsingFailed) {
276 CreateRequest();
277 request_->Start();
279 SetResponse(net::HTTP_OK, "some malformed response");
280 CompleteFetch();
282 EXPECT_FALSE(callback_called_);
284 SetResponse(net::HTTP_OK, kDeletedAppId);
285 CompleteFetch();
287 EXPECT_TRUE(callback_called_);
288 EXPECT_EQ(UnregistrationRequest::SUCCESS, status_);
291 TEST_F(GCMUnregistrationRequestTest, MaximumAttemptsReachedWithZeroRetries) {
292 set_max_retry_count(0);
293 CreateRequest();
294 request_->Start();
296 SetResponse(net::HTTP_GATEWAY_TIMEOUT, "bad response");
297 CompleteFetch();
299 EXPECT_TRUE(callback_called_);
300 EXPECT_EQ(UnregistrationRequest::REACHED_MAX_RETRIES, status_);
303 TEST_F(GCMUnregistrationRequestTest, MaximumAttemptsReached) {
304 CreateRequest();
305 request_->Start();
307 SetResponse(net::HTTP_GATEWAY_TIMEOUT, "bad response");
308 CompleteFetch();
310 EXPECT_FALSE(callback_called_);
312 SetResponse(net::HTTP_GATEWAY_TIMEOUT, "bad response");
313 CompleteFetch();
315 EXPECT_FALSE(callback_called_);
317 SetResponse(net::HTTP_GATEWAY_TIMEOUT, "bad response");
318 CompleteFetch();
320 EXPECT_TRUE(callback_called_);
321 EXPECT_EQ(UnregistrationRequest::REACHED_MAX_RETRIES, status_);
324 class InstaceIDDeleteTokenRequestTest : public UnregistrationRequestTest {
325 public:
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),
351 request_info,
352 request_handler.Pass(),
353 GetBackoffPolicy(),
354 base::Bind(&UnregistrationRequestTest::UnregistrationCallback,
355 base::Unretained(this)),
356 max_retry_count(),
357 url_request_context_getter(),
358 &recorder_,
359 std::string()));
362 TEST_F(InstaceIDDeleteTokenRequestTest, RequestDataPassedToFetcher) {
363 CreateRequest(kInstanceId, kDeveloperId, kScope);
364 request_->Start();
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);
417 request_->Start();
419 SetResponse(net::HTTP_OK, kDeletedToken);
420 CompleteFetch();
422 EXPECT_TRUE(callback_called_);
423 EXPECT_EQ(UnregistrationRequest::SUCCESS, status_);
426 TEST_F(InstaceIDDeleteTokenRequestTest, ResponseHttpStatusNotOK) {
427 CreateRequest(kInstanceId, kDeveloperId, kScope);
428 request_->Start();
430 SetResponse(net::HTTP_UNAUTHORIZED, "");
431 CompleteFetch();
433 EXPECT_FALSE(callback_called_);
435 SetResponse(net::HTTP_OK, kDeletedToken);
436 CompleteFetch();
438 EXPECT_TRUE(callback_called_);
439 EXPECT_EQ(UnregistrationRequest::SUCCESS, status_);
442 TEST_F(InstaceIDDeleteTokenRequestTest, InvalidParametersError) {
443 CreateRequest(kInstanceId, kDeveloperId, kScope);
444 request_->Start();
446 SetResponse(net::HTTP_OK, "Error=INVALID_PARAMETERS");
447 CompleteFetch();
449 EXPECT_TRUE(callback_called_);
450 EXPECT_EQ(UnregistrationRequest::INVALID_PARAMETERS, status_);
453 TEST_F(InstaceIDDeleteTokenRequestTest, UnkwnownError) {
454 CreateRequest(kInstanceId, kDeveloperId, kScope);
455 request_->Start();
457 SetResponse(net::HTTP_OK, "Error=XXX");
458 CompleteFetch();
460 EXPECT_TRUE(callback_called_);
461 EXPECT_EQ(UnregistrationRequest::UNKNOWN_ERROR, status_);
464 } // namespace gcm