OLD | NEW |
(Empty) | |
| 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 "chrome/browser/history/web_history_service.h" |
| 6 |
| 7 #include "base/memory/scoped_ptr.h" |
| 8 #include "base/run_loop.h" |
| 9 #include "chrome/browser/history/web_history_service_factory.h" |
| 10 #include "chrome/browser/sync/profile_sync_service.h" |
| 11 #include "chrome/browser/sync/profile_sync_service_factory.h" |
| 12 #include "chrome/browser/sync/profile_sync_service_mock.h" |
| 13 #include "chrome/test/base/testing_profile.h" |
| 14 #include "content/public/test/test_browser_thread_bundle.h" |
| 15 #include "net/http/http_status_code.h" |
| 16 #include "testing/gmock/include/gmock/gmock.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" |
| 18 |
| 19 using history::WebHistoryService; |
| 20 using ::testing::Return; |
| 21 |
| 22 namespace { |
| 23 |
| 24 // A testing web history service that does extra checks and creates a |
| 25 // TestRequest instead of a normal request. |
| 26 class TestingWebHistoryService : public WebHistoryService { |
| 27 public: |
| 28 explicit TestingWebHistoryService(Profile* profile) |
| 29 : WebHistoryService(profile), |
| 30 profile_(profile), |
| 31 expected_url_(GURL()), |
| 32 expected_audio_history_value_(false), |
| 33 current_expected_post_data_("") { |
| 34 } |
| 35 ~TestingWebHistoryService() override {} |
| 36 |
| 37 WebHistoryService::Request* CreateRequest( |
| 38 const GURL& url, const CompletionCallback& callback) override; |
| 39 |
| 40 // This is sorta an override but override and static don't mix. |
| 41 // This function just calls WebHistoryService::ReadResponse. |
| 42 static scoped_ptr<base::DictionaryValue> ReadResponse( |
| 43 Request* request); |
| 44 |
| 45 const std::string& GetExpectedPostData(WebHistoryService::Request* request); |
| 46 |
| 47 std::string GetExpectedAudioHistoryValue(); |
| 48 |
| 49 void SetAudioHistoryCallback(bool success, bool new_enabled_value); |
| 50 |
| 51 void GetAudioHistoryCallback(bool success, bool new_enabled_value); |
| 52 |
| 53 void MultipleRequestsCallback(bool success, bool new_enabled_value); |
| 54 |
| 55 void SetExpectedURL(const GURL& expected_url) { |
| 56 expected_url_ = expected_url; |
| 57 } |
| 58 |
| 59 void SetExpectedAudioHistoryValue(bool expected_value) { |
| 60 expected_audio_history_value_ = expected_value; |
| 61 } |
| 62 |
| 63 void SetExpectedPostData(const std::string& expected_data) { |
| 64 current_expected_post_data_= expected_data; |
| 65 } |
| 66 |
| 67 void EnsureNoPendingRequestsRemain() { |
| 68 EXPECT_EQ(0u, GetNumberOfPendingAudioHistoryRequests()); |
| 69 } |
| 70 |
| 71 private: |
| 72 Profile* profile_; |
| 73 GURL expected_url_; |
| 74 bool expected_audio_history_value_; |
| 75 std::string current_expected_post_data_; |
| 76 std::map<Request*, std::string> expected_post_data_; |
| 77 |
| 78 DISALLOW_COPY_AND_ASSIGN(TestingWebHistoryService); |
| 79 }; |
| 80 |
| 81 // A testing request class that allows expected values to be filled in. |
| 82 class TestRequest : public WebHistoryService::Request { |
| 83 public: |
| 84 TestRequest(Profile* profile, |
| 85 const GURL& url, |
| 86 const WebHistoryService::CompletionCallback& callback, |
| 87 int response_code, |
| 88 const std::string& response_body) |
| 89 : profile_(profile), |
| 90 web_history_service_(nullptr), |
| 91 url_(url), |
| 92 callback_(callback), |
| 93 response_code_(response_code), |
| 94 response_body_(response_body), |
| 95 post_data_(""), |
| 96 is_pending_(false) { |
| 97 } |
| 98 |
| 99 TestRequest(Profile* profile, |
| 100 const GURL& url, |
| 101 const WebHistoryService::CompletionCallback& callback, |
| 102 TestingWebHistoryService* web_history_service) |
| 103 : profile_(profile), |
| 104 web_history_service_(web_history_service), |
| 105 url_(url), |
| 106 callback_(callback), |
| 107 response_code_(net::HTTP_OK), |
| 108 response_body_(""), |
| 109 post_data_(""), |
| 110 is_pending_(false) { |
| 111 response_body_ = std::string("{\"history_recording_enabled\":") + |
| 112 web_history_service->GetExpectedAudioHistoryValue() + |
| 113 ("}"); |
| 114 } |
| 115 |
| 116 ~TestRequest() override {} |
| 117 |
| 118 // history::Request overrides |
| 119 bool IsPending() override { return is_pending_; } |
| 120 int GetResponseCode() override { return response_code_; } |
| 121 const std::string& GetResponseBody() override { return response_body_; } |
| 122 void SetPostData(const std::string& post_data) override { |
| 123 post_data_ = post_data; |
| 124 } |
| 125 |
| 126 void Start() override { |
| 127 is_pending_ = true; |
| 128 base::MessageLoop::current()->PostTask( |
| 129 FROM_HERE, |
| 130 base::Bind(&TestRequest::MimicReturnFromFetch, base::Unretained(this))); |
| 131 } |
| 132 |
| 133 void MimicReturnFromFetch() { |
| 134 // Mimic a successful fetch and return. We don't actually send out a request |
| 135 // in unittests. |
| 136 EXPECT_EQ(web_history_service_->GetExpectedPostData(this), post_data_); |
| 137 callback_.Run(this, true); |
| 138 } |
| 139 |
| 140 private: |
| 141 Profile* profile_; |
| 142 TestingWebHistoryService* web_history_service_; |
| 143 GURL url_; |
| 144 WebHistoryService::CompletionCallback callback_; |
| 145 int response_code_; |
| 146 std::string response_body_; |
| 147 std::string post_data_; |
| 148 bool is_pending_; |
| 149 |
| 150 DISALLOW_COPY_AND_ASSIGN(TestRequest); |
| 151 }; |
| 152 |
| 153 WebHistoryService::Request* TestingWebHistoryService::CreateRequest( |
| 154 const GURL& url, const CompletionCallback& callback) { |
| 155 EXPECT_EQ(expected_url_, url); |
| 156 WebHistoryService::Request* request = |
| 157 new TestRequest(profile_, url, callback, this); |
| 158 expected_post_data_[request] = current_expected_post_data_; |
| 159 return request; |
| 160 } |
| 161 |
| 162 scoped_ptr<base::DictionaryValue> TestingWebHistoryService::ReadResponse( |
| 163 Request* request) { |
| 164 return WebHistoryService::ReadResponse(request); |
| 165 } |
| 166 |
| 167 void TestingWebHistoryService::SetAudioHistoryCallback( |
| 168 bool success, bool new_enabled_value) { |
| 169 EXPECT_TRUE(success); |
| 170 // |new_enabled_value| should be equal to whatever the audio history value |
| 171 // was just set to. |
| 172 EXPECT_EQ(expected_audio_history_value_, new_enabled_value); |
| 173 } |
| 174 |
| 175 void TestingWebHistoryService::GetAudioHistoryCallback( |
| 176 bool success, bool new_enabled_value) { |
| 177 EXPECT_TRUE(success); |
| 178 EXPECT_EQ(expected_audio_history_value_, new_enabled_value); |
| 179 } |
| 180 |
| 181 void TestingWebHistoryService::MultipleRequestsCallback( |
| 182 bool success, bool new_enabled_value) { |
| 183 EXPECT_TRUE(success); |
| 184 EXPECT_EQ(expected_audio_history_value_, new_enabled_value); |
| 185 } |
| 186 |
| 187 const std::string& TestingWebHistoryService::GetExpectedPostData( |
| 188 Request* request) { |
| 189 return expected_post_data_[request]; |
| 190 } |
| 191 |
| 192 std::string TestingWebHistoryService::GetExpectedAudioHistoryValue() { |
| 193 if (expected_audio_history_value_) |
| 194 return "true"; |
| 195 return "false"; |
| 196 } |
| 197 |
| 198 static KeyedService* BuildWebHistoryService(content::BrowserContext* profile) { |
| 199 return new TestingWebHistoryService(static_cast<Profile*>(profile)); |
| 200 } |
| 201 |
| 202 } // namespace |
| 203 |
| 204 // A test class used for testing the WebHistoryService class. |
| 205 // In order for WebHistoryService to be valid, we must have a valid |
| 206 // ProfileSyncService. Using the ProfileSyncServiceMock class allows to |
| 207 // assign specific return values as needed to make sure the web history |
| 208 // service is available. |
| 209 class WebHistoryServiceTest : public testing::Test { |
| 210 public: |
| 211 WebHistoryServiceTest() |
| 212 : thread_bundle_(content::TestBrowserThreadBundle::REAL_DB_THREAD) {} |
| 213 virtual ~WebHistoryServiceTest() {} |
| 214 |
| 215 void SetUp() override { |
| 216 ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse( |
| 217 &profile_, &ProfileSyncServiceMock::BuildMockProfileSyncService); |
| 218 // Use SetTestingFactoryAndUse to force creation and initialization. |
| 219 WebHistoryServiceFactory::GetInstance()->SetTestingFactoryAndUse( |
| 220 &profile_, &BuildWebHistoryService); |
| 221 |
| 222 ProfileSyncServiceMock* sync_service = static_cast<ProfileSyncServiceMock*>( |
| 223 ProfileSyncServiceFactory::GetInstance()->GetForProfile(&profile_)); |
| 224 EXPECT_CALL(*sync_service, |
| 225 SyncActive()).WillRepeatedly(Return(true)); |
| 226 syncer::ModelTypeSet result; |
| 227 result.Put(syncer::HISTORY_DELETE_DIRECTIVES); |
| 228 EXPECT_CALL(*sync_service, |
| 229 GetActiveDataTypes()).WillRepeatedly(Return(result)); |
| 230 } |
| 231 void TearDown() override { |
| 232 base::RunLoop run_loop; |
| 233 base::MessageLoop::current()->PostTask(FROM_HERE, run_loop.QuitClosure()); |
| 234 run_loop.Run(); |
| 235 } |
| 236 Profile* profile() { return &profile_; } |
| 237 |
| 238 ProfileSyncServiceMock* mock_sync_service() { |
| 239 return static_cast<ProfileSyncServiceMock*>( |
| 240 ProfileSyncServiceFactory::GetInstance()->GetForProfile(&profile_)); |
| 241 } |
| 242 |
| 243 private: |
| 244 |
| 245 content::TestBrowserThreadBundle thread_bundle_; |
| 246 TestingProfile profile_; |
| 247 |
| 248 DISALLOW_COPY_AND_ASSIGN(WebHistoryServiceTest); |
| 249 }; |
| 250 |
| 251 TEST_F(WebHistoryServiceTest, GetAudioHistoryEnabled) { |
| 252 TestingWebHistoryService* web_history_service = |
| 253 static_cast<TestingWebHistoryService*>( |
| 254 WebHistoryServiceFactory::GetForProfile(profile())); |
| 255 EXPECT_TRUE(web_history_service); |
| 256 |
| 257 web_history_service->SetExpectedURL( |
| 258 GURL("https://history.google.com/history/api/lookup?client=audio")); |
| 259 web_history_service->SetExpectedAudioHistoryValue(true); |
| 260 web_history_service->GetAudioHistoryEnabled( |
| 261 base::Bind(&TestingWebHistoryService::GetAudioHistoryCallback, |
| 262 base::Unretained(web_history_service))); |
| 263 base::MessageLoop::current()->PostTask( |
| 264 FROM_HERE, |
| 265 base::Bind(&TestingWebHistoryService::EnsureNoPendingRequestsRemain, |
| 266 base::Unretained(web_history_service))); |
| 267 } |
| 268 |
| 269 TEST_F(WebHistoryServiceTest, SetAudioHistoryEnabledTrue) { |
| 270 TestingWebHistoryService* web_history_service = |
| 271 static_cast<TestingWebHistoryService*>( |
| 272 WebHistoryServiceFactory::GetForProfile(profile())); |
| 273 EXPECT_TRUE(web_history_service); |
| 274 |
| 275 web_history_service->SetExpectedURL( |
| 276 GURL("https://history.google.com/history/api/change")); |
| 277 web_history_service->SetExpectedAudioHistoryValue(true); |
| 278 web_history_service->SetExpectedPostData( |
| 279 "{\"client\":\"audio\",\"enable_history_recording\":true}"); |
| 280 web_history_service->SetAudioHistoryEnabled( |
| 281 true, |
| 282 base::Bind(&TestingWebHistoryService::SetAudioHistoryCallback, |
| 283 base::Unretained(web_history_service))); |
| 284 base::MessageLoop::current()->PostTask( |
| 285 FROM_HERE, |
| 286 base::Bind(&TestingWebHistoryService::EnsureNoPendingRequestsRemain, |
| 287 base::Unretained(web_history_service))); |
| 288 } |
| 289 |
| 290 TEST_F(WebHistoryServiceTest, SetAudioHistoryEnabledFalse) { |
| 291 TestingWebHistoryService* web_history_service = |
| 292 static_cast<TestingWebHistoryService*>( |
| 293 WebHistoryServiceFactory::GetForProfile(profile())); |
| 294 EXPECT_TRUE(web_history_service); |
| 295 |
| 296 web_history_service->SetExpectedURL( |
| 297 GURL("https://history.google.com/history/api/change")); |
| 298 web_history_service->SetExpectedAudioHistoryValue(false); |
| 299 web_history_service->SetExpectedPostData( |
| 300 "{\"client\":\"audio\",\"enable_history_recording\":false}"); |
| 301 web_history_service->SetAudioHistoryEnabled( |
| 302 false, |
| 303 base::Bind(&TestingWebHistoryService::SetAudioHistoryCallback, |
| 304 base::Unretained(web_history_service))); |
| 305 base::MessageLoop::current()->PostTask( |
| 306 FROM_HERE, |
| 307 base::Bind(&TestingWebHistoryService::EnsureNoPendingRequestsRemain, |
| 308 base::Unretained(web_history_service))); |
| 309 } |
| 310 |
| 311 TEST_F(WebHistoryServiceTest, MultipleRequests) { |
| 312 TestingWebHistoryService* web_history_service = |
| 313 static_cast<TestingWebHistoryService*>( |
| 314 WebHistoryServiceFactory::GetForProfile(profile())); |
| 315 EXPECT_TRUE(web_history_service); |
| 316 |
| 317 web_history_service->SetExpectedURL( |
| 318 GURL("https://history.google.com/history/api/change")); |
| 319 web_history_service->SetExpectedAudioHistoryValue(false); |
| 320 web_history_service->SetExpectedPostData( |
| 321 "{\"client\":\"audio\",\"enable_history_recording\":false}"); |
| 322 web_history_service->SetAudioHistoryEnabled( |
| 323 false, |
| 324 base::Bind(&TestingWebHistoryService::MultipleRequestsCallback, |
| 325 base::Unretained(web_history_service))); |
| 326 |
| 327 web_history_service->SetExpectedURL( |
| 328 GURL("https://history.google.com/history/api/lookup?client=audio")); |
| 329 web_history_service->SetExpectedPostData(""); |
| 330 web_history_service->GetAudioHistoryEnabled( |
| 331 base::Bind(&TestingWebHistoryService::MultipleRequestsCallback, |
| 332 base::Unretained(web_history_service))); |
| 333 |
| 334 // Check that both requests are no longer pending. |
| 335 base::MessageLoop::current()->PostTask( |
| 336 FROM_HERE, |
| 337 base::Bind(&TestingWebHistoryService::EnsureNoPendingRequestsRemain, |
| 338 base::Unretained(web_history_service))); |
| 339 } |
| 340 |
| 341 TEST_F(WebHistoryServiceTest, VerifyReadResponse) { |
| 342 // Test that properly formatted response with good response code returns true |
| 343 // as expected. |
| 344 WebHistoryService::CompletionCallback completion_callback; |
| 345 scoped_ptr<WebHistoryService::Request> request( |
| 346 new TestRequest( |
| 347 profile(), |
| 348 GURL("http://history.google.com/"), |
| 349 completion_callback, |
| 350 net::HTTP_OK, /* response code */ |
| 351 "{\n" /* response body */ |
| 352 " \"history_recording_enabled\": true\n" |
| 353 "}")); |
| 354 scoped_ptr<base::DictionaryValue> response_value; |
| 355 // ReadResponse deletes the request |
| 356 response_value = TestingWebHistoryService::ReadResponse(request.get()); |
| 357 bool enabled_value = false; |
| 358 response_value->GetBoolean("history_recording_enabled", &enabled_value); |
| 359 EXPECT_TRUE(enabled_value); |
| 360 |
| 361 // Test that properly formatted response with good response code returns false |
| 362 // as expected. |
| 363 scoped_ptr<WebHistoryService::Request> request2( |
| 364 new TestRequest( |
| 365 profile(), |
| 366 GURL("http://history.google.com/"), |
| 367 completion_callback, |
| 368 net::HTTP_OK, |
| 369 "{\n" |
| 370 " \"history_recording_enabled\": false\n" |
| 371 "}")); |
| 372 scoped_ptr<base::DictionaryValue> response_value2; |
| 373 // ReadResponse deletes the request |
| 374 response_value2 = TestingWebHistoryService::ReadResponse(request2.get()); |
| 375 enabled_value = true; |
| 376 response_value2->GetBoolean("history_recording_enabled", &enabled_value); |
| 377 EXPECT_FALSE(enabled_value); |
| 378 |
| 379 // Test that a bad response code returns false. |
| 380 scoped_ptr<WebHistoryService::Request> request3( |
| 381 new TestRequest( |
| 382 profile(), |
| 383 GURL("http://history.google.com/"), |
| 384 completion_callback, |
| 385 net::HTTP_UNAUTHORIZED, |
| 386 "{\n" |
| 387 " \"history_recording_enabled\": true\n" |
| 388 "}")); |
| 389 scoped_ptr<base::DictionaryValue> response_value3; |
| 390 // ReadResponse deletes the request |
| 391 response_value3 = TestingWebHistoryService::ReadResponse(request3.get()); |
| 392 EXPECT_FALSE(response_value3); |
| 393 |
| 394 // Test that improperly formatted response returns false. |
| 395 // Note: we expect to see a warning when running this test similar to |
| 396 // "Non-JSON response received from history server". |
| 397 // This test tests how that situation is handled. |
| 398 scoped_ptr<WebHistoryService::Request> request4( |
| 399 new TestRequest( |
| 400 profile(), |
| 401 GURL("http://history.google.com/"), |
| 402 completion_callback, |
| 403 net::HTTP_OK, |
| 404 "{\n" |
| 405 " \"history_recording_enabled\": not true\n" |
| 406 "}")); |
| 407 scoped_ptr<base::DictionaryValue> response_value4; |
| 408 // ReadResponse deletes the request |
| 409 response_value4 = TestingWebHistoryService::ReadResponse(request4.get()); |
| 410 EXPECT_FALSE(response_value4); |
| 411 |
| 412 // Test that improperly formatted response returns false. |
| 413 scoped_ptr<WebHistoryService::Request> request5( |
| 414 new TestRequest( |
| 415 profile(), |
| 416 GURL("http://history.google.com/"), |
| 417 completion_callback, |
| 418 net::HTTP_OK, |
| 419 "{\n" |
| 420 " \"history_recording\": true\n" |
| 421 "}")); |
| 422 scoped_ptr<base::DictionaryValue> response_value5; |
| 423 // ReadResponse deletes the request |
| 424 response_value5 = TestingWebHistoryService::ReadResponse(request5.get()); |
| 425 enabled_value = true; |
| 426 EXPECT_FALSE(response_value5->GetBoolean("history_recording_enabled", |
| 427 &enabled_value)); |
| 428 EXPECT_TRUE(enabled_value); |
| 429 } |
OLD | NEW |