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.
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"
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;
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.
33 // Initial delay for exponential back-off in ms.
36 // Factor by which the waiting time will be multiplied.
39 // Fuzzing percentage. ex: 10% will spread requests randomly
40 // between 90%-100% of the calculated time.
43 // Maximum amount of time we are willing to delay our request in ms.
44 1000 * 60 * 5, // 5 minutes.
46 // Time to keep an entry from being discarded even when it
47 // has no significant state, -1 to never discard.
50 // Don't use initial delay unless the last request was an error.
55 class UnregistrationRequestTest : public testing::Test {
57 UnregistrationRequestTest();
58 virtual ~UnregistrationRequestTest();
60 void UnregistrationCallback(UnregistrationRequest::Status status);
63 void SetResponseStatusAndString(net::HttpStatusCode status_code,
64 const std::string& response_body);
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_;
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())) {}
82 UnregistrationRequestTest::~UnregistrationRequestTest() {}
84 void UnregistrationRequestTest::UnregistrationCallback(
85 UnregistrationRequest::Status status) {
86 callback_called_ = true;
90 void UnregistrationRequestTest::CreateRequest() {
91 request_.reset(new UnregistrationRequest(
92 UnregistrationRequest::RequestInfo(kAndroidId,
95 kDefaultBackoffPolicy,
96 base::Bind(&UnregistrationRequestTest::UnregistrationCallback,
97 base::Unretained(this)),
98 url_request_context_getter_.get()));
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);
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);
118 TEST_F(UnregistrationRequestTest, RequestDataPassedToFetcher) {
122 // Get data sent by request.
123 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
124 ASSERT_TRUE(fetcher);
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);
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";
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);
161 EXPECT_EQ(0UL, expected_pairs.size());
164 TEST_F(UnregistrationRequestTest, SuccessfulUnregistration) {
168 SetResponseStatusAndString(net::HTTP_OK, kDeletedAppId);
171 EXPECT_TRUE(callback_called_);
172 EXPECT_EQ(UnregistrationRequest::SUCCESS, status_);
175 TEST_F(UnregistrationRequestTest, ResponseHttpStatusNotOK) {
179 SetResponseStatusAndString(net::HTTP_UNAUTHORIZED, "");
182 EXPECT_TRUE(callback_called_);
183 EXPECT_EQ(UnregistrationRequest::HTTP_NOT_OK, status_);
186 TEST_F(UnregistrationRequestTest, ResponseEmpty) {
190 SetResponseStatusAndString(net::HTTP_OK, "");
193 EXPECT_FALSE(callback_called_);
195 SetResponseStatusAndString(net::HTTP_OK, kDeletedAppId);
198 EXPECT_TRUE(callback_called_);
199 EXPECT_EQ(UnregistrationRequest::SUCCESS, status_);
202 TEST_F(UnregistrationRequestTest, InvalidParametersError) {
206 SetResponseStatusAndString(net::HTTP_OK, "Error=INVALID_PARAMETERS");
209 EXPECT_TRUE(callback_called_);
210 EXPECT_EQ(UnregistrationRequest::INVALID_PARAMETERS, status_);
213 TEST_F(UnregistrationRequestTest, UnkwnownError) {
217 SetResponseStatusAndString(net::HTTP_OK, "Error=XXX");
220 EXPECT_TRUE(callback_called_);
221 EXPECT_EQ(UnregistrationRequest::UNKNOWN_ERROR, status_);
224 TEST_F(UnregistrationRequestTest, ServiceUnavailable) {
228 SetResponseStatusAndString(net::HTTP_SERVICE_UNAVAILABLE, "");
231 EXPECT_FALSE(callback_called_);
233 SetResponseStatusAndString(net::HTTP_OK, kDeletedAppId);
236 EXPECT_TRUE(callback_called_);
237 EXPECT_EQ(UnregistrationRequest::SUCCESS, status_);
240 TEST_F(UnregistrationRequestTest, InternalServerError) {
244 SetResponseStatusAndString(net::HTTP_INTERNAL_SERVER_ERROR, "");
247 EXPECT_FALSE(callback_called_);
249 SetResponseStatusAndString(net::HTTP_OK, kDeletedAppId);
252 EXPECT_TRUE(callback_called_);
253 EXPECT_EQ(UnregistrationRequest::SUCCESS, status_);
256 TEST_F(UnregistrationRequestTest, IncorrectAppId) {
260 SetResponseStatusAndString(net::HTTP_OK, "deleted=OtherTestAppId");
263 EXPECT_FALSE(callback_called_);
265 SetResponseStatusAndString(net::HTTP_OK, kDeletedAppId);
268 EXPECT_TRUE(callback_called_);
269 EXPECT_EQ(UnregistrationRequest::SUCCESS, status_);
272 TEST_F(UnregistrationRequestTest, ResponseParsingFailed) {
276 SetResponseStatusAndString(net::HTTP_OK, "some malformed response");
279 EXPECT_FALSE(callback_called_);
281 SetResponseStatusAndString(net::HTTP_OK, kDeletedAppId);
284 EXPECT_TRUE(callback_called_);
285 EXPECT_EQ(UnregistrationRequest::SUCCESS, status_);