DevTools: cut host and port from webSocketDebuggerUrl in addition to ws:// prefix
[chromium-blink-merge.git] / content / browser / geolocation / geolocation_provider_impl_unittest.cc
blob3ba4dae1baa22819d6a26dd59f59e804cef77ac6
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.
5 #include "base/bind.h"
6 #include "base/bind_helpers.h"
7 #include "base/location.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/strings/string16.h"
12 #include "base/time/time.h"
13 #include "content/browser/geolocation/geolocation_provider_impl.h"
14 #include "content/browser/geolocation/mock_location_arbitrator.h"
15 #include "content/public/browser/access_token_store.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/test/test_browser_thread.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
21 using testing::MakeMatcher;
22 using testing::Matcher;
23 using testing::MatcherInterface;
24 using testing::MatchResultListener;
26 namespace content {
28 class LocationProviderForTestArbitrator : public GeolocationProviderImpl {
29 public:
30 LocationProviderForTestArbitrator() : mock_arbitrator_(NULL) {}
31 ~LocationProviderForTestArbitrator() override {}
33 // Only valid for use on the geolocation thread.
34 MockLocationArbitrator* mock_arbitrator() const {
35 return mock_arbitrator_;
38 protected:
39 // GeolocationProviderImpl implementation:
40 LocationArbitrator* CreateArbitrator() override;
42 private:
43 MockLocationArbitrator* mock_arbitrator_;
46 LocationArbitrator* LocationProviderForTestArbitrator::CreateArbitrator() {
47 DCHECK(mock_arbitrator_ == NULL);
48 mock_arbitrator_ = new MockLocationArbitrator;
49 return mock_arbitrator_;
52 class GeolocationObserver {
53 public:
54 virtual ~GeolocationObserver() {}
55 virtual void OnLocationUpdate(const Geoposition& position) = 0;
58 class MockGeolocationObserver : public GeolocationObserver {
59 public:
60 MOCK_METHOD1(OnLocationUpdate, void(const Geoposition& position));
63 class AsyncMockGeolocationObserver : public MockGeolocationObserver {
64 public:
65 void OnLocationUpdate(const Geoposition& position) override {
66 MockGeolocationObserver::OnLocationUpdate(position);
67 base::MessageLoop::current()->Quit();
71 class MockGeolocationCallbackWrapper {
72 public:
73 MOCK_METHOD1(Callback, void(const Geoposition& position));
76 class GeopositionEqMatcher
77 : public MatcherInterface<const Geoposition&> {
78 public:
79 explicit GeopositionEqMatcher(const Geoposition& expected)
80 : expected_(expected) {}
82 bool MatchAndExplain(const Geoposition& actual,
83 MatchResultListener* listener) const override {
84 return actual.latitude == expected_.latitude &&
85 actual.longitude == expected_.longitude &&
86 actual.altitude == expected_.altitude &&
87 actual.accuracy == expected_.accuracy &&
88 actual.altitude_accuracy == expected_.altitude_accuracy &&
89 actual.heading == expected_.heading &&
90 actual.speed == expected_.speed &&
91 actual.timestamp == expected_.timestamp &&
92 actual.error_code == expected_.error_code &&
93 actual.error_message == expected_.error_message;
96 void DescribeTo(::std::ostream* os) const override {
97 *os << "which matches the expected position";
100 void DescribeNegationTo(::std::ostream* os) const override {
101 *os << "which does not match the expected position";
104 private:
105 Geoposition expected_;
107 DISALLOW_COPY_AND_ASSIGN(GeopositionEqMatcher);
110 Matcher<const Geoposition&> GeopositionEq(const Geoposition& expected) {
111 return MakeMatcher(new GeopositionEqMatcher(expected));
114 class GeolocationProviderTest : public testing::Test {
115 protected:
116 GeolocationProviderTest()
117 : message_loop_(),
118 ui_thread_(BrowserThread::UI, &message_loop_),
119 provider_(new LocationProviderForTestArbitrator) {
122 ~GeolocationProviderTest() override {}
124 LocationProviderForTestArbitrator* provider() { return provider_.get(); }
126 // Called on test thread.
127 bool ProvidersStarted();
128 void SendMockLocation(const Geoposition& position);
130 private:
131 // Called on provider thread.
132 void GetProvidersStarted(bool* started);
134 base::MessageLoop message_loop_;
135 TestBrowserThread ui_thread_;
136 scoped_ptr<LocationProviderForTestArbitrator> provider_;
140 bool GeolocationProviderTest::ProvidersStarted() {
141 DCHECK(provider_->IsRunning());
142 DCHECK(base::MessageLoop::current() == &message_loop_);
143 bool started;
144 provider_->task_runner()->PostTaskAndReply(
145 FROM_HERE, base::Bind(&GeolocationProviderTest::GetProvidersStarted,
146 base::Unretained(this), &started),
147 base::MessageLoop::QuitClosure());
148 message_loop_.Run();
149 return started;
152 void GeolocationProviderTest::GetProvidersStarted(bool* started) {
153 DCHECK(base::MessageLoop::current() == provider_->message_loop());
154 *started = provider_->mock_arbitrator()->providers_started();
157 void GeolocationProviderTest::SendMockLocation(const Geoposition& position) {
158 DCHECK(provider_->IsRunning());
159 DCHECK(base::MessageLoop::current() == &message_loop_);
160 provider_->task_runner()->PostTask(
161 FROM_HERE, base::Bind(&GeolocationProviderImpl::OnLocationUpdate,
162 base::Unretained(provider_.get()), position));
165 // Regression test for http://crbug.com/59377
166 TEST_F(GeolocationProviderTest, OnPermissionGrantedWithoutObservers) {
167 EXPECT_FALSE(provider()->user_did_opt_into_location_services_for_testing());
168 provider()->UserDidOptIntoLocationServices();
169 EXPECT_TRUE(provider()->user_did_opt_into_location_services_for_testing());
172 void DummyFunction(const Geoposition& position) {
175 TEST_F(GeolocationProviderTest, StartStop) {
176 EXPECT_FALSE(provider()->IsRunning());
177 GeolocationProviderImpl::LocationUpdateCallback callback =
178 base::Bind(&DummyFunction);
179 scoped_ptr<content::GeolocationProvider::Subscription> subscription =
180 provider()->AddLocationUpdateCallback(callback, false);
181 EXPECT_TRUE(provider()->IsRunning());
182 EXPECT_TRUE(ProvidersStarted());
184 subscription.reset();
186 EXPECT_FALSE(ProvidersStarted());
187 EXPECT_TRUE(provider()->IsRunning());
190 TEST_F(GeolocationProviderTest, StalePositionNotSent) {
191 Geoposition first_position;
192 first_position.latitude = 12;
193 first_position.longitude = 34;
194 first_position.accuracy = 56;
195 first_position.timestamp = base::Time::Now();
197 AsyncMockGeolocationObserver first_observer;
198 GeolocationProviderImpl::LocationUpdateCallback first_callback = base::Bind(
199 &MockGeolocationObserver::OnLocationUpdate,
200 base::Unretained(&first_observer));
201 EXPECT_CALL(first_observer, OnLocationUpdate(GeopositionEq(first_position)));
202 scoped_ptr<content::GeolocationProvider::Subscription> subscription =
203 provider()->AddLocationUpdateCallback(first_callback, false);
204 SendMockLocation(first_position);
205 base::MessageLoop::current()->Run();
207 subscription.reset();
209 Geoposition second_position;
210 second_position.latitude = 13;
211 second_position.longitude = 34;
212 second_position.accuracy = 56;
213 second_position.timestamp = base::Time::Now();
215 AsyncMockGeolocationObserver second_observer;
217 // After adding a second observer, check that no unexpected position update
218 // is sent.
219 EXPECT_CALL(second_observer, OnLocationUpdate(testing::_)).Times(0);
220 GeolocationProviderImpl::LocationUpdateCallback second_callback = base::Bind(
221 &MockGeolocationObserver::OnLocationUpdate,
222 base::Unretained(&second_observer));
223 scoped_ptr<content::GeolocationProvider::Subscription> subscription2 =
224 provider()->AddLocationUpdateCallback(second_callback, false);
225 base::MessageLoop::current()->RunUntilIdle();
227 // The second observer should receive the new position now.
228 EXPECT_CALL(second_observer,
229 OnLocationUpdate(GeopositionEq(second_position)));
230 SendMockLocation(second_position);
231 base::MessageLoop::current()->Run();
233 subscription2.reset();
234 EXPECT_FALSE(ProvidersStarted());
237 TEST_F(GeolocationProviderTest, OverrideLocationForTesting) {
238 Geoposition position;
239 position.error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
240 provider()->OverrideLocationForTesting(position);
241 // Adding an observer when the location is overridden should synchronously
242 // update the observer with our overridden position.
243 MockGeolocationObserver mock_observer;
244 EXPECT_CALL(mock_observer, OnLocationUpdate(GeopositionEq(position)));
245 GeolocationProviderImpl::LocationUpdateCallback callback = base::Bind(
246 &MockGeolocationObserver::OnLocationUpdate,
247 base::Unretained(&mock_observer));
248 scoped_ptr<content::GeolocationProvider::Subscription> subscription =
249 provider()->AddLocationUpdateCallback(callback, false);
250 subscription.reset();
251 // Wait for the providers to be stopped now that all clients are gone.
252 EXPECT_FALSE(ProvidersStarted());
255 } // namespace content