// Copyright 2013 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 "base/basictypes.h" #include "base/bind.h" #include "base/callback.h" #include "base/command_line.h" #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" #include "base/message_loop/message_loop.h" #include "chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/url_constants.h" #include "chrome/test/base/ui_test_utils.cc" #include "chrome/test/base/web_ui_browsertest.h" namespace local_discovery { namespace { const char kSampleServiceName[] = "myService._privet._tcp.local"; class TestMessageLoopCondition { public: TestMessageLoopCondition() : signaled_(false), waiting_(false) { } ~TestMessageLoopCondition() { } // Signal a waiting method that it can continue executing. void Signal() { signaled_ = true; if (waiting_) base::MessageLoop::current()->Quit(); } // Pause execution and recursively run the message loop until |Signal()| is // called. Do not pause if |Signal()| has already been called. void Wait() { if (!signaled_) { waiting_ = true; base::MessageLoop::current()->Run(); waiting_ = false; } } private: bool signaled_; bool waiting_; DISALLOW_COPY_AND_ASSIGN(TestMessageLoopCondition); }; class FakePrivetDeviceLister : public PrivetDeviceLister { public: explicit FakePrivetDeviceLister(const base::Closure& discover_devices_called) : discover_devices_called_(discover_devices_called) { } virtual ~FakePrivetDeviceLister() { } // PrivetDeviceLister implementation. virtual void Start() OVERRIDE { } virtual void DiscoverNewDevices(bool force_referesh) OVERRIDE { discover_devices_called_.Run(); } void set_delegate(Delegate* delegate) { delegate_ = delegate; } Delegate* delegate() { return delegate_; } private: Delegate* delegate_; base::Closure discover_devices_called_; DISALLOW_COPY_AND_ASSIGN(FakePrivetDeviceLister); }; class FakeLocalDiscoveryUIFactory : public LocalDiscoveryUIHandler::Factory { public: explicit FakeLocalDiscoveryUIFactory( scoped_ptr privet_lister) { owned_privet_lister_ = privet_lister.Pass(); privet_lister_ = owned_privet_lister_.get(); LocalDiscoveryUIHandler::SetFactory(this); } virtual ~FakeLocalDiscoveryUIFactory() { LocalDiscoveryUIHandler::SetFactory(NULL); } // LocalDiscoveryUIHandler::Factory implementation. virtual LocalDiscoveryUIHandler* CreateLocalDiscoveryUIHandler() OVERRIDE { DCHECK(owned_privet_lister_); // This factory is a one-use factory. scoped_ptr handler( new LocalDiscoveryUIHandler( owned_privet_lister_.PassAs())); privet_lister_->set_delegate(handler.get()); return handler.release(); } FakePrivetDeviceLister* privet_lister() { return privet_lister_; } private: // FakePrivetDeviceLister is owned either by the factory or, once it creates a // LocalDiscoveryUI, by the LocalDiscoveryUI. |privet_lister_| points to the // FakePrivetDeviceLister whereas |owned_privet_lister_| manages the ownership // of the pointer when it is owned by the factory. scoped_ptr owned_privet_lister_; FakePrivetDeviceLister* privet_lister_; DISALLOW_COPY_AND_ASSIGN(FakeLocalDiscoveryUIFactory); }; class LocalDiscoveryUITest : public WebUIBrowserTest { public: LocalDiscoveryUITest() { } virtual ~LocalDiscoveryUITest() { } virtual void SetUpOnMainThread() OVERRIDE { WebUIBrowserTest::SetUpOnMainThread(); scoped_ptr fake_lister; fake_lister.reset(new FakePrivetDeviceLister( base::Bind(&TestMessageLoopCondition::Signal, base::Unretained(&condition_devices_listed_)))); ui_factory_.reset(new FakeLocalDiscoveryUIFactory( fake_lister.Pass())); AddLibrary(base::FilePath(FILE_PATH_LITERAL("local_discovery_ui_test.js"))); } virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { WebUIBrowserTest::SetUpCommandLine(command_line); } FakeLocalDiscoveryUIFactory* ui_factory() { return ui_factory_.get(); } TestMessageLoopCondition& condition_devices_listed() { return condition_devices_listed_; } private: scoped_ptr ui_factory_; TestMessageLoopCondition condition_devices_listed_; DISALLOW_COPY_AND_ASSIGN(LocalDiscoveryUITest); }; IN_PROC_BROWSER_TEST_F(LocalDiscoveryUITest, EmptyTest) { ui_test_utils::NavigateToURL(browser(), GURL( chrome::kChromeUIDevicesURL)); condition_devices_listed().Wait(); EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("checkNoDevices")); } IN_PROC_BROWSER_TEST_F(LocalDiscoveryUITest, AddRowTest) { ui_test_utils::NavigateToURL(browser(), GURL( chrome::kChromeUIDevicesURL)); condition_devices_listed().Wait(); DeviceDescription description; description.name = "Sample device"; description.description = "Sample device description"; ui_factory()->privet_lister()->delegate()->DeviceChanged( true, kSampleServiceName, description); EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("checkOneDevice")); ui_factory()->privet_lister()->delegate()->DeviceRemoved( kSampleServiceName); EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("checkNoDevices")); } } // namespace } // namespace local_discovery