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.
4
5 #include <stdint.h>
6 #include <map>
7 #include <string>
8 #include <utility>
9 #include <vector>
10
11 #include "base/bind.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/string_tokenizer.h"
14 #include "base/threading/thread_task_runner_handle.h"
15 #include "google_apis/gcm/engine/gcm_registration_request_handler.h"
16 #include "google_apis/gcm/engine/gcm_request_test_base.h"
17 #include "google_apis/gcm/engine/instance_id_get_token_request_handler.h"
18 #include "google_apis/gcm/monitoring/fake_gcm_stats_recorder.h"
19 #include "net/base/escape.h"
20 #include "net/base/load_flags.h"
21 #include "net/base/net_errors.h"
22 #include "services/network/public/cpp/shared_url_loader_factory.h"
23
24 namespace gcm {
25
26 namespace {
27 const uint64_t kAndroidId = 42UL;
28 const char kAppId[] = "TestAppId";
29 const char kProductCategoryForSubtypes[] = "com.chrome.macosx";
30 const char kDeveloperId[] = "Project1";
31 const char kLoginHeader[] = "AidLogin";
32 const char kRegistrationURL[] = "http://foo.bar/register";
33 const uint64_t kSecurityToken = 77UL;
34 const int kGCMVersion = 40;
35 const char kInstanceId[] = "IID1";
36 const char kScope[] = "GCM";
37
38 } // namespace
39
40 class RegistrationRequestTest : public GCMRequestTestBase {
41 public:
42 RegistrationRequestTest();
43 ~RegistrationRequestTest() override;
44
45 void RegistrationCallback(RegistrationRequest::Status status,
46 const std::string& registration_id);
47
48 void OnAboutToCompleteFetch() override;
49
set_max_retry_count(int max_retry_count)50 void set_max_retry_count(int max_retry_count) {
51 max_retry_count_ = max_retry_count;
52 }
53
54 protected:
55 int max_retry_count_;
56 RegistrationRequest::Status status_;
57 std::string registration_id_;
58 bool callback_called_;
59 std::map<std::string, std::string> extras_;
60 std::unique_ptr<RegistrationRequest> request_;
61 FakeGCMStatsRecorder recorder_;
62 };
63
RegistrationRequestTest()64 RegistrationRequestTest::RegistrationRequestTest()
65 : max_retry_count_(2),
66 status_(RegistrationRequest::SUCCESS),
67 callback_called_(false) {}
68
~RegistrationRequestTest()69 RegistrationRequestTest::~RegistrationRequestTest() {}
70
RegistrationCallback(RegistrationRequest::Status status,const std::string & registration_id)71 void RegistrationRequestTest::RegistrationCallback(
72 RegistrationRequest::Status status,
73 const std::string& registration_id) {
74 status_ = status;
75 registration_id_ = registration_id;
76 callback_called_ = true;
77 }
78
OnAboutToCompleteFetch()79 void RegistrationRequestTest::OnAboutToCompleteFetch() {
80 registration_id_.clear();
81 status_ = RegistrationRequest::SUCCESS;
82 callback_called_ = false;
83 }
84
85 class GCMRegistrationRequestTest : public RegistrationRequestTest {
86 public:
87 GCMRegistrationRequestTest();
88 ~GCMRegistrationRequestTest() override;
89
90 void CreateRequest(const std::string& sender_ids);
91 };
92
GCMRegistrationRequestTest()93 GCMRegistrationRequestTest::GCMRegistrationRequestTest() {
94 }
95
~GCMRegistrationRequestTest()96 GCMRegistrationRequestTest::~GCMRegistrationRequestTest() {
97 }
98
CreateRequest(const std::string & sender_ids)99 void GCMRegistrationRequestTest::CreateRequest(const std::string& sender_ids) {
100 RegistrationRequest::RequestInfo request_info(kAndroidId, kSecurityToken,
101 kAppId /* category */,
102 std::string() /* subtype */);
103 std::unique_ptr<GCMRegistrationRequestHandler> request_handler(
104 new GCMRegistrationRequestHandler(sender_ids));
105 request_.reset(new RegistrationRequest(
106 GURL(kRegistrationURL), request_info, std::move(request_handler),
107 GetBackoffPolicy(),
108 base::BindOnce(&RegistrationRequestTest::RegistrationCallback,
109 base::Unretained(this)),
110 max_retry_count_, url_loader_factory(),
111 base::ThreadTaskRunnerHandle::Get(), &recorder_, sender_ids));
112 }
113
TEST_F(GCMRegistrationRequestTest,RequestSuccessful)114 TEST_F(GCMRegistrationRequestTest, RequestSuccessful) {
115 set_max_retry_count(0);
116 CreateRequest("sender1,sender2");
117 request_->Start();
118
119 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_OK, "token=2501");
120 EXPECT_TRUE(callback_called_);
121 EXPECT_EQ(RegistrationRequest::SUCCESS, status_);
122 EXPECT_EQ("2501", registration_id_);
123 }
124
TEST_F(GCMRegistrationRequestTest,RequestDataAndURL)125 TEST_F(GCMRegistrationRequestTest, RequestDataAndURL) {
126 CreateRequest(kDeveloperId);
127 request_->Start();
128
129 // Get data sent by request and verify that authorization header was put
130 // together properly.
131 const net::HttpRequestHeaders* headers =
132 GetExtraHeadersForURL(kRegistrationURL);
133 ASSERT_TRUE(headers != nullptr);
134 std::string auth_header;
135 headers->GetHeader(net::HttpRequestHeaders::kAuthorization, &auth_header);
136 base::StringTokenizer auth_tokenizer(auth_header, " :");
137 ASSERT_TRUE(auth_tokenizer.GetNext());
138 EXPECT_EQ(kLoginHeader, auth_tokenizer.token());
139 ASSERT_TRUE(auth_tokenizer.GetNext());
140 EXPECT_EQ(base::NumberToString(kAndroidId), auth_tokenizer.token());
141 ASSERT_TRUE(auth_tokenizer.GetNext());
142 EXPECT_EQ(base::NumberToString(kSecurityToken), auth_tokenizer.token());
143
144 std::map<std::string, std::string> expected_pairs;
145 expected_pairs["app"] = kAppId;
146 expected_pairs["sender"] = kDeveloperId;
147 expected_pairs["device"] = base::NumberToString(kAndroidId);
148
149 ASSERT_NO_FATAL_FAILURE(
150 VerifyFetcherUploadDataForURL(kRegistrationURL, &expected_pairs));
151 }
152
TEST_F(GCMRegistrationRequestTest,RequestRegistrationWithMultipleSenderIds)153 TEST_F(GCMRegistrationRequestTest, RequestRegistrationWithMultipleSenderIds) {
154 CreateRequest("sender1,sender2@gmail.com");
155 request_->Start();
156
157
158 // Verify data was formatted properly.
159 std::string upload_data;
160 ASSERT_TRUE(GetUploadDataForURL(kRegistrationURL, &upload_data));
161 base::StringTokenizer data_tokenizer(upload_data, "&=");
162
163 // Skip all tokens until you hit entry for senders.
164 while (data_tokenizer.GetNext() && data_tokenizer.token() != "sender")
165 continue;
166
167 ASSERT_TRUE(data_tokenizer.GetNext());
168 std::string senders(net::UnescapeBinaryURLComponent(data_tokenizer.token()));
169 base::StringTokenizer sender_tokenizer(senders, ",");
170 ASSERT_TRUE(sender_tokenizer.GetNext());
171 EXPECT_EQ("sender1", sender_tokenizer.token());
172 ASSERT_TRUE(sender_tokenizer.GetNext());
173 EXPECT_EQ("sender2@gmail.com", sender_tokenizer.token());
174 }
175
TEST_F(GCMRegistrationRequestTest,ResponseParsing)176 TEST_F(GCMRegistrationRequestTest, ResponseParsing) {
177 CreateRequest("sender1,sender2");
178 request_->Start();
179
180 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_OK, "token=2501");
181 EXPECT_TRUE(callback_called_);
182 EXPECT_EQ(RegistrationRequest::SUCCESS, status_);
183 EXPECT_EQ("2501", registration_id_);
184 }
185
TEST_F(GCMRegistrationRequestTest,ResponseParsingFailed)186 TEST_F(GCMRegistrationRequestTest, ResponseParsingFailed) {
187 CreateRequest("sender1,sender2");
188 request_->Start();
189
190 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_OK,
191 "tok"); // Simulate truncated message.
192 EXPECT_FALSE(callback_called_);
193
194 // Ensuring a retry happened and succeeds.
195 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_OK, "token=2501");
196 EXPECT_TRUE(callback_called_);
197 EXPECT_EQ(RegistrationRequest::SUCCESS, status_);
198 EXPECT_EQ("2501", registration_id_);
199 }
200
TEST_F(GCMRegistrationRequestTest,ResponseHttpStatusNotOK)201 TEST_F(GCMRegistrationRequestTest, ResponseHttpStatusNotOK) {
202 CreateRequest("sender1,sender2");
203 request_->Start();
204
205 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_UNAUTHORIZED,
206 "token=2501");
207 EXPECT_FALSE(callback_called_);
208
209 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_OK, "token=2501");
210 EXPECT_TRUE(callback_called_);
211 EXPECT_EQ(RegistrationRequest::SUCCESS, status_);
212 EXPECT_EQ("2501", registration_id_);
213 }
214
TEST_F(GCMRegistrationRequestTest,ResponseMissingRegistrationId)215 TEST_F(GCMRegistrationRequestTest, ResponseMissingRegistrationId) {
216 CreateRequest("sender1,sender2");
217 request_->Start();
218
219 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_OK, "");
220 EXPECT_FALSE(callback_called_);
221
222 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_OK,
223 "some error in response");
224 EXPECT_FALSE(callback_called_);
225
226 // Ensuring a retry happened and succeeds.
227 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_OK, "token=2501");
228 EXPECT_TRUE(callback_called_);
229 EXPECT_EQ(RegistrationRequest::SUCCESS, status_);
230 EXPECT_EQ("2501", registration_id_);
231 }
232
TEST_F(GCMRegistrationRequestTest,ResponseDeviceRegistrationError)233 TEST_F(GCMRegistrationRequestTest, ResponseDeviceRegistrationError) {
234 CreateRequest("sender1,sender2");
235 request_->Start();
236
237 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_OK,
238 "Error=PHONE_REGISTRATION_ERROR");
239 EXPECT_FALSE(callback_called_);
240
241 // Ensuring a retry happened and succeeds.
242 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_OK, "token=2501");
243 EXPECT_TRUE(callback_called_);
244 EXPECT_EQ(RegistrationRequest::SUCCESS, status_);
245 EXPECT_EQ("2501", registration_id_);
246 }
247
TEST_F(GCMRegistrationRequestTest,ResponseAuthenticationError)248 TEST_F(GCMRegistrationRequestTest, ResponseAuthenticationError) {
249 CreateRequest("sender1,sender2");
250 request_->Start();
251
252 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_UNAUTHORIZED,
253 "Error=AUTHENTICATION_FAILED");
254 EXPECT_FALSE(callback_called_);
255
256 // Ensuring a retry happened and succeeds.
257 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_OK, "token=2501");
258 EXPECT_TRUE(callback_called_);
259 EXPECT_EQ(RegistrationRequest::SUCCESS, status_);
260 EXPECT_EQ("2501", registration_id_);
261 }
262
TEST_F(GCMRegistrationRequestTest,ResponseInternalServerError)263 TEST_F(GCMRegistrationRequestTest, ResponseInternalServerError) {
264 CreateRequest("sender1,sender2");
265 request_->Start();
266
267 SetResponseForURLAndComplete(kRegistrationURL,
268 net::HTTP_INTERNAL_SERVER_ERROR,
269 "Error=InternalServerError");
270 EXPECT_FALSE(callback_called_);
271
272 // Ensuring a retry happened and succeeds.
273 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_OK, "token=2501");
274 EXPECT_TRUE(callback_called_);
275 EXPECT_EQ(RegistrationRequest::SUCCESS, status_);
276 EXPECT_EQ("2501", registration_id_);
277 }
278
TEST_F(GCMRegistrationRequestTest,ResponseInvalidParameters)279 TEST_F(GCMRegistrationRequestTest, ResponseInvalidParameters) {
280 CreateRequest("sender1,sender2");
281 request_->Start();
282
283 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_OK,
284 "Error=INVALID_PARAMETERS");
285 EXPECT_TRUE(callback_called_);
286 EXPECT_EQ(RegistrationRequest::INVALID_PARAMETERS, status_);
287 EXPECT_EQ(std::string(), registration_id_);
288 }
289
TEST_F(GCMRegistrationRequestTest,ResponseInvalidSender)290 TEST_F(GCMRegistrationRequestTest, ResponseInvalidSender) {
291 CreateRequest("sender1,sender2");
292 request_->Start();
293
294 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_OK,
295 "Error=INVALID_SENDER");
296 EXPECT_TRUE(callback_called_);
297 EXPECT_EQ(RegistrationRequest::INVALID_SENDER, status_);
298 EXPECT_EQ(std::string(), registration_id_);
299 }
300
TEST_F(GCMRegistrationRequestTest,ResponseInvalidSenderBadRequest)301 TEST_F(GCMRegistrationRequestTest, ResponseInvalidSenderBadRequest) {
302 CreateRequest("sender1");
303 request_->Start();
304
305 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_BAD_REQUEST,
306 "Error=INVALID_SENDER");
307 EXPECT_TRUE(callback_called_);
308 EXPECT_EQ(RegistrationRequest::INVALID_SENDER, status_);
309 EXPECT_EQ(std::string(), registration_id_);
310 }
311
TEST_F(GCMRegistrationRequestTest,ResponseQuotaExceeded)312 TEST_F(GCMRegistrationRequestTest, ResponseQuotaExceeded) {
313 CreateRequest("sender1");
314 request_->Start();
315
316 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_SERVICE_UNAVAILABLE,
317 "Error=QUOTA_EXCEEDED");
318 EXPECT_TRUE(callback_called_);
319 EXPECT_EQ(RegistrationRequest::QUOTA_EXCEEDED, status_);
320 EXPECT_EQ(std::string(), registration_id_);
321 }
322
TEST_F(GCMRegistrationRequestTest,ResponseTooManyRegistrations)323 TEST_F(GCMRegistrationRequestTest, ResponseTooManyRegistrations) {
324 CreateRequest("sender1");
325 request_->Start();
326
327 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_OK,
328 "Error=TOO_MANY_REGISTRATIONS");
329 EXPECT_TRUE(callback_called_);
330 EXPECT_EQ(RegistrationRequest::TOO_MANY_REGISTRATIONS, status_);
331 EXPECT_EQ(std::string(), registration_id_);
332 }
333
TEST_F(GCMRegistrationRequestTest,RequestNotSuccessful)334 TEST_F(GCMRegistrationRequestTest, RequestNotSuccessful) {
335 CreateRequest("sender1,sender2");
336 request_->Start();
337
338 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_OK, "token=2501",
339 net::ERR_FAILED);
340 EXPECT_FALSE(callback_called_);
341
342 // Ensuring a retry happened and succeeded.
343 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_OK, "token=2501");
344
345 EXPECT_TRUE(callback_called_);
346 EXPECT_EQ(RegistrationRequest::SUCCESS, status_);
347 EXPECT_EQ("2501", registration_id_);
348 }
349
TEST_F(GCMRegistrationRequestTest,ResponseHttpNotOk)350 TEST_F(GCMRegistrationRequestTest, ResponseHttpNotOk) {
351 CreateRequest("sender1,sender2");
352 request_->Start();
353
354 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_GATEWAY_TIMEOUT,
355 "token=2501");
356 EXPECT_FALSE(callback_called_);
357
358 // Ensuring a retry happened and succeeded.
359 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_OK, "token=2501");
360
361 EXPECT_TRUE(callback_called_);
362 EXPECT_EQ(RegistrationRequest::SUCCESS, status_);
363 EXPECT_EQ("2501", registration_id_);
364 }
365
TEST_F(GCMRegistrationRequestTest,MaximumAttemptsReachedWithZeroRetries)366 TEST_F(GCMRegistrationRequestTest, MaximumAttemptsReachedWithZeroRetries) {
367 set_max_retry_count(0);
368 CreateRequest("sender1,sender2");
369 request_->Start();
370
371 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_GATEWAY_TIMEOUT,
372 "token=2501");
373
374 EXPECT_TRUE(callback_called_);
375 EXPECT_EQ(RegistrationRequest::REACHED_MAX_RETRIES, status_);
376 EXPECT_EQ(std::string(), registration_id_);
377 }
378
TEST_F(GCMRegistrationRequestTest,MaximumAttemptsReached)379 TEST_F(GCMRegistrationRequestTest, MaximumAttemptsReached) {
380 CreateRequest("sender1,sender2");
381 request_->Start();
382
383 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_GATEWAY_TIMEOUT,
384 "token=2501");
385 EXPECT_FALSE(callback_called_);
386
387 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_GATEWAY_TIMEOUT,
388 "token=2501");
389 EXPECT_FALSE(callback_called_);
390
391 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_GATEWAY_TIMEOUT,
392 "token=2501");
393 EXPECT_TRUE(callback_called_);
394 EXPECT_EQ(RegistrationRequest::REACHED_MAX_RETRIES, status_);
395 EXPECT_EQ(std::string(), registration_id_);
396 }
397
398 class InstanceIDGetTokenRequestTest : public RegistrationRequestTest {
399 public:
400 InstanceIDGetTokenRequestTest();
401 ~InstanceIDGetTokenRequestTest() override;
402
403 void CreateRequest(bool use_subtype,
404 const std::string& instance_id,
405 const std::string& authorized_entity,
406 const std::string& scope,
407 base::TimeDelta time_to_live,
408 const std::map<std::string, std::string>& options);
409 };
410
InstanceIDGetTokenRequestTest()411 InstanceIDGetTokenRequestTest::InstanceIDGetTokenRequestTest() {
412 }
413
~InstanceIDGetTokenRequestTest()414 InstanceIDGetTokenRequestTest::~InstanceIDGetTokenRequestTest() {
415 }
416
CreateRequest(bool use_subtype,const std::string & instance_id,const std::string & authorized_entity,const std::string & scope,base::TimeDelta time_to_live,const std::map<std::string,std::string> & options)417 void InstanceIDGetTokenRequestTest::CreateRequest(
418 bool use_subtype,
419 const std::string& instance_id,
420 const std::string& authorized_entity,
421 const std::string& scope,
422 base::TimeDelta time_to_live,
423 const std::map<std::string, std::string>& options) {
424 std::string category = use_subtype ? kProductCategoryForSubtypes : kAppId;
425 std::string subtype = use_subtype ? kAppId : std::string();
426 RegistrationRequest::RequestInfo request_info(kAndroidId, kSecurityToken,
427 category, subtype);
428 std::unique_ptr<InstanceIDGetTokenRequestHandler> request_handler(
429 new InstanceIDGetTokenRequestHandler(instance_id, authorized_entity,
430 scope, kGCMVersion, time_to_live,
431 options));
432 request_.reset(new RegistrationRequest(
433 GURL(kRegistrationURL), request_info, std::move(request_handler),
434 GetBackoffPolicy(),
435 base::BindOnce(&RegistrationRequestTest::RegistrationCallback,
436 base::Unretained(this)),
437 max_retry_count_, url_loader_factory(),
438 base::ThreadTaskRunnerHandle::Get(), &recorder_, authorized_entity));
439 }
440
TEST_F(InstanceIDGetTokenRequestTest,RequestSuccessful)441 TEST_F(InstanceIDGetTokenRequestTest, RequestSuccessful) {
442 std::map<std::string, std::string> options;
443 options["Foo"] = "Bar";
444
445 set_max_retry_count(0);
446 CreateRequest(false /* use_subtype */, kInstanceId, kDeveloperId, kScope,
447 /*time_to_live=*/base::TimeDelta(), options);
448 request_->Start();
449
450 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_OK, "token=2501");
451 EXPECT_TRUE(callback_called_);
452 EXPECT_EQ(RegistrationRequest::SUCCESS, status_);
453 EXPECT_EQ("2501", registration_id_);
454 }
455
TEST_F(InstanceIDGetTokenRequestTest,RequestDataAndURL)456 TEST_F(InstanceIDGetTokenRequestTest, RequestDataAndURL) {
457 std::map<std::string, std::string> options;
458 options["Foo"] = "Bar";
459 CreateRequest(false /* use_subtype */, kInstanceId, kDeveloperId, kScope,
460 /*time_to_live=*/base::TimeDelta(), options);
461 request_->Start();
462
463 // Verify that the no-cookie flag is set.
464 const network::ResourceRequest* pending_request;
465 ASSERT_TRUE(
466 test_url_loader_factory()->IsPending(kRegistrationURL, &pending_request));
467 EXPECT_EQ(network::mojom::CredentialsMode::kOmit,
468 pending_request->credentials_mode);
469
470 // Verify that authorization header was put together properly.
471 const net::HttpRequestHeaders* headers =
472 GetExtraHeadersForURL(kRegistrationURL);
473 ASSERT_TRUE(headers != nullptr);
474 std::string auth_header;
475 headers->GetHeader(net::HttpRequestHeaders::kAuthorization, &auth_header);
476 base::StringTokenizer auth_tokenizer(auth_header, " :");
477 ASSERT_TRUE(auth_tokenizer.GetNext());
478 EXPECT_EQ(kLoginHeader, auth_tokenizer.token());
479 ASSERT_TRUE(auth_tokenizer.GetNext());
480 EXPECT_EQ(base::NumberToString(kAndroidId), auth_tokenizer.token());
481 ASSERT_TRUE(auth_tokenizer.GetNext());
482 EXPECT_EQ(base::NumberToString(kSecurityToken), auth_tokenizer.token());
483
484 std::map<std::string, std::string> expected_pairs;
485 expected_pairs["gmsv"] = base::NumberToString(kGCMVersion);
486 expected_pairs["app"] = kAppId;
487 expected_pairs["sender"] = kDeveloperId;
488 expected_pairs["device"] = base::NumberToString(kAndroidId);
489 expected_pairs["appid"] = kInstanceId;
490 expected_pairs["scope"] = kScope;
491 expected_pairs["X-scope"] = kScope;
492 expected_pairs["X-Foo"] = "Bar";
493
494 ASSERT_NO_FATAL_FAILURE(
495 VerifyFetcherUploadDataForURL(kRegistrationURL, &expected_pairs));
496 }
497
TEST_F(InstanceIDGetTokenRequestTest,RequestDataWithTTL)498 TEST_F(InstanceIDGetTokenRequestTest, RequestDataWithTTL) {
499 CreateRequest(false, kInstanceId, kDeveloperId, kScope,
500 /*time_to_live=*/base::TimeDelta::FromSeconds(100),
501 /*options=*/{});
502 request_->Start();
503
504 // Same as RequestDataAndURL except "ttl" and "X-Foo".
505 std::map<std::string, std::string> expected_pairs;
506 expected_pairs["gmsv"] = base::NumberToString(kGCMVersion);
507 expected_pairs["app"] = kAppId;
508 expected_pairs["sender"] = kDeveloperId;
509 expected_pairs["device"] = base::NumberToString(kAndroidId);
510 expected_pairs["appid"] = kInstanceId;
511 expected_pairs["scope"] = kScope;
512 expected_pairs["ttl"] = "100";
513 expected_pairs["X-scope"] = kScope;
514
515 ASSERT_NO_FATAL_FAILURE(
516 VerifyFetcherUploadDataForURL(kRegistrationURL, &expected_pairs));
517 }
518
TEST_F(InstanceIDGetTokenRequestTest,RequestDataWithSubtype)519 TEST_F(InstanceIDGetTokenRequestTest, RequestDataWithSubtype) {
520 std::map<std::string, std::string> options;
521 options["Foo"] = "Bar";
522 CreateRequest(true /* use_subtype */, kInstanceId, kDeveloperId, kScope,
523 /*time_to_live=*/base::TimeDelta(), options);
524 request_->Start();
525
526 // Same as RequestDataAndURL except "app" and "X-subtype".
527 std::map<std::string, std::string> expected_pairs;
528 expected_pairs["gmsv"] = base::NumberToString(kGCMVersion);
529 expected_pairs["app"] = kProductCategoryForSubtypes;
530 expected_pairs["X-subtype"] = kAppId;
531 expected_pairs["sender"] = kDeveloperId;
532 expected_pairs["device"] = base::NumberToString(kAndroidId);
533 expected_pairs["appid"] = kInstanceId;
534 expected_pairs["scope"] = kScope;
535 expected_pairs["X-scope"] = kScope;
536 expected_pairs["X-Foo"] = "Bar";
537
538 // Verify data was formatted properly.
539 std::string upload_data;
540 ASSERT_TRUE(GetUploadDataForURL(kRegistrationURL, &upload_data));
541 base::StringTokenizer data_tokenizer(upload_data, "&=");
542 while (data_tokenizer.GetNext()) {
543 auto iter = expected_pairs.find(data_tokenizer.token());
544 ASSERT_TRUE(iter != expected_pairs.end());
545 ASSERT_TRUE(data_tokenizer.GetNext());
546 EXPECT_EQ(iter->second, data_tokenizer.token());
547 // Ensure that none of the keys appears twice.
548 expected_pairs.erase(iter);
549 }
550
551 EXPECT_EQ(0UL, expected_pairs.size());
552 }
553
TEST_F(InstanceIDGetTokenRequestTest,ResponseHttpStatusNotOK)554 TEST_F(InstanceIDGetTokenRequestTest, ResponseHttpStatusNotOK) {
555 std::map<std::string, std::string> options;
556 CreateRequest(false /* use_subtype */, kInstanceId, kDeveloperId, kScope,
557 /*time_to_live=*/base::TimeDelta(), options);
558 request_->Start();
559
560 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_UNAUTHORIZED,
561 "token=2501");
562 EXPECT_FALSE(callback_called_);
563
564 SetResponseForURLAndComplete(kRegistrationURL, net::HTTP_OK, "token=2501");
565 EXPECT_TRUE(callback_called_);
566 EXPECT_EQ(RegistrationRequest::SUCCESS, status_);
567 EXPECT_EQ("2501", registration_id_);
568 }
569
570 } // namespace gcm
571