| Index: content/browser/geolocation/geolocation_provider_unittest.cc
|
| diff --git a/content/browser/geolocation/geolocation_provider_unittest.cc b/content/browser/geolocation/geolocation_provider_unittest.cc
|
| index ca1e12229a85f61b04c89469598cf0efb3ba1816..9f141a8282bd907c9e7bacbd679d5e8c00e20e7e 100644
|
| --- a/content/browser/geolocation/geolocation_provider_unittest.cc
|
| +++ b/content/browser/geolocation/geolocation_provider_unittest.cc
|
| @@ -2,215 +2,226 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -#include "base/memory/singleton.h"
|
| +#include "base/basictypes.h"
|
| +#include "base/bind.h"
|
| +#include "base/bind_helpers.h"
|
| +#include "base/compiler_specific.h"
|
| +#include "base/memory/ref_counted.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| +#include "base/message_loop.h"
|
| #include "base/synchronization/waitable_event.h"
|
| -#include "content/browser/geolocation/arbitrator_dependency_factories_for_test.h"
|
| +#include "base/time.h"
|
| +#include "content/browser/geolocation/arbitrator_dependency_factory.h"
|
| #include "content/browser/geolocation/fake_access_token_store.h"
|
| +#include "content/browser/geolocation/geolocation_observer.h"
|
| #include "content/browser/geolocation/geolocation_provider.h"
|
| #include "content/browser/geolocation/location_arbitrator.h"
|
| #include "content/browser/geolocation/mock_location_provider.h"
|
| +#include "content/public/browser/browser_thread.h"
|
| +#include "content/test/test_browser_thread.h"
|
| #include "testing/gmock/include/gmock/gmock.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| -using content::AccessTokenStore;
|
| -using content::FakeAccessTokenStore;
|
| using content::Geoposition;
|
| using testing::_;
|
| using testing::DoAll;
|
| -using testing::DoDefault;
|
| using testing::Invoke;
|
| using testing::InvokeWithoutArgs;
|
| +using testing::MakeMatcher;
|
| +using testing::Matcher;
|
| +using testing::MatcherInterface;
|
| +using testing::MatchResultListener;
|
|
|
| namespace {
|
| +class NonSingletonGeolocationProvider : public GeolocationProvider {
|
| + public:
|
| + NonSingletonGeolocationProvider() {}
|
|
|
| -class GeolocationProviderTest : public testing::Test {
|
| - protected:
|
| - GeolocationProviderTest()
|
| - : provider_(new GeolocationProvider),
|
| - dependency_factory_(
|
| - new GeolocationArbitratorDependencyFactoryWithLocationProvider(
|
| - &NewAutoSuccessMockNetworkLocationProvider))
|
| - {
|
| + virtual ~NonSingletonGeolocationProvider() {}
|
| +};
|
| +
|
| +class StartStopMockLocationProvider : public MockLocationProvider {
|
| + public:
|
| + explicit StartStopMockLocationProvider() : MockLocationProvider(&instance_) {
|
| }
|
|
|
| - ~GeolocationProviderTest() {
|
| - DefaultSingletonTraits<GeolocationProvider>::Delete(provider_);
|
| + virtual ~StartStopMockLocationProvider() {
|
| + Die();
|
| }
|
|
|
| - // testing::Test
|
| - virtual void SetUp() {
|
| - GeolocationArbitrator::SetDependencyFactoryForTest(
|
| - dependency_factory_.get());
|
| + MOCK_METHOD0(Die, void());
|
| +};
|
| +
|
| +class TestingDependencyFactory
|
| + : public DefaultGeolocationArbitratorDependencyFactory {
|
| + public:
|
| + TestingDependencyFactory(base::WaitableEvent* event) : event_(event) {
|
| }
|
|
|
| - // testing::Test
|
| - virtual void TearDown() {
|
| - provider_->Stop();
|
| - GeolocationArbitrator::SetDependencyFactoryForTest(NULL);
|
| + virtual content::AccessTokenStore* NewAccessTokenStore() OVERRIDE {
|
| + content::FakeAccessTokenStore* store = new content::FakeAccessTokenStore();
|
| + EXPECT_CALL(*store, LoadAccessTokens(_))
|
| + .WillRepeatedly(DoAll(
|
| + Invoke(store,
|
| + &content::FakeAccessTokenStore::DefaultLoadAccessTokens),
|
| + InvokeWithoutArgs(store,
|
| + &content::FakeAccessTokenStore::
|
| + NotifyDelegateTokensLoaded),
|
| + InvokeWithoutArgs(event_, &base::WaitableEvent::Signal)));
|
| + return store;
|
| }
|
|
|
| - // Message loop for main thread, as provider depends on it existing.
|
| - MessageLoop message_loop_;
|
| + virtual LocationProviderBase* NewNetworkLocationProvider(
|
| + content::AccessTokenStore* access_token_store,
|
| + net::URLRequestContextGetter* context,
|
| + const GURL& url,
|
| + const string16& access_token) OVERRIDE {
|
| + StartStopMockLocationProvider* provider =
|
| + new StartStopMockLocationProvider();
|
| + EXPECT_CALL(*provider, Die())
|
| + .Times(1)
|
| + .WillOnce(InvokeWithoutArgs(event_, &base::WaitableEvent::Signal));
|
| + return provider;
|
| + }
|
|
|
| - // Object under tests. Owned, but not a scoped_ptr due to specialized
|
| - // destruction protocol.
|
| - GeolocationProvider* provider_;
|
| + virtual LocationProviderBase* NewSystemLocationProvider() OVERRIDE {
|
| + return NULL;
|
| + }
|
|
|
| - scoped_refptr<GeolocationArbitratorDependencyFactory> dependency_factory_;
|
| + private:
|
| + base::WaitableEvent* event_;
|
| };
|
|
|
| -// Regression test for http://crbug.com/59377
|
| -TEST_F(GeolocationProviderTest, OnPermissionGrantedWithoutObservers) {
|
| - EXPECT_FALSE(provider_->HasPermissionBeenGranted());
|
| - provider_->OnPermissionGranted();
|
| - EXPECT_TRUE(provider_->HasPermissionBeenGranted());
|
| -}
|
| -
|
| class NullGeolocationObserver : public GeolocationObserver {
|
| public:
|
| // GeolocationObserver
|
| - virtual void OnLocationUpdate(const Geoposition& position) {}
|
| + virtual void OnLocationUpdate(const content::Geoposition& position) {}
|
| };
|
|
|
| class MockGeolocationObserver : public GeolocationObserver {
|
| public:
|
| // GeolocationObserver
|
| - MOCK_METHOD1(OnLocationUpdate, void(const Geoposition& position));
|
| + MOCK_METHOD1(OnLocationUpdate, void(const content::Geoposition& position));
|
| };
|
|
|
| -class StartStopMockLocationProvider : public MockLocationProvider {
|
| +class MockGeolocationCallbackWrapper {
|
| public:
|
| - explicit StartStopMockLocationProvider(MessageLoop* test_loop)
|
| - : MockLocationProvider(&instance_),
|
| - test_loop_(test_loop) {
|
| - }
|
| + MOCK_METHOD1(Callback, void(const content::Geoposition& position));
|
| +};
|
|
|
| - virtual ~StartStopMockLocationProvider() {
|
| - Die();
|
| +class GeopositionEqMatcher
|
| + : public MatcherInterface<const content::Geoposition&> {
|
| + public:
|
| + explicit GeopositionEqMatcher(const content::Geoposition& expected)
|
| + : expected_(expected) {}
|
| +
|
| + virtual bool MatchAndExplain(const content::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;
|
| }
|
|
|
| - MOCK_METHOD0(Die, void());
|
| -
|
| - virtual bool StartProvider(bool high_accuracy) {
|
| - bool result = MockLocationProvider::StartProvider(high_accuracy);
|
| - test_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure());
|
| - return result;
|
| + virtual void DescribeTo(::std::ostream* os) const OVERRIDE {
|
| + *os << "which matches the expected position";
|
| }
|
|
|
| - virtual void StopProvider() {
|
| - MockLocationProvider::StopProvider();
|
| - test_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure());
|
| + virtual void DescribeNegationTo(::std::ostream* os) const OVERRIDE{
|
| + *os << "which does not match the expected position";
|
| }
|
|
|
| private:
|
| - MessageLoop* test_loop_;
|
| -};
|
| -
|
| -class MockDependencyFactory : public GeolocationArbitratorDependencyFactory {
|
| - public:
|
| - MockDependencyFactory(MessageLoop* test_loop_,
|
| - AccessTokenStore* access_token_store)
|
| - : test_loop_(test_loop_),
|
| - access_token_store_(access_token_store) {
|
| - }
|
| + content::Geoposition expected_;
|
|
|
| - virtual net::URLRequestContextGetter* GetContextGetter() {
|
| - return NULL;
|
| - }
|
| -
|
| - virtual GeolocationArbitrator::GetTimeNow GetTimeFunction() {
|
| - return base::Time::Now;
|
| - }
|
| + DISALLOW_COPY_AND_ASSIGN(GeopositionEqMatcher);
|
| +};
|
|
|
| - virtual AccessTokenStore* NewAccessTokenStore() {
|
| - return access_token_store_.get();
|
| - }
|
| +Matcher<const content::Geoposition&> GeopositionEq(
|
| + const content::Geoposition& expected) {
|
| + return MakeMatcher(new GeopositionEqMatcher(expected));
|
| +}
|
|
|
| - virtual LocationProviderBase* NewNetworkLocationProvider(
|
| - AccessTokenStore* access_token_store,
|
| - net::URLRequestContextGetter* context,
|
| - const GURL& url,
|
| - const string16& access_token) {
|
| - return new StartStopMockLocationProvider(test_loop_);
|
| +class GeolocationProviderTest : public testing::Test {
|
| + protected:
|
| + GeolocationProviderTest()
|
| + : message_loop_(),
|
| + io_thread_(content::BrowserThread::IO, &message_loop_),
|
| + event_(false, false),
|
| + dependency_factory_(new TestingDependencyFactory(&event_)),
|
| + provider_(new NonSingletonGeolocationProvider) {
|
| + GeolocationArbitrator::SetDependencyFactoryForTest(
|
| + dependency_factory_.get());
|
| }
|
|
|
| - virtual LocationProviderBase* NewSystemLocationProvider() {
|
| - return NULL;
|
| + ~GeolocationProviderTest() {
|
| + GeolocationArbitrator::SetDependencyFactoryForTest(NULL);
|
| }
|
|
|
| - private:
|
| - virtual ~MockDependencyFactory() {}
|
| + MessageLoop message_loop_;
|
| + content::TestBrowserThread io_thread_;
|
|
|
| - MessageLoop* test_loop_;
|
| - scoped_refptr<AccessTokenStore> access_token_store_;
|
| + base::WaitableEvent event_;
|
| + scoped_refptr<TestingDependencyFactory> dependency_factory_;
|
| + scoped_ptr<NonSingletonGeolocationProvider> provider_;
|
| };
|
|
|
| -TEST_F(GeolocationProviderTest, StartStop) {
|
| - scoped_refptr<FakeAccessTokenStore> fake_access_token_store =
|
| - new FakeAccessTokenStore;
|
| - scoped_refptr<GeolocationArbitratorDependencyFactory> dependency_factory =
|
| - new MockDependencyFactory(&message_loop_, fake_access_token_store.get());
|
| - base::WaitableEvent event(false, false);
|
| -
|
| - EXPECT_CALL(*(fake_access_token_store.get()), LoadAccessTokens(_))
|
| - .Times(1)
|
| - .WillOnce(DoAll(Invoke(fake_access_token_store.get(),
|
| - &FakeAccessTokenStore::DefaultLoadAccessTokens),
|
| - InvokeWithoutArgs(&event, &base::WaitableEvent::Signal)));
|
| -
|
| - GeolocationArbitrator::SetDependencyFactoryForTest(dependency_factory.get());
|
| +// Regression test for http://crbug.com/59377
|
| +TEST_F(GeolocationProviderTest, OnPermissionGrantedWithoutObservers) {
|
| + EXPECT_FALSE(provider_->HasPermissionBeenGranted());
|
| + provider_->OnPermissionGranted();
|
| + EXPECT_TRUE(provider_->HasPermissionBeenGranted());
|
| +}
|
|
|
| +TEST_F(GeolocationProviderTest, StartStop) {
|
| EXPECT_FALSE(provider_->IsRunning());
|
| NullGeolocationObserver null_observer;
|
| GeolocationObserverOptions options;
|
| provider_->AddObserver(&null_observer, options);
|
| EXPECT_TRUE(provider_->IsRunning());
|
| // Wait for token load request from the arbitrator to come through.
|
| - event.Wait();
|
| - event.Reset();
|
| - // The GeolocationArbitrator won't start the providers until it has
|
| - // finished loading access tokens.
|
| - fake_access_token_store->NotifyDelegateTokensLoaded();
|
| - message_loop_.Run();
|
| + event_.Wait();
|
| +
|
| + event_.Reset();
|
| EXPECT_EQ(MockLocationProvider::instance_->state_,
|
| MockLocationProvider::LOW_ACCURACY);
|
| - EXPECT_CALL(*(static_cast<StartStopMockLocationProvider*>(
|
| - MockLocationProvider::instance_)),
|
| - Die())
|
| - .Times(1)
|
| - .WillOnce(InvokeWithoutArgs(&event, &base::WaitableEvent::Signal));
|
| provider_->RemoveObserver(&null_observer);
|
| // Wait for the providers to be stopped.
|
| - event.Wait();
|
| - event.Reset();
|
| + event_.Wait();
|
| EXPECT_TRUE(provider_->IsRunning());
|
| -
|
| - GeolocationArbitrator::SetDependencyFactoryForTest(NULL);
|
| }
|
|
|
| TEST_F(GeolocationProviderTest, OverrideLocationForTesting) {
|
| - scoped_refptr<FakeAccessTokenStore> fake_access_token_store =
|
| - new FakeAccessTokenStore;
|
| - scoped_refptr<GeolocationArbitratorDependencyFactory> dependency_factory =
|
| - new MockDependencyFactory(&message_loop_, fake_access_token_store.get());
|
| + content::Geoposition position;
|
| + position.error_code = content::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(*(fake_access_token_store.get()), LoadAccessTokens(_));
|
| -
|
| - GeolocationArbitrator::SetDependencyFactoryForTest(dependency_factory.get());
|
| -
|
| - Geoposition override_position;
|
| - override_position.error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
|
| - provider_->OverrideLocationForTesting(override_position);
|
| - // Adding an observer when the location is overriden should synchronously
|
| - // update the observer with our overriden position.
|
| - EXPECT_CALL(mock_observer, OnLocationUpdate(
|
| - testing::Field(
|
| - &Geoposition::error_code,
|
| - testing::Eq(Geoposition::ERROR_CODE_POSITION_UNAVAILABLE))));
|
| + EXPECT_CALL(mock_observer, OnLocationUpdate(GeopositionEq(position)));
|
| provider_->AddObserver(&mock_observer, GeolocationObserverOptions());
|
| provider_->RemoveObserver(&mock_observer);
|
| +}
|
|
|
| - GeolocationArbitrator::SetDependencyFactoryForTest(NULL);
|
| +TEST_F(GeolocationProviderTest, Callback) {
|
| + MockGeolocationCallbackWrapper callback_wrapper;
|
| + provider_->RequestCallback(
|
| + base::Bind(&MockGeolocationCallbackWrapper::Callback,
|
| + base::Unretained(&callback_wrapper)));
|
| +
|
| + content::Geoposition position;
|
| + position.latitude = 12;
|
| + position.longitude = 34;
|
| + position.accuracy = 56;
|
| + position.timestamp = base::Time::Now();
|
| + EXPECT_CALL(callback_wrapper, Callback(GeopositionEq(position)));
|
| + provider_->OverrideLocationForTesting(position);
|
| }
|
|
|
| } // namespace
|
|
|