Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(628)

Unified Diff: content/browser/geolocation/geolocation_provider_impl_unittest.cc

Issue 2188933002: Revert of Reland: Geolocation: move from content/browser to device/ (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/geolocation/geolocation_provider_impl_unittest.cc
diff --git a/content/browser/geolocation/geolocation_provider_impl_unittest.cc b/content/browser/geolocation/geolocation_provider_impl_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..62506f9688be36aeffcedc9a655eeba3b1f4caf9
--- /dev/null
+++ b/content/browser/geolocation/geolocation_provider_impl_unittest.cc
@@ -0,0 +1,262 @@
+// Copyright 2014 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 "content/browser/geolocation/geolocation_provider_impl.h"
+
+#include <memory>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/location.h"
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "base/memory/ref_counted.h"
+#include "base/run_loop.h"
+#include "base/single_thread_task_runner.h"
+#include "base/strings/string16.h"
+#include "base/time/time.h"
+#include "content/browser/geolocation/mock_location_arbitrator.h"
+#include "content/public/browser/access_token_store.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/test/test_browser_thread.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::MakeMatcher;
+using testing::Matcher;
+using testing::MatcherInterface;
+using testing::MatchResultListener;
+
+namespace content {
+
+class LocationProviderForTestArbitrator : public GeolocationProviderImpl {
+ public:
+ LocationProviderForTestArbitrator() : mock_arbitrator_(NULL) {}
+ ~LocationProviderForTestArbitrator() override {}
+
+ // Only valid for use on the geolocation thread.
+ MockLocationArbitrator* mock_arbitrator() const {
+ return mock_arbitrator_;
+ }
+
+ protected:
+ // GeolocationProviderImpl implementation:
+ std::unique_ptr<LocationArbitrator> CreateArbitrator() override;
+
+ private:
+ // An alias to the arbitrator stored in the super class, where it is owned.
+ MockLocationArbitrator* mock_arbitrator_;
+};
+
+std::unique_ptr<LocationArbitrator>
+LocationProviderForTestArbitrator::CreateArbitrator() {
+ DCHECK(mock_arbitrator_ == NULL);
+ mock_arbitrator_ = new MockLocationArbitrator;
+ return base::WrapUnique(mock_arbitrator_);
+}
+
+class GeolocationObserver {
+ public:
+ virtual ~GeolocationObserver() {}
+ virtual void OnLocationUpdate(const Geoposition& position) = 0;
+};
+
+class MockGeolocationObserver : public GeolocationObserver {
+ public:
+ MOCK_METHOD1(OnLocationUpdate, void(const Geoposition& position));
+};
+
+class AsyncMockGeolocationObserver : public MockGeolocationObserver {
+ public:
+ void OnLocationUpdate(const Geoposition& position) override {
+ MockGeolocationObserver::OnLocationUpdate(position);
+ base::MessageLoop::current()->QuitWhenIdle();
+ }
+};
+
+class MockGeolocationCallbackWrapper {
+ public:
+ MOCK_METHOD1(Callback, void(const Geoposition& position));
+};
+
+class GeopositionEqMatcher
+ : public MatcherInterface<const Geoposition&> {
+ public:
+ explicit GeopositionEqMatcher(const Geoposition& expected)
+ : expected_(expected) {}
+
+ bool MatchAndExplain(const Geoposition& actual,
+ MatchResultListener* listener) const override {
+ return actual.latitude == expected_.latitude &&
+ actual.longitude == expected_.longitude &&
+ actual.altitude == expected_.altitude &&
+ actual.accuracy == expected_.accuracy &&
+ actual.altitude_accuracy == expected_.altitude_accuracy &&
+ actual.heading == expected_.heading &&
+ actual.speed == expected_.speed &&
+ actual.timestamp == expected_.timestamp &&
+ actual.error_code == expected_.error_code &&
+ actual.error_message == expected_.error_message;
+ }
+
+ void DescribeTo(::std::ostream* os) const override {
+ *os << "which matches the expected position";
+ }
+
+ void DescribeNegationTo(::std::ostream* os) const override {
+ *os << "which does not match the expected position";
+ }
+
+ private:
+ Geoposition expected_;
+
+ DISALLOW_COPY_AND_ASSIGN(GeopositionEqMatcher);
+};
+
+Matcher<const Geoposition&> GeopositionEq(const Geoposition& expected) {
+ return MakeMatcher(new GeopositionEqMatcher(expected));
+}
+
+class GeolocationProviderTest : public testing::Test {
+ protected:
+ GeolocationProviderTest()
+ : message_loop_(),
+ ui_thread_(BrowserThread::UI, &message_loop_),
+ provider_(new LocationProviderForTestArbitrator) {
+ }
+
+ ~GeolocationProviderTest() override {}
+
+ LocationProviderForTestArbitrator* provider() { return provider_.get(); }
+
+ // Called on test thread.
+ bool ProvidersStarted();
+ void SendMockLocation(const Geoposition& position);
+
+ private:
+ // Called on provider thread.
+ void GetProvidersStarted(bool* started);
+
+ base::MessageLoop message_loop_;
+ TestBrowserThread ui_thread_;
+ std::unique_ptr<LocationProviderForTestArbitrator> provider_;
+};
+
+
+bool GeolocationProviderTest::ProvidersStarted() {
+ DCHECK(provider_->IsRunning());
+ DCHECK(base::MessageLoop::current() == &message_loop_);
+ bool started;
+ provider_->task_runner()->PostTaskAndReply(
+ FROM_HERE, base::Bind(&GeolocationProviderTest::GetProvidersStarted,
+ base::Unretained(this), &started),
+ base::MessageLoop::QuitWhenIdleClosure());
+ base::RunLoop().Run();
+ return started;
+}
+
+void GeolocationProviderTest::GetProvidersStarted(bool* started) {
+ DCHECK(provider_->task_runner()->BelongsToCurrentThread());
+ *started = provider_->mock_arbitrator()->providers_started();
+}
+
+void GeolocationProviderTest::SendMockLocation(const Geoposition& position) {
+ DCHECK(provider_->IsRunning());
+ DCHECK(base::MessageLoop::current() == &message_loop_);
+ provider_->task_runner()->PostTask(
+ FROM_HERE, base::Bind(&GeolocationProviderImpl::OnLocationUpdate,
+ base::Unretained(provider_.get()), position));
+}
+
+// Regression test for http://crbug.com/59377
+TEST_F(GeolocationProviderTest, OnPermissionGrantedWithoutObservers) {
+ EXPECT_FALSE(provider()->user_did_opt_into_location_services_for_testing());
+ provider()->UserDidOptIntoLocationServices();
+ EXPECT_TRUE(provider()->user_did_opt_into_location_services_for_testing());
+}
+
+void DummyFunction(const Geoposition& position) {
+}
+
+TEST_F(GeolocationProviderTest, StartStop) {
+ EXPECT_FALSE(provider()->IsRunning());
+ GeolocationProviderImpl::LocationUpdateCallback callback =
+ base::Bind(&DummyFunction);
+ std::unique_ptr<content::GeolocationProvider::Subscription> subscription =
+ provider()->AddLocationUpdateCallback(callback, false);
+ EXPECT_TRUE(provider()->IsRunning());
+ EXPECT_TRUE(ProvidersStarted());
+
+ subscription.reset();
+
+ EXPECT_FALSE(ProvidersStarted());
+ EXPECT_TRUE(provider()->IsRunning());
+}
+
+TEST_F(GeolocationProviderTest, StalePositionNotSent) {
+ Geoposition first_position;
+ first_position.latitude = 12;
+ first_position.longitude = 34;
+ first_position.accuracy = 56;
+ first_position.timestamp = base::Time::Now();
+
+ AsyncMockGeolocationObserver first_observer;
+ GeolocationProviderImpl::LocationUpdateCallback first_callback = base::Bind(
+ &MockGeolocationObserver::OnLocationUpdate,
+ base::Unretained(&first_observer));
+ EXPECT_CALL(first_observer, OnLocationUpdate(GeopositionEq(first_position)));
+ std::unique_ptr<content::GeolocationProvider::Subscription> subscription =
+ provider()->AddLocationUpdateCallback(first_callback, false);
+ SendMockLocation(first_position);
+ base::RunLoop().Run();
+
+ subscription.reset();
+
+ Geoposition second_position;
+ second_position.latitude = 13;
+ second_position.longitude = 34;
+ second_position.accuracy = 56;
+ second_position.timestamp = base::Time::Now();
+
+ AsyncMockGeolocationObserver second_observer;
+
+ // After adding a second observer, check that no unexpected position update
+ // is sent.
+ EXPECT_CALL(second_observer, OnLocationUpdate(testing::_)).Times(0);
+ GeolocationProviderImpl::LocationUpdateCallback second_callback = base::Bind(
+ &MockGeolocationObserver::OnLocationUpdate,
+ base::Unretained(&second_observer));
+ std::unique_ptr<content::GeolocationProvider::Subscription> subscription2 =
+ provider()->AddLocationUpdateCallback(second_callback, false);
+ base::RunLoop().RunUntilIdle();
+
+ // The second observer should receive the new position now.
+ EXPECT_CALL(second_observer,
+ OnLocationUpdate(GeopositionEq(second_position)));
+ SendMockLocation(second_position);
+ base::RunLoop().Run();
+
+ subscription2.reset();
+ EXPECT_FALSE(ProvidersStarted());
+}
+
+TEST_F(GeolocationProviderTest, OverrideLocationForTesting) {
+ Geoposition position;
+ position.error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
+ provider()->OverrideLocationForTesting(position);
+ // Adding an observer when the location is overridden should synchronously
+ // update the observer with our overridden position.
+ MockGeolocationObserver mock_observer;
+ EXPECT_CALL(mock_observer, OnLocationUpdate(GeopositionEq(position)));
+ GeolocationProviderImpl::LocationUpdateCallback callback = base::Bind(
+ &MockGeolocationObserver::OnLocationUpdate,
+ base::Unretained(&mock_observer));
+ std::unique_ptr<content::GeolocationProvider::Subscription> subscription =
+ provider()->AddLocationUpdateCallback(callback, false);
+ subscription.reset();
+ // Wait for the providers to be stopped now that all clients are gone.
+ EXPECT_FALSE(ProvidersStarted());
+}
+
+} // namespace content
« no previous file with comments | « content/browser/geolocation/geolocation_provider_impl.cc ('k') | content/browser/geolocation/geolocation_service_context.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698