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