| // Copyright 2015 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/sync_driver/sync_stopped_reporter.h" |
| |
| #include <string> |
| |
| #include "base/macros.h" |
| #include "base/message_loop/message_loop.h" |
| #include "base/run_loop.h" |
| #include "base/test/test_simple_task_runner.h" |
| #include "base/threading/non_thread_safe.h" |
| #include "net/http/http_status_code.h" |
| #include "net/url_request/test_url_fetcher_factory.h" |
| #include "net/url_request/url_request_test_util.h" |
| #include "sync/protocol/sync.pb.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "url/gurl.h" |
| |
| using browser_sync::SyncStoppedReporter; |
| |
| const char kTestURL[] = "http://chromium.org/test"; |
| const char kTestURLTrailingSlash[] = "http://chromium.org/test/"; |
| const char kEventURL[] = "http://chromium.org/test/event"; |
| |
| const char kTestUserAgent[] = "the_fifth_element"; |
| const char kAuthToken[] = "multipass"; |
| const char kCacheGuid[] = "leeloo"; |
| const char kBirthday[] = "2263"; |
| |
| const char kAuthHeaderPrefix[] = "Bearer "; |
| |
| class SyncStoppedReporterTest : public testing::Test { |
| public: |
| SyncStoppedReporterTest() {} |
| ~SyncStoppedReporterTest() override {} |
| |
| void SetUp() override { |
| request_context_ = new net::TestURLRequestContextGetter( |
| message_loop_.task_runner()); |
| } |
| |
| void RequestFinishedCallback(const SyncStoppedReporter::Result& result) { |
| request_result_ = result; |
| } |
| |
| GURL test_url() { |
| return GURL(kTestURL); |
| } |
| |
| std::string user_agent() const { |
| return std::string(kTestUserAgent); |
| } |
| |
| SyncStoppedReporter::ResultCallback callback() { |
| return base::Bind(&SyncStoppedReporterTest::RequestFinishedCallback, |
| base::Unretained(this)); |
| } |
| |
| const SyncStoppedReporter::Result& request_result() const { |
| return request_result_; |
| } |
| |
| net::URLRequestContextGetter* request_context() { |
| return request_context_.get(); |
| } |
| |
| private: |
| base::MessageLoop message_loop_; |
| scoped_refptr<net::URLRequestContextGetter> request_context_; |
| SyncStoppedReporter::Result request_result_; |
| |
| DISALLOW_COPY_AND_ASSIGN(SyncStoppedReporterTest); |
| }; |
| |
| // Test that the event URL gets constructed correctly. |
| TEST_F(SyncStoppedReporterTest, EventURL) { |
| net::TestURLFetcherFactory factory; |
| SyncStoppedReporter ssr(GURL(kTestURL), user_agent(), |
| request_context(), callback()); |
| ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday); |
| net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); |
| EXPECT_EQ(kEventURL, fetcher->GetOriginalURL().spec()); |
| } |
| |
| // Test that the event URL gets constructed correctly with a trailing slash. |
| TEST_F(SyncStoppedReporterTest, EventURLWithSlash) { |
| net::TestURLFetcherFactory factory; |
| SyncStoppedReporter ssr(GURL(kTestURLTrailingSlash), user_agent(), |
| request_context(), callback()); |
| ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday); |
| net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); |
| EXPECT_EQ(kEventURL, fetcher->GetOriginalURL().spec()); |
| } |
| |
| // Test that the URLFetcher gets configured correctly. |
| TEST_F(SyncStoppedReporterTest, FetcherConfiguration) { |
| net::TestURLFetcherFactory factory; |
| SyncStoppedReporter ssr(test_url(), user_agent(), |
| request_context(), callback()); |
| ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday); |
| net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); |
| |
| // Ensure the headers are set correctly. |
| net::HttpRequestHeaders headers; |
| std::string header; |
| fetcher->GetExtraRequestHeaders(&headers); |
| headers.GetHeader(net::HttpRequestHeaders::kAuthorization, &header); |
| std::string auth_header(kAuthHeaderPrefix); |
| auth_header.append(kAuthToken); |
| EXPECT_EQ(auth_header, header); |
| headers.GetHeader(net::HttpRequestHeaders::kUserAgent, &header); |
| EXPECT_EQ(user_agent(), header); |
| |
| sync_pb::EventRequest event_request; |
| event_request.ParseFromString(fetcher->upload_data()); |
| |
| EXPECT_EQ(kCacheGuid, event_request.sync_disabled().cache_guid()); |
| EXPECT_EQ(kBirthday, event_request.sync_disabled().store_birthday()); |
| EXPECT_EQ(kEventURL, fetcher->GetOriginalURL().spec()); |
| } |
| |
| TEST_F(SyncStoppedReporterTest, HappyCase) { |
| net::TestURLFetcherFactory factory; |
| SyncStoppedReporter ssr(test_url(), user_agent(), |
| request_context(), callback()); |
| ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday); |
| net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); |
| fetcher->set_response_code(net::HTTP_OK); |
| ssr.OnURLFetchComplete(fetcher); |
| base::RunLoop run_loop; |
| run_loop.RunUntilIdle(); |
| EXPECT_EQ(SyncStoppedReporter::RESULT_SUCCESS, request_result()); |
| } |
| |
| TEST_F(SyncStoppedReporterTest, ServerNotFound) { |
| net::TestURLFetcherFactory factory; |
| SyncStoppedReporter ssr(test_url(), user_agent(), |
| request_context(), callback()); |
| ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday); |
| net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); |
| fetcher->set_response_code(net::HTTP_NOT_FOUND); |
| ssr.OnURLFetchComplete(fetcher); |
| base::RunLoop run_loop; |
| run_loop.RunUntilIdle(); |
| EXPECT_EQ(SyncStoppedReporter::RESULT_ERROR, request_result()); |
| } |
| |
| TEST_F(SyncStoppedReporterTest, DestructionDuringRequestHandler) { |
| net::TestURLFetcherFactory factory; |
| factory.set_remove_fetcher_on_delete(true); |
| { |
| SyncStoppedReporter ssr(test_url(), user_agent(), |
| request_context(), callback()); |
| ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday); |
| EXPECT_FALSE(factory.GetFetcherByID(0) == nullptr); |
| } |
| EXPECT_TRUE(factory.GetFetcherByID(0) == nullptr); |
| } |
| |
| TEST_F(SyncStoppedReporterTest, Timeout) { |
| SyncStoppedReporter ssr(test_url(), user_agent(), |
| request_context(), callback()); |
| |
| // A task runner that can trigger the timeout immediately. |
| scoped_refptr<base::TestSimpleTaskRunner> task_runner( |
| new base::TestSimpleTaskRunner()); |
| ssr.SetTimerTaskRunnerForTest(task_runner); |
| |
| // Begin request. |
| ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday); |
| |
| // Trigger the timeout. |
| ASSERT_TRUE(task_runner->HasPendingTask()); |
| task_runner->RunPendingTasks(); |
| |
| base::RunLoop run_loop; |
| run_loop.RunUntilIdle(); |
| EXPECT_EQ(SyncStoppedReporter::RESULT_TIMEOUT, request_result()); |
| } |
| |
| TEST_F(SyncStoppedReporterTest, NoCallback) { |
| net::TestURLFetcherFactory factory; |
| SyncStoppedReporter ssr(GURL(kTestURL), user_agent(), request_context(), |
| SyncStoppedReporter::ResultCallback()); |
| ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday); |
| net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); |
| fetcher->set_response_code(net::HTTP_OK); |
| ssr.OnURLFetchComplete(fetcher); |
| } |
| |
| TEST_F(SyncStoppedReporterTest, NoCallbackTimeout) { |
| SyncStoppedReporter ssr(GURL(kTestURL), user_agent(), request_context(), |
| SyncStoppedReporter::ResultCallback()); |
| |
| // A task runner that can trigger the timeout immediately. |
| scoped_refptr<base::TestSimpleTaskRunner> task_runner( |
| new base::TestSimpleTaskRunner()); |
| ssr.SetTimerTaskRunnerForTest(task_runner); |
| |
| // Begin request. |
| ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday); |
| |
| // Trigger the timeout. |
| ASSERT_TRUE(task_runner->HasPendingTask()); |
| task_runner->RunPendingTasks(); |
| } |