Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / google_apis / gcm / engine / unregistration_request_unittest.cc
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 <map>
6 #include <string>
7 #include <vector>
8
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/string_tokenizer.h"
11 #include "google_apis/gcm/engine/unregistration_request.h"
12 #include "google_apis/gcm/monitoring/fake_gcm_stats_recorder.h"
13 #include "net/url_request/test_url_fetcher_factory.h"
14 #include "net/url_request/url_request_test_util.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 namespace gcm {
18
19 namespace {
20 const uint64 kAndroidId = 42UL;
21 const char kLoginHeader[] = "AidLogin";
22 const char kAppId[] = "TestAppId";
23 const char kDeletedAppId[] = "deleted=TestAppId";
24 const char kRegistrationURL[] = "http://foo.bar/register";
25 const uint64 kSecurityToken = 77UL;
26
27 // Backoff policy for testing registration request.
28 const net::BackoffEntry::Policy kDefaultBackoffPolicy = {
29   // Number of initial errors (in sequence) to ignore before applying
30   // exponential back-off rules.
31   // Explicitly set to 2 to skip the delay on the first retry, as we are not
32   // trying to test the backoff itself, but rather the fact that retry happens.
33   1,
34
35   // Initial delay for exponential back-off in ms.
36   15000,  // 15 seconds.
37
38   // Factor by which the waiting time will be multiplied.
39   2,
40
41   // Fuzzing percentage. ex: 10% will spread requests randomly
42   // between 90%-100% of the calculated time.
43   0.5,  // 50%.
44
45   // Maximum amount of time we are willing to delay our request in ms.
46   1000 * 60 * 5, // 5 minutes.
47
48   // Time to keep an entry from being discarded even when it
49   // has no significant state, -1 to never discard.
50   -1,
51
52   // Don't use initial delay unless the last request was an error.
53   false,
54 };
55 }  // namespace
56
57 class UnregistrationRequestTest : public testing::Test {
58  public:
59   UnregistrationRequestTest();
60   virtual ~UnregistrationRequestTest();
61
62   void UnregistrationCallback(UnregistrationRequest::Status status);
63
64   void CreateRequest();
65   void SetResponseStatusAndString(net::HttpStatusCode status_code,
66                                   const std::string& response_body);
67   void CompleteFetch();
68
69  protected:
70   bool callback_called_;
71   UnregistrationRequest::Status status_;
72   scoped_ptr<UnregistrationRequest> request_;
73   base::MessageLoop message_loop_;
74   net::TestURLFetcherFactory url_fetcher_factory_;
75   scoped_refptr<net::TestURLRequestContextGetter> url_request_context_getter_;
76   FakeGCMStatsRecorder recorder_;
77 };
78
79 UnregistrationRequestTest::UnregistrationRequestTest()
80     : callback_called_(false),
81       status_(UnregistrationRequest::UNREGISTRATION_STATUS_COUNT),
82       url_request_context_getter_(new net::TestURLRequestContextGetter(
83           message_loop_.message_loop_proxy())) {}
84
85 UnregistrationRequestTest::~UnregistrationRequestTest() {}
86
87 void UnregistrationRequestTest::UnregistrationCallback(
88     UnregistrationRequest::Status status) {
89   callback_called_ = true;
90   status_ = status;
91 }
92
93 void UnregistrationRequestTest::CreateRequest() {
94   request_.reset(new UnregistrationRequest(
95       GURL(kRegistrationURL),
96       UnregistrationRequest::RequestInfo(kAndroidId,
97                                          kSecurityToken,
98                                          kAppId),
99       kDefaultBackoffPolicy,
100       base::Bind(&UnregistrationRequestTest::UnregistrationCallback,
101                  base::Unretained(this)),
102       url_request_context_getter_.get(),
103       &recorder_));
104 }
105
106 void UnregistrationRequestTest::SetResponseStatusAndString(
107     net::HttpStatusCode status_code,
108     const std::string& response_body) {
109   net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
110   ASSERT_TRUE(fetcher);
111   fetcher->set_response_code(status_code);
112   fetcher->SetResponseString(response_body);
113 }
114
115 void UnregistrationRequestTest::CompleteFetch() {
116   status_ = UnregistrationRequest::UNREGISTRATION_STATUS_COUNT;
117   callback_called_ = false;
118   net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
119   ASSERT_TRUE(fetcher);
120   fetcher->delegate()->OnURLFetchComplete(fetcher);
121 }
122
123 TEST_F(UnregistrationRequestTest, RequestDataPassedToFetcher) {
124   CreateRequest();
125   request_->Start();
126
127   // Get data sent by request.
128   net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
129   ASSERT_TRUE(fetcher);
130
131   EXPECT_EQ(GURL(kRegistrationURL), fetcher->GetOriginalURL());
132
133   // Verify that authorization header was put together properly.
134   net::HttpRequestHeaders headers;
135   fetcher->GetExtraRequestHeaders(&headers);
136   std::string auth_header;
137   headers.GetHeader(net::HttpRequestHeaders::kAuthorization, &auth_header);
138   base::StringTokenizer auth_tokenizer(auth_header, " :");
139   ASSERT_TRUE(auth_tokenizer.GetNext());
140   EXPECT_EQ(kLoginHeader, auth_tokenizer.token());
141   ASSERT_TRUE(auth_tokenizer.GetNext());
142   EXPECT_EQ(base::Uint64ToString(kAndroidId), auth_tokenizer.token());
143   ASSERT_TRUE(auth_tokenizer.GetNext());
144   EXPECT_EQ(base::Uint64ToString(kSecurityToken), auth_tokenizer.token());
145   std::string app_id_header;
146   headers.GetHeader("app", &app_id_header);
147   EXPECT_EQ(kAppId, app_id_header);
148
149   std::map<std::string, std::string> expected_pairs;
150   expected_pairs["app"] = kAppId;
151   expected_pairs["device"] = base::Uint64ToString(kAndroidId);
152   expected_pairs["delete"] = "true";
153   expected_pairs["gcm_unreg_caller"] = "false";
154
155   // Verify data was formatted properly.
156   std::string upload_data = fetcher->upload_data();
157   base::StringTokenizer data_tokenizer(upload_data, "&=");
158   while (data_tokenizer.GetNext()) {
159     std::map<std::string, std::string>::iterator iter =
160         expected_pairs.find(data_tokenizer.token());
161     ASSERT_TRUE(iter != expected_pairs.end()) << data_tokenizer.token();
162     ASSERT_TRUE(data_tokenizer.GetNext()) << data_tokenizer.token();
163     EXPECT_EQ(iter->second, data_tokenizer.token());
164     // Ensure that none of the keys appears twice.
165     expected_pairs.erase(iter);
166   }
167
168   EXPECT_EQ(0UL, expected_pairs.size());
169 }
170
171 TEST_F(UnregistrationRequestTest, SuccessfulUnregistration) {
172   CreateRequest();
173   request_->Start();
174
175   SetResponseStatusAndString(net::HTTP_OK, kDeletedAppId);
176   CompleteFetch();
177
178   EXPECT_TRUE(callback_called_);
179   EXPECT_EQ(UnregistrationRequest::SUCCESS, status_);
180 }
181
182 TEST_F(UnregistrationRequestTest, ResponseHttpStatusNotOK) {
183   CreateRequest();
184   request_->Start();
185
186   SetResponseStatusAndString(net::HTTP_UNAUTHORIZED, "");
187   CompleteFetch();
188
189   EXPECT_TRUE(callback_called_);
190   EXPECT_EQ(UnregistrationRequest::HTTP_NOT_OK, status_);
191 }
192
193 TEST_F(UnregistrationRequestTest, ResponseEmpty) {
194   CreateRequest();
195   request_->Start();
196
197   SetResponseStatusAndString(net::HTTP_OK, "");
198   CompleteFetch();
199
200   EXPECT_FALSE(callback_called_);
201
202   SetResponseStatusAndString(net::HTTP_OK, kDeletedAppId);
203   CompleteFetch();
204
205   EXPECT_TRUE(callback_called_);
206   EXPECT_EQ(UnregistrationRequest::SUCCESS, status_);
207 }
208
209 TEST_F(UnregistrationRequestTest, InvalidParametersError) {
210   CreateRequest();
211   request_->Start();
212
213   SetResponseStatusAndString(net::HTTP_OK, "Error=INVALID_PARAMETERS");
214   CompleteFetch();
215
216   EXPECT_TRUE(callback_called_);
217   EXPECT_EQ(UnregistrationRequest::INVALID_PARAMETERS, status_);
218 }
219
220 TEST_F(UnregistrationRequestTest, UnkwnownError) {
221   CreateRequest();
222   request_->Start();
223
224   SetResponseStatusAndString(net::HTTP_OK, "Error=XXX");
225   CompleteFetch();
226
227   EXPECT_TRUE(callback_called_);
228   EXPECT_EQ(UnregistrationRequest::UNKNOWN_ERROR, status_);
229 }
230
231 TEST_F(UnregistrationRequestTest, ServiceUnavailable) {
232   CreateRequest();
233   request_->Start();
234
235   SetResponseStatusAndString(net::HTTP_SERVICE_UNAVAILABLE, "");
236   CompleteFetch();
237
238   EXPECT_FALSE(callback_called_);
239
240   SetResponseStatusAndString(net::HTTP_OK, kDeletedAppId);
241   CompleteFetch();
242
243   EXPECT_TRUE(callback_called_);
244   EXPECT_EQ(UnregistrationRequest::SUCCESS, status_);
245 }
246
247 TEST_F(UnregistrationRequestTest, InternalServerError) {
248   CreateRequest();
249   request_->Start();
250
251   SetResponseStatusAndString(net::HTTP_INTERNAL_SERVER_ERROR, "");
252   CompleteFetch();
253
254   EXPECT_FALSE(callback_called_);
255
256   SetResponseStatusAndString(net::HTTP_OK, kDeletedAppId);
257   CompleteFetch();
258
259   EXPECT_TRUE(callback_called_);
260   EXPECT_EQ(UnregistrationRequest::SUCCESS, status_);
261 }
262
263 TEST_F(UnregistrationRequestTest, IncorrectAppId) {
264   CreateRequest();
265   request_->Start();
266
267   SetResponseStatusAndString(net::HTTP_OK, "deleted=OtherTestAppId");
268   CompleteFetch();
269
270   EXPECT_FALSE(callback_called_);
271
272   SetResponseStatusAndString(net::HTTP_OK, kDeletedAppId);
273   CompleteFetch();
274
275   EXPECT_TRUE(callback_called_);
276   EXPECT_EQ(UnregistrationRequest::SUCCESS, status_);
277 }
278
279 TEST_F(UnregistrationRequestTest, ResponseParsingFailed) {
280   CreateRequest();
281   request_->Start();
282
283   SetResponseStatusAndString(net::HTTP_OK, "some malformed response");
284   CompleteFetch();
285
286   EXPECT_FALSE(callback_called_);
287
288   SetResponseStatusAndString(net::HTTP_OK, kDeletedAppId);
289   CompleteFetch();
290
291   EXPECT_TRUE(callback_called_);
292   EXPECT_EQ(UnregistrationRequest::SUCCESS, status_);
293 }
294
295 }  // namespace gcm