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