diff options
author | bulach@chromium.org <bulach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-15 13:29:33 +0000 |
---|---|---|
committer | bulach@chromium.org <bulach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-15 13:29:33 +0000 |
commit | e90a045f85d852e2d70c422456d963c93b42d37f (patch) | |
tree | 63048b6cdc21ba83505acba63fc64f26a6c402cf /chrome/browser/geolocation | |
parent | 857e79dae449847fe9045034039e57b1433ddb38 (diff) | |
download | chromium_src-e90a045f85d852e2d70c422456d963c93b42d37f.zip chromium_src-e90a045f85d852e2d70c422456d963c93b42d37f.tar.gz chromium_src-e90a045f85d852e2d70c422456d963c93b42d37f.tar.bz2 |
Uses MockLocationProvider on GeolocationBrowserTest.
TEST=geolocation_browsertest.cc
Review URL: http://codereview.chromium.org/661371
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@41581 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/geolocation')
-rw-r--r-- | chrome/browser/geolocation/geolocation_browsertest.cc | 239 |
1 files changed, 172 insertions, 67 deletions
diff --git a/chrome/browser/geolocation/geolocation_browsertest.cc b/chrome/browser/geolocation/geolocation_browsertest.cc index 3694e22..b2f0656 100644 --- a/chrome/browser/geolocation/geolocation_browsertest.cc +++ b/chrome/browser/geolocation/geolocation_browsertest.cc @@ -3,10 +3,13 @@ // found in the LICENSE file. #include "base/string_util.h" +#include "base/waitable_event.h" #include "chrome/browser/app_modal_dialog.h" #include "chrome/browser/browser.h" #include "chrome/browser/browser_list.h" +#include "chrome/browser/dom_operation_notification_details.h" #include "chrome/browser/geolocation/location_arbitrator.h" +#include "chrome/browser/geolocation/location_provider.h" #include "chrome/browser/geolocation/mock_location_provider.h" #include "chrome/browser/profile.h" #include "chrome/browser/renderer_host/render_view_host.h" @@ -22,13 +25,36 @@ #include "chrome/test/ui_test_utils.h" #include "net/base/net_util.h" -class InfobarNotificationObserver : public NotificationObserver { +class GeolocationNotificationObserver : public NotificationObserver { public: - InfobarNotificationObserver() : infobar_(NULL) { + GeolocationNotificationObserver() : infobar_(NULL) { } - void Add(NotificationType notification_type) { - registrar_.Add(this, notification_type, NotificationService::AllSources()); + void ObserveInfobarAddedNotification() { + registrar_.Add(this, NotificationType::TAB_CONTENTS_INFOBAR_ADDED, + NotificationService::AllSources()); + } + + void ObserveInfobarRemovedNotification() { + registrar_.Add(this, NotificationType::TAB_CONTENTS_INFOBAR_REMOVED, + NotificationService::AllSources()); + } + + void ObserveDOMOperationResponseNotification() { + registrar_.Add(this, NotificationType::DOM_OPERATION_RESPONSE, + NotificationService::AllSources()); + } + + void ExecuteJavaScript(RenderViewHost* render_view_host, + const std::string& original_script) { + LOG(WARNING) << "will run " << original_script; + ObserveDOMOperationResponseNotification(); + std::string script = StringPrintf( + "window.domAutomationController.setAutomationId(0);" + "window.domAutomationController.send(%s);", original_script.c_str()); + render_view_host->ExecuteJavascriptInWebFrame(L"", UTF8ToWide(script)); + ui_test_utils::RunMessageLoop(); + LOG(WARNING) << "ran " << original_script; } // NotificationObserver @@ -42,13 +68,66 @@ class InfobarNotificationObserver : public NotificationObserver { MessageLoopForUI::current()->Quit(); } else if (type.value == NotificationType::TAB_CONTENTS_INFOBAR_REMOVED) { infobar_ = NULL; + } else if (type == NotificationType::DOM_OPERATION_RESPONSE) { + Details<DomOperationNotificationDetails> dom_op_details(details); + javascript_response_ = dom_op_details->json(); + LOG(WARNING) << "javascript_response " << javascript_response_; + MessageLoopForUI::current()->Quit(); } } NotificationRegistrar registrar_; InfoBarDelegate* infobar_; + std::string javascript_response_; +}; + +void NotifyGeopositionOnIOThread(const Geoposition& geoposition) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); + DCHECK(MockLocationProvider::instance_); + MockLocationProvider::instance_->position_ = geoposition; + MockLocationProvider::instance_->UpdateListeners(); + LOG(WARNING) << "MockLocationProvider listeners updated"; +} + +// This class is used so that we can block the UI thread until +// LocationArbitrator is fully setup and has acquired the MockLocationProvider. +// This setup occurs on the IO thread within a message loop that is running a +// javascript call. We can't simply MessageLoopForUI::current()->Quit() +// otherwise we won't be able to fetch the javascript result. +class MockLocationProviderSetup { + public: + MockLocationProviderSetup() : mock_transfer_event_(true, false) { + DCHECK(!instance_); + instance_ = this; + GeolocationArbitrator::SetProviderFactoryForTest(&MockCreator); + } + + ~MockLocationProviderSetup() { + DCHECK(instance_ == this); + instance_ = NULL; + GeolocationArbitrator::SetProviderFactoryForTest(NULL); + } + + void BlockForArbitratorSetup() { + LOG(WARNING) << "will block for arbitrator setup"; + mock_transfer_event_.Wait(); + EXPECT_TRUE(MockLocationProvider::instance_); + LOG(WARNING) << "arbitrator setup"; + } + + static LocationProviderBase* MockCreator() { + LOG(WARNING) << "will create mock"; + LocationProviderBase* mock = NewMockLocationProvider(); + instance_->mock_transfer_event_.Signal(); + return mock; + } + + static MockLocationProviderSetup* instance_; + base::WaitableEvent mock_transfer_event_; }; +MockLocationProviderSetup* MockLocationProviderSetup::instance_ = NULL; + // This is a browser test for Geolocation. // It exercises various integration points from javascript <-> browser: // 1. Infobar is displayed when a geolocation is requested from an unauthorized @@ -71,10 +150,11 @@ class GeolocationBrowserTest : public InProcessBrowserTest { }; void Initialize(InitializationOptions options) { - GeolocationArbitrator::SetProviderFactoryForTest(&NewMockLocationProvider); - if (!server_.get()) { + if (!server_.get()) server_ = StartHTTPServer(); - } + if (!mock_location_provider_setup_.get()) + mock_location_provider_setup_.reset(new MockLocationProviderSetup); + GURL url = server_->TestServerPage("files/geolocation/simple.html"); LOG(WARNING) << "before navigate"; if (options == INITIALIZATION_OFFTHERECORD) { @@ -91,49 +171,76 @@ class GeolocationBrowserTest : public InProcessBrowserTest { } EXPECT_TRUE(current_browser_); LOG(WARNING) << "after navigate"; + } + + void AddGeolocationWatch(bool wait_for_infobar) { + GeolocationNotificationObserver notification_observer; + if (wait_for_infobar) { + // Observe infobar notification. + notification_observer.ObserveInfobarAddedNotification(); + } - int watch_id = 0; - EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractInt( - current_browser_->GetSelectedTabContents()->render_view_host(), L"", - UTF8ToWide("window.domAutomationController.send(geoStart());"), - &watch_id)); - EXPECT_GT(watch_id, 0); + notification_observer.ExecuteJavaScript( + current_browser_->GetSelectedTabContents()->render_view_host(), + "geoStart()"); + EXPECT_NE("0", notification_observer.javascript_response_); LOG(WARNING) << "got geolocation watch"; + + mock_location_provider_setup_->BlockForArbitratorSetup(); + + if (wait_for_infobar) { + if (!notification_observer.infobar_) { + LOG(WARNING) << "will block for infobar"; + ui_test_utils::RunMessageLoop(); + LOG(WARNING) << "infobar created"; + } + EXPECT_TRUE(notification_observer.infobar_); + infobar_ = notification_observer.infobar_; + } + } + + Geoposition GeopositionFromLatLong(double latitude, double longitude) { + Geoposition geoposition; + geoposition.latitude = latitude; + geoposition.longitude = longitude; + geoposition.accuracy = 0; + geoposition.error_code = Geoposition::ERROR_CODE_NONE; + geoposition.timestamp = 0; + EXPECT_TRUE(geoposition.IsValidFix()); + return geoposition; } void SendGeoposition(bool wait_for_infobar, const Geoposition& geoposition) { - InfobarNotificationObserver infobar_notification_observer; + GeolocationNotificationObserver notification_observer; if (wait_for_infobar) { // Observe infobar notification. - infobar_notification_observer.Add( - NotificationType::TAB_CONTENTS_INFOBAR_ADDED); + notification_observer.ObserveInfobarAddedNotification(); } // Sending the Geoposition makes webkit trigger the permission request flow. // If the origin is already allowed, no infobar will be displayed. - LOG(WARNING) << "will send geoposition"; - RenderViewHost* render_view_host = - current_browser_->GetSelectedTabContents()->render_view_host(); - render_view_host->Send( - new ViewMsg_Geolocation_PositionUpdated( - render_view_host->routing_id(), geoposition)); - LOG(WARNING) << "geoposition sent"; + LOG(WARNING) << "will update geoposition"; + + // MockLocationProvider must have been created. + DCHECK(MockLocationProvider::instance_); + ChromeThread::PostTask(ChromeThread::IO, FROM_HERE, NewRunnableFunction( + &NotifyGeopositionOnIOThread, geoposition)); + LOG(WARNING) << "geoposition updated"; if (wait_for_infobar) { LOG(WARNING) << "will block for infobar"; ui_test_utils::RunMessageLoop(); LOG(WARNING) << "infobar created"; - EXPECT_TRUE(infobar_notification_observer.infobar_); - infobar_ = infobar_notification_observer.infobar_; + EXPECT_TRUE(notification_observer.infobar_); + infobar_ = notification_observer.infobar_; } else { WaitForJSPrompt(); } } void SetInfobarResponse(bool allowed) { - InfobarNotificationObserver infobar_notification_observer; - infobar_notification_observer.Add( - NotificationType::TAB_CONTENTS_INFOBAR_REMOVED); + GeolocationNotificationObserver notification_observer; + notification_observer.ObserveInfobarRemovedNotification(); ASSERT_TRUE(infobar_); LOG(WARNING) << "will set infobar response"; if (allowed) @@ -141,7 +248,7 @@ class GeolocationBrowserTest : public InProcessBrowserTest { else infobar_->AsConfirmInfoBarDelegate()->Cancel(); LOG(WARNING) << "infobar response set"; - EXPECT_FALSE(infobar_notification_observer.infobar_); + EXPECT_FALSE(notification_observer.infobar_); infobar_ = NULL; WaitForJSPrompt(); } @@ -156,18 +263,14 @@ class GeolocationBrowserTest : public InProcessBrowserTest { LOG(WARNING) << "closed JS prompt"; } - void CheckValueFromJavascript( + void CheckStringValueFromJavascript( const std::string& expected, const std::string& function) { - std::string js_call = StringPrintf( - "window.domAutomationController.send(%s);", function.c_str()); - std::string value; - LOG(WARNING) << "will check for JS value"; - EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString( - current_browser_->GetSelectedTabContents()->render_view_host(), L"", - UTF8ToWide(js_call), - &value)); - LOG(WARNING) << "JS value checked"; - EXPECT_EQ(expected, value); + GeolocationNotificationObserver notification_observer; + notification_observer.ExecuteJavaScript( + current_browser_->GetSelectedTabContents()->render_view_host(), + function); + EXPECT_EQ(StringPrintf("\"%s\"", expected.c_str()), + notification_observer.javascript_response_); } // InProcessBrowserTest @@ -175,11 +278,9 @@ class GeolocationBrowserTest : public InProcessBrowserTest { InProcessBrowserTest::SetUpCommandLine(command_line); command_line->AppendSwitch(switches::kEnableGeolocation); } - virtual void TearDownInProcessBrowserTestFixture() { - GeolocationArbitrator::SetProviderFactoryForTest(NULL); - } scoped_refptr<HTTPTestServer> server_; + scoped_ptr<MockLocationProviderSetup> mock_location_provider_setup_; InfoBarDelegate* infobar_; Browser* current_browser_; }; @@ -194,7 +295,8 @@ class GeolocationBrowserTest : public InProcessBrowserTest { IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, MAYBE_DisplaysPermissionBar) { Initialize(INITIALIZATION_NONE); - SendGeoposition(true, Geoposition()); + AddGeolocationWatch(false); + SendGeoposition(true, GeopositionFromLatLong(0, 0)); } #if defined(OS_MACOSX) @@ -207,10 +309,11 @@ IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, MAYBE_DisplaysPermissionBar) { IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, MAYBE_ErrorOnPermissionDenied) { Initialize(INITIALIZATION_NONE); - SendGeoposition(true, Geoposition()); + AddGeolocationWatch(false); + SendGeoposition(true, GeopositionFromLatLong(0, 0)); // Infobar was displayed, deny access and check for error code. SetInfobarResponse(false); - CheckValueFromJavascript("1", "geoGetLastError()"); + CheckStringValueFromJavascript("1", "geoGetLastError()"); } #if defined(OS_MACOSX) @@ -226,12 +329,12 @@ IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, MAYBE_NoInfobarForSecondTab) { // TODO(bulach): enable this test once we use HostContentSettingsMap instead // of files. Initialize(INITIALIZATION_NONE); - SendGeoposition(true, Geoposition()); + SendGeoposition(true, GeopositionFromLatLong(0, 0)); SetInfobarResponse(true); // Checks infobar will not be created a second tab. Initialize(INITIALIZATION_NEWTAB); - SendGeoposition(false, Geoposition()); - CheckValueFromJavascript("0", "geoGetLastError()"); + SendGeoposition(false, GeopositionFromLatLong(0, 0)); + CheckStringValueFromJavascript("0", "geoGetLastError()"); #endif } @@ -250,12 +353,12 @@ IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, MAYBE_NoInfobarForDeniedOrigin) { WritePermissionFile("{\"allowed\":false}"); // Checks no infobar will be created. Initialize(INITIALIZATION_NONE); - SendGeoposition(false, Geoposition()); - CheckValueFromJavascript("1", "geoGetLastError()"); + SendGeoposition(false, GeopositionFromLatLong(0, 0)); + CheckStringValueFromJavascript("1", "geoGetLastError()"); // Checks infobar will not be created a second tab. Initialize(INITIALIZATION_NEWTAB); - SendGeoposition(false, Geoposition()); - CheckValueFromJavascript("1", "geoGetLastError()"); + SendGeoposition(false, GeopositionFromLatLong(0, 0)); + CheckStringValueFromJavascript("1", "geoGetLastError()"); #endif } @@ -275,8 +378,8 @@ IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, WritePermissionFile("{\"allowed\":true}"); // Checks no infobar will be created and there's no error callback. Initialize(INITIALIZATION_NONE); - SendGeoposition(false, Geoposition()); - CheckValueFromJavascript("0", "geoGetLastError()"); + SendGeoposition(false, GeopositionFromLatLong(0, 0)); + CheckStringValueFromJavascript("0", "geoGetLastError()"); #endif } @@ -291,15 +394,18 @@ IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, MAYBE_InfobarForOffTheRecord) { // Checks infobar will be created for regular profile. Initialize(INITIALIZATION_NONE); - SendGeoposition(true, Geoposition()); + AddGeolocationWatch(false); + SendGeoposition(true, GeopositionFromLatLong(0, 0)); SetInfobarResponse(true); - CheckValueFromJavascript("0", "geoGetLastError()"); + CheckStringValueFromJavascript("0", "geoGetLastError()"); + // Disables further prompts from this tab. + CheckStringValueFromJavascript("false", "geoDisableAlerts()"); // Go off the record, and checks infobar will be created and an error callback // is triggered. Initialize(INITIALIZATION_OFFTHERECORD); - SendGeoposition(true, Geoposition()); + AddGeolocationWatch(true); SetInfobarResponse(false); - CheckValueFromJavascript("1", "geoGetLastError()"); + CheckStringValueFromJavascript("1", "geoGetLastError()"); } #if defined(OS_MACOSX) @@ -313,19 +419,18 @@ IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, MAYBE_InfobarForOffTheRecord) { IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, MAYBE_Geoposition) { // Checks infobar will be created. Initialize(INITIALIZATION_NONE); - SendGeoposition(true, Geoposition()); + AddGeolocationWatch(false); + SendGeoposition(true, GeopositionFromLatLong(0, 0)); // Infobar was displayed, allow access and check there's no error code. SetInfobarResponse(true); - CheckValueFromJavascript("0", "geoGetLastError()"); + CheckStringValueFromJavascript("0", "geoGetLastError()"); // Sends a Geoposition over IPC, and check it arrives in the javascript side. - Geoposition geoposition; - geoposition.latitude = 3.17; - geoposition.longitude = 4.23; + Geoposition geoposition = GeopositionFromLatLong(3.17, 4.23); SendGeoposition(false, geoposition); // Checks we have no error. - CheckValueFromJavascript("0", "geoGetLastError()"); - CheckValueFromJavascript( + CheckStringValueFromJavascript("0", "geoGetLastError()"); + CheckStringValueFromJavascript( DoubleToString(geoposition.latitude), "geoGetLastPositionLatitude()"); - CheckValueFromJavascript( + CheckStringValueFromJavascript( DoubleToString(geoposition.longitude), "geoGetLastPositionLongitude()"); } |