public_ip_address_geolocator_unittest.cc 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. // Copyright 2017 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 "services/device/geolocation/public_ip_address_geolocator.h"
  5. #include <memory>
  6. #include "base/bind.h"
  7. #include "base/callback_helpers.h"
  8. #include "base/run_loop.h"
  9. #include "base/strings/string_util.h"
  10. #include "base/test/task_environment.h"
  11. #include "mojo/public/cpp/bindings/remote.h"
  12. #include "mojo/public/cpp/bindings/unique_receiver_set.h"
  13. #include "mojo/public/cpp/system/functions.h"
  14. #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
  15. #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
  16. #include "services/network/test/test_network_connection_tracker.h"
  17. #include "services/network/test/test_url_loader_factory.h"
  18. #include "testing/gmock/include/gmock/gmock.h"
  19. #include "testing/gtest/include/gtest/gtest.h"
  20. namespace device {
  21. namespace {
  22. const char kTestGeolocationApiKey[] = "";
  23. class PublicIpAddressGeolocatorTest : public testing::Test {
  24. public:
  25. PublicIpAddressGeolocatorTest()
  26. : task_environment_(base::test::TaskEnvironment::MainThreadType::IO),
  27. network_connection_tracker_(
  28. network::TestNetworkConnectionTracker::CreateInstance()) {
  29. notifier_ = std::make_unique<PublicIpAddressLocationNotifier>(
  30. base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
  31. &test_url_loader_factory_),
  32. network::TestNetworkConnectionTracker::GetInstance(),
  33. kTestGeolocationApiKey);
  34. }
  35. PublicIpAddressGeolocatorTest(const PublicIpAddressGeolocatorTest&) = delete;
  36. PublicIpAddressGeolocatorTest& operator=(
  37. const PublicIpAddressGeolocatorTest&) = delete;
  38. ~PublicIpAddressGeolocatorTest() override {}
  39. protected:
  40. void SetUp() override {
  41. // Intercept Mojo bad-message errors.
  42. mojo::SetDefaultProcessErrorHandler(
  43. base::BindRepeating(&PublicIpAddressGeolocatorTest::OnMojoBadMessage,
  44. base::Unretained(this)));
  45. receiver_set_.Add(
  46. std::make_unique<PublicIpAddressGeolocator>(
  47. PARTIAL_TRAFFIC_ANNOTATION_FOR_TESTS, notifier_.get(),
  48. base::BindRepeating(
  49. &PublicIpAddressGeolocatorTest::OnGeolocatorBadMessage,
  50. base::Unretained(this))),
  51. public_ip_address_geolocator_.BindNewPipeAndPassReceiver());
  52. }
  53. void TearDown() override {
  54. // Stop intercepting Mojo bad-message errors.
  55. mojo::SetDefaultProcessErrorHandler(base::NullCallback());
  56. }
  57. // Deal with mojo bad message.
  58. void OnMojoBadMessage(const std::string& error) {
  59. bad_messages_.push_back(error);
  60. }
  61. // Deal with PublicIpAddressGeolocator bad message.
  62. void OnGeolocatorBadMessage(const std::string& message) {
  63. receiver_set_.ReportBadMessage(message);
  64. }
  65. // Invokes QueryNextPosition on |public_ip_address_geolocator_|, and runs
  66. // |done_closure| when the response comes back.
  67. void QueryNextPosition(base::OnceClosure done_closure) {
  68. public_ip_address_geolocator_->QueryNextPosition(base::BindOnce(
  69. &PublicIpAddressGeolocatorTest::OnQueryNextPositionResponse,
  70. base::Unretained(this), std::move(done_closure)));
  71. }
  72. // Callback for QueryNextPosition() that records the result in |position_| and
  73. // then invokes |done_closure|.
  74. void OnQueryNextPositionResponse(base::OnceClosure done_closure,
  75. mojom::GeopositionPtr position) {
  76. position_ = std::move(position);
  77. std::move(done_closure).Run();
  78. }
  79. // Result of the latest completed call to QueryNextPosition.
  80. mojom::GeopositionPtr position_;
  81. // UniqueReceiverSet to mojom::Geolocation.
  82. mojo::UniqueReceiverSet<mojom::Geolocation> receiver_set_;
  83. // Test task runner.
  84. base::test::TaskEnvironment task_environment_;
  85. // List of any Mojo bad-message errors raised.
  86. std::vector<std::string> bad_messages_;
  87. // Test NetworkConnectionTracker for PublicIpAddressLocationNotifier.
  88. std::unique_ptr<network::TestNetworkConnectionTracker>
  89. network_connection_tracker_;
  90. // PublicIpAddressGeolocator requires a notifier.
  91. std::unique_ptr<PublicIpAddressLocationNotifier> notifier_;
  92. // The object under test.
  93. mojo::Remote<mojom::Geolocation> public_ip_address_geolocator_;
  94. // Test URLLoaderFactory for handling requests to the geolocation API.
  95. network::TestURLLoaderFactory test_url_loader_factory_;
  96. };
  97. // Basic test of a client invoking QueryNextPosition.
  98. TEST_F(PublicIpAddressGeolocatorTest, BindAndQuery) {
  99. // Invoke QueryNextPosition.
  100. base::RunLoop loop;
  101. QueryNextPosition(loop.QuitClosure());
  102. ASSERT_EQ(1, test_url_loader_factory_.NumPending());
  103. const std::string& request_url =
  104. test_url_loader_factory_.pending_requests()->back().request.url.spec();
  105. EXPECT_TRUE(
  106. base::StartsWith("https://www.googleapis.com/geolocation/v1/geolocate",
  107. request_url, base::CompareCase::SENSITIVE));
  108. // Issue a valid response.
  109. test_url_loader_factory_.AddResponse(request_url, R"({
  110. "accuracy": 100.0,
  111. "location": {
  112. "lat": 10.0,
  113. "lng": 20.0
  114. }
  115. })",
  116. net::HTTP_OK);
  117. // Wait for QueryNextPosition to return.
  118. loop.Run();
  119. EXPECT_THAT(position_->accuracy, testing::Eq(100.0));
  120. EXPECT_THAT(position_->latitude, testing::Eq(10.0));
  121. EXPECT_THAT(position_->longitude, testing::Eq(20.0));
  122. EXPECT_THAT(bad_messages_, testing::IsEmpty());
  123. }
  124. // Tests that multiple overlapping calls to QueryNextPosition result in a
  125. // connection error and reports a bad message.
  126. TEST_F(PublicIpAddressGeolocatorTest, ProhibitedOverlappingCalls) {
  127. base::RunLoop loop;
  128. public_ip_address_geolocator_.set_disconnect_handler(loop.QuitClosure());
  129. // Issue two overlapping calls to QueryNextPosition.
  130. QueryNextPosition(base::NullCallback());
  131. QueryNextPosition(base::NullCallback());
  132. // This terminates only in case of connection error, which we expect.
  133. loop.Run();
  134. // Verify that the geolocator reported a bad message.
  135. EXPECT_THAT(bad_messages_, testing::SizeIs(1));
  136. }
  137. } // namespace
  138. } // namespace device