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 "base/message_loop/message_loop.h" 6#include "components/gcm_driver/gcm_channel_status_request.h" 7#include "net/url_request/test_url_fetcher_factory.h" 8#include "net/url_request/url_request_test_util.h" 9#include "sync/protocol/experiment_status.pb.h" 10#include "sync/protocol/experiments_specifics.pb.h" 11#include "testing/gtest/include/gtest/gtest.h" 12 13namespace gcm { 14 15class GCMChannelStatusRequestTest : public testing::Test { 16 public: 17 GCMChannelStatusRequestTest(); 18 virtual ~GCMChannelStatusRequestTest(); 19 20 protected: 21 enum GCMStatus { 22 NOT_SPECIFIED, 23 GCM_ENABLED, 24 GCM_DISABLED, 25 }; 26 27 void StartRequest(); 28 void SetResponseStatusAndString(net::HttpStatusCode status_code, 29 const std::string& response_body); 30 void SetResponseProtoData(GCMStatus status, int poll_interval_seconds); 31 void CompleteFetch(); 32 void OnRequestCompleted(bool update_received, 33 bool enabled, 34 int poll_interval_seconds); 35 36 scoped_ptr<GCMChannelStatusRequest> request_; 37 base::MessageLoop message_loop_; 38 net::TestURLFetcherFactory url_fetcher_factory_; 39 scoped_refptr<net::TestURLRequestContextGetter> url_request_context_getter_; 40 bool request_callback_invoked_; 41 bool update_received_; 42 bool enabled_; 43 int poll_interval_seconds_; 44}; 45 46GCMChannelStatusRequestTest::GCMChannelStatusRequestTest() 47 : url_request_context_getter_(new net::TestURLRequestContextGetter( 48 message_loop_.message_loop_proxy())), 49 request_callback_invoked_(false), 50 update_received_(false), 51 enabled_(true), 52 poll_interval_seconds_(0) { 53} 54 55GCMChannelStatusRequestTest::~GCMChannelStatusRequestTest() { 56} 57 58void GCMChannelStatusRequestTest::StartRequest() { 59 request_.reset(new GCMChannelStatusRequest( 60 url_request_context_getter_.get(), 61 "http://channel.status.request.com/", 62 "user agent string", 63 base::Bind(&GCMChannelStatusRequestTest::OnRequestCompleted, 64 base::Unretained(this)))); 65 request_->Start(); 66} 67 68void GCMChannelStatusRequestTest::SetResponseStatusAndString( 69 net::HttpStatusCode status_code, 70 const std::string& response_body) { 71 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); 72 ASSERT_TRUE(fetcher); 73 fetcher->set_response_code(status_code); 74 fetcher->SetResponseString(response_body); 75} 76 77void GCMChannelStatusRequestTest::SetResponseProtoData( 78 GCMStatus status, int poll_interval_seconds) { 79 sync_pb::ExperimentStatusResponse response_proto; 80 if (status != NOT_SPECIFIED) { 81 sync_pb::ExperimentsSpecifics* experiment_specifics = 82 response_proto.add_experiment(); 83 experiment_specifics->mutable_gcm_channel()->set_enabled(status == 84 GCM_ENABLED); 85 } 86 87 // Zero |poll_interval_seconds| means the optional field is not set. 88 if (poll_interval_seconds) 89 response_proto.set_poll_interval_seconds(poll_interval_seconds); 90 91 std::string response_string; 92 response_proto.SerializeToString(&response_string); 93 SetResponseStatusAndString(net::HTTP_OK, response_string); 94} 95 96void GCMChannelStatusRequestTest::CompleteFetch() { 97 request_callback_invoked_ = false; 98 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); 99 ASSERT_TRUE(fetcher); 100 fetcher->delegate()->OnURLFetchComplete(fetcher); 101} 102 103void GCMChannelStatusRequestTest::OnRequestCompleted( 104 bool update_received, bool enabled, int poll_interval_seconds) { 105 request_callback_invoked_ = true; 106 update_received_ = update_received; 107 enabled_ = enabled; 108 poll_interval_seconds_ = poll_interval_seconds; 109} 110 111TEST_F(GCMChannelStatusRequestTest, RequestData) { 112 StartRequest(); 113 114 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); 115 ASSERT_TRUE(fetcher); 116 117 EXPECT_EQ(GURL(request_->channel_status_request_url_), 118 fetcher->GetOriginalURL()); 119 120 net::HttpRequestHeaders headers; 121 fetcher->GetExtraRequestHeaders(&headers); 122 std::string user_agent_header; 123 headers.GetHeader("User-Agent", &user_agent_header); 124 EXPECT_FALSE(user_agent_header.empty()); 125 EXPECT_EQ(request_->user_agent_, user_agent_header); 126 127 std::string upload_data = fetcher->upload_data(); 128 EXPECT_FALSE(upload_data.empty()); 129 sync_pb::ExperimentStatusRequest proto_data; 130 proto_data.ParseFromString(upload_data); 131 EXPECT_EQ(1, proto_data.experiment_name_size()); 132 EXPECT_EQ("gcm_channel", proto_data.experiment_name(0)); 133} 134 135TEST_F(GCMChannelStatusRequestTest, ResponseHttpStatusNotOK) { 136 StartRequest(); 137 SetResponseStatusAndString(net::HTTP_UNAUTHORIZED, ""); 138 CompleteFetch(); 139 140 EXPECT_FALSE(request_callback_invoked_); 141} 142 143TEST_F(GCMChannelStatusRequestTest, ResponseEmpty) { 144 StartRequest(); 145 SetResponseStatusAndString(net::HTTP_OK, ""); 146 CompleteFetch(); 147 148 EXPECT_TRUE(request_callback_invoked_); 149 EXPECT_FALSE(update_received_); 150} 151 152TEST_F(GCMChannelStatusRequestTest, ResponseNotInProtoFormat) { 153 StartRequest(); 154 SetResponseStatusAndString(net::HTTP_OK, "foo"); 155 CompleteFetch(); 156 157 EXPECT_FALSE(request_callback_invoked_); 158} 159 160TEST_F(GCMChannelStatusRequestTest, ResponseEmptyProtoData) { 161 StartRequest(); 162 SetResponseProtoData(NOT_SPECIFIED, 0); 163 CompleteFetch(); 164 165 EXPECT_TRUE(request_callback_invoked_); 166 EXPECT_FALSE(update_received_); 167} 168 169TEST_F(GCMChannelStatusRequestTest, ResponseWithDisabledStatus) { 170 StartRequest(); 171 SetResponseProtoData(GCM_DISABLED, 0); 172 CompleteFetch(); 173 174 EXPECT_TRUE(request_callback_invoked_); 175 EXPECT_TRUE(update_received_); 176 EXPECT_FALSE(enabled_); 177 EXPECT_EQ( 178 GCMChannelStatusRequest::default_poll_interval_seconds(), 179 poll_interval_seconds_); 180} 181 182TEST_F(GCMChannelStatusRequestTest, ResponseWithEnabledStatus) { 183 StartRequest(); 184 SetResponseProtoData(GCM_ENABLED, 0); 185 CompleteFetch(); 186 187 EXPECT_TRUE(request_callback_invoked_); 188 EXPECT_TRUE(update_received_); 189 EXPECT_TRUE(enabled_); 190 EXPECT_EQ( 191 GCMChannelStatusRequest::default_poll_interval_seconds(), 192 poll_interval_seconds_); 193} 194 195TEST_F(GCMChannelStatusRequestTest, ResponseWithPollInterval) { 196 // Setting a poll interval 15 minutes longer than the minimum interval we 197 // enforce. 198 int poll_interval_seconds = 199 GCMChannelStatusRequest::min_poll_interval_seconds() + 15 * 60; 200 StartRequest(); 201 SetResponseProtoData(NOT_SPECIFIED, poll_interval_seconds); 202 CompleteFetch(); 203 204 EXPECT_TRUE(request_callback_invoked_); 205 EXPECT_TRUE(update_received_); 206 EXPECT_TRUE(enabled_); 207 EXPECT_EQ(poll_interval_seconds, poll_interval_seconds_); 208} 209 210TEST_F(GCMChannelStatusRequestTest, ResponseWithShortPollInterval) { 211 // Setting a poll interval 15 minutes shorter than the minimum interval we 212 // enforce. 213 int poll_interval_seconds = 214 GCMChannelStatusRequest::min_poll_interval_seconds() - 15 * 60; 215 StartRequest(); 216 SetResponseProtoData(NOT_SPECIFIED, poll_interval_seconds); 217 CompleteFetch(); 218 219 EXPECT_TRUE(request_callback_invoked_); 220 EXPECT_TRUE(update_received_); 221 EXPECT_TRUE(enabled_); 222 EXPECT_EQ(GCMChannelStatusRequest::min_poll_interval_seconds(), 223 poll_interval_seconds_); 224} 225 226TEST_F(GCMChannelStatusRequestTest, ResponseWithDisabledStatusAndPollInterval) { 227 int poll_interval_seconds = 228 GCMChannelStatusRequest::min_poll_interval_seconds() + 15 * 60; 229 StartRequest(); 230 SetResponseProtoData(GCM_DISABLED, poll_interval_seconds); 231 CompleteFetch(); 232 233 EXPECT_TRUE(request_callback_invoked_); 234 EXPECT_TRUE(update_received_); 235 EXPECT_FALSE(enabled_); 236 EXPECT_EQ(poll_interval_seconds, poll_interval_seconds_); 237} 238 239} // namespace gcm 240