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