sync_stopped_reporter_unittest.cc 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. // Copyright 2015 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. #include "components/sync/driver/sync_stopped_reporter.h"
  5. #include "base/bind.h"
  6. #include "base/run_loop.h"
  7. #include "base/test/bind.h"
  8. #include "base/test/scoped_mock_time_message_loop_task_runner.h"
  9. #include "base/test/task_environment.h"
  10. #include "components/sync/protocol/sync.pb.h"
  11. #include "net/http/http_status_code.h"
  12. #include "net/http/http_util.h"
  13. #include "services/network/public/cpp/resource_request.h"
  14. #include "services/network/public/cpp/shared_url_loader_factory.h"
  15. #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
  16. #include "services/network/test/test_url_loader_factory.h"
  17. #include "services/network/test/test_utils.h"
  18. #include "testing/gtest/include/gtest/gtest.h"
  19. namespace syncer {
  20. const char kTestURL[] = "http://chromium.org/test";
  21. const char kTestURLTrailingSlash[] = "http://chromium.org/test/";
  22. const char kEventURL[] = "http://chromium.org/test/event";
  23. const char kTestUserAgent[] = "the_fifth_element";
  24. const char kAuthToken[] = "multipass";
  25. const char kCacheGuid[] = "leeloo";
  26. const char kBirthday[] = "2263";
  27. const char kAuthHeaderPrefix[] = "Bearer ";
  28. class SyncStoppedReporterTest : public testing::Test {
  29. public:
  30. SyncStoppedReporterTest(const SyncStoppedReporterTest&) = delete;
  31. SyncStoppedReporterTest& operator=(const SyncStoppedReporterTest&) = delete;
  32. protected:
  33. SyncStoppedReporterTest() = default;
  34. ~SyncStoppedReporterTest() override = default;
  35. void SetUp() override {
  36. test_shared_loader_factory_ =
  37. base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
  38. url_loader_factory());
  39. }
  40. void RequestFinishedCallback(const SyncStoppedReporter::Result& result) {
  41. request_result_ = result;
  42. }
  43. GURL interception_url(const GURL& url) {
  44. return SyncStoppedReporter::GetSyncEventURL(url);
  45. }
  46. GURL test_url() { return GURL(kTestURL); }
  47. void call_on_timeout(SyncStoppedReporter* ssr) { ssr->OnTimeout(); }
  48. std::string user_agent() const { return std::string(kTestUserAgent); }
  49. SyncStoppedReporter::ResultCallback callback() {
  50. return base::BindOnce(&SyncStoppedReporterTest::RequestFinishedCallback,
  51. base::Unretained(this));
  52. }
  53. const SyncStoppedReporter::Result& request_result() const {
  54. return request_result_;
  55. }
  56. network::TestURLLoaderFactory* url_loader_factory() {
  57. return &test_url_loader_factory_;
  58. }
  59. scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory() {
  60. return test_shared_loader_factory_;
  61. }
  62. private:
  63. base::test::SingleThreadTaskEnvironment task_environment_;
  64. network::TestURLLoaderFactory test_url_loader_factory_;
  65. scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
  66. SyncStoppedReporter::Result request_result_;
  67. };
  68. // Test that the event URL gets constructed correctly.
  69. TEST_F(SyncStoppedReporterTest, EventURL) {
  70. GURL intercepted_url;
  71. url_loader_factory()->AddResponse(interception_url(GURL(kTestURL)).spec(),
  72. "");
  73. url_loader_factory()->SetInterceptor(
  74. base::BindLambdaForTesting([&](const network::ResourceRequest& request) {
  75. intercepted_url = request.url;
  76. }));
  77. SyncStoppedReporter ssr(GURL(kTestURL), user_agent(),
  78. shared_url_loader_factory(), callback());
  79. ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday);
  80. EXPECT_EQ(kEventURL, intercepted_url.spec());
  81. }
  82. // Test that the event URL gets constructed correctly with a trailing slash.
  83. TEST_F(SyncStoppedReporterTest, EventURLWithSlash) {
  84. GURL intercepted_url;
  85. url_loader_factory()->AddResponse(
  86. interception_url(GURL(kTestURLTrailingSlash)).spec(), "");
  87. url_loader_factory()->SetInterceptor(
  88. base::BindLambdaForTesting([&](const network::ResourceRequest& request) {
  89. intercepted_url = request.url;
  90. }));
  91. SyncStoppedReporter ssr(GURL(kTestURLTrailingSlash), user_agent(),
  92. shared_url_loader_factory(), callback());
  93. ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday);
  94. EXPECT_EQ(kEventURL, intercepted_url.spec());
  95. }
  96. // Test that the URLFetcher gets configured correctly.
  97. TEST_F(SyncStoppedReporterTest, FetcherConfiguration) {
  98. GURL intercepted_url;
  99. net::HttpRequestHeaders intercepted_headers;
  100. std::string intercepted_body;
  101. url_loader_factory()->AddResponse(interception_url(test_url()).spec(), "");
  102. url_loader_factory()->SetInterceptor(
  103. base::BindLambdaForTesting([&](const network::ResourceRequest& request) {
  104. intercepted_url = request.url;
  105. intercepted_headers = request.headers;
  106. intercepted_body = network::GetUploadData(request);
  107. }));
  108. SyncStoppedReporter ssr(test_url(), user_agent(), shared_url_loader_factory(),
  109. callback());
  110. ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday);
  111. // Ensure the headers are set correctly.
  112. std::string header;
  113. intercepted_headers.GetHeader(net::HttpRequestHeaders::kAuthorization,
  114. &header);
  115. std::string auth_header(kAuthHeaderPrefix);
  116. auth_header.append(kAuthToken);
  117. EXPECT_EQ(auth_header, header);
  118. intercepted_headers.GetHeader(net::HttpRequestHeaders::kUserAgent, &header);
  119. EXPECT_EQ(user_agent(), header);
  120. sync_pb::EventRequest event_request;
  121. event_request.ParseFromString(intercepted_body);
  122. EXPECT_EQ(kCacheGuid, event_request.sync_disabled().cache_guid());
  123. EXPECT_EQ(kBirthday, event_request.sync_disabled().store_birthday());
  124. EXPECT_EQ(kEventURL, intercepted_url.spec());
  125. }
  126. TEST_F(SyncStoppedReporterTest, HappyCase) {
  127. url_loader_factory()->AddResponse(interception_url(test_url()).spec(), "");
  128. SyncStoppedReporter ssr(test_url(), user_agent(), shared_url_loader_factory(),
  129. callback());
  130. ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday);
  131. base::RunLoop run_loop;
  132. run_loop.RunUntilIdle();
  133. EXPECT_EQ(SyncStoppedReporter::RESULT_SUCCESS, request_result());
  134. }
  135. TEST_F(SyncStoppedReporterTest, ServerNotFound) {
  136. url_loader_factory()->AddResponse(interception_url(test_url()).spec(), "",
  137. net::HTTP_NOT_FOUND);
  138. SyncStoppedReporter ssr(test_url(), user_agent(), shared_url_loader_factory(),
  139. callback());
  140. ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday);
  141. base::RunLoop run_loop;
  142. run_loop.RunUntilIdle();
  143. EXPECT_EQ(SyncStoppedReporter::RESULT_ERROR, request_result());
  144. }
  145. TEST_F(SyncStoppedReporterTest, Timeout) {
  146. url_loader_factory()->AddResponse(interception_url(test_url()).spec(), "");
  147. // Mock the underlying loop's clock to trigger the timer at will.
  148. base::ScopedMockTimeMessageLoopTaskRunner mock_main_runner;
  149. SyncStoppedReporter ssr(test_url(), user_agent(), shared_url_loader_factory(),
  150. callback());
  151. // Begin request.
  152. ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday);
  153. // Trigger the timeout.
  154. ASSERT_TRUE(mock_main_runner->HasPendingTask());
  155. call_on_timeout(&ssr);
  156. mock_main_runner->FastForwardUntilNoTasksRemain();
  157. EXPECT_EQ(SyncStoppedReporter::RESULT_TIMEOUT, request_result());
  158. }
  159. TEST_F(SyncStoppedReporterTest, NoCallback) {
  160. url_loader_factory()->AddResponse(interception_url(GURL(kTestURL)).spec(),
  161. "");
  162. SyncStoppedReporter ssr(GURL(kTestURL), user_agent(),
  163. shared_url_loader_factory(),
  164. SyncStoppedReporter::ResultCallback());
  165. ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday);
  166. base::RunLoop run_loop;
  167. run_loop.RunUntilIdle();
  168. }
  169. TEST_F(SyncStoppedReporterTest, NoCallbackTimeout) {
  170. url_loader_factory()->AddResponse(interception_url(GURL(kTestURL)).spec(),
  171. "");
  172. // Mock the underlying loop's clock to trigger the timer at will.
  173. base::ScopedMockTimeMessageLoopTaskRunner mock_main_runner;
  174. SyncStoppedReporter ssr(GURL(kTestURL), user_agent(),
  175. shared_url_loader_factory(),
  176. SyncStoppedReporter::ResultCallback());
  177. // Begin request.
  178. ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday);
  179. // Trigger the timeout.
  180. ASSERT_TRUE(mock_main_runner->HasPendingTask());
  181. call_on_timeout(&ssr);
  182. mock_main_runner->FastForwardUntilNoTasksRemain();
  183. }
  184. } // namespace syncer