Home | History | Annotate | Download | only in extensions
      1 // Copyright (c) 2012 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.
      4 
      5 #include "chrome/browser/extensions/event_router_forwarder.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/message_loop/message_loop.h"
      9 #include "base/power_monitor/power_monitor.h"
     10 #include "base/power_monitor/power_monitor_device_source.h"
     11 #include "base/test/thread_test_helper.h"
     12 #include "chrome/browser/profiles/profile_manager.h"
     13 #include "chrome/test/base/testing_browser_process.h"
     14 #include "chrome/test/base/testing_profile.h"
     15 #include "chrome/test/base/testing_profile_manager.h"
     16 #include "content/public/test/test_browser_thread.h"
     17 #include "testing/gmock/include/gmock/gmock.h"
     18 #include "testing/gtest/include/gtest/gtest.h"
     19 #include "url/gurl.h"
     20 
     21 using content::BrowserThread;
     22 
     23 namespace extensions {
     24 
     25 namespace {
     26 
     27 const char kEventName[] = "event_name";
     28 const char kExt[] = "extension";
     29 
     30 class MockEventRouterForwarder : public EventRouterForwarder {
     31  public:
     32   MOCK_METHOD5(CallEventRouter,
     33       void(Profile*, const std::string&, const std::string&, Profile*,
     34            const GURL&));
     35 
     36   virtual void CallEventRouter(
     37       Profile* profile, const std::string& extension_id,
     38       const std::string& event_name, scoped_ptr<base::ListValue> event_args,
     39       Profile* restrict_to_profile, const GURL& event_url) {
     40     CallEventRouter(profile, extension_id, event_name,
     41                              restrict_to_profile, event_url);
     42   }
     43 
     44  protected:
     45   virtual ~MockEventRouterForwarder() {}
     46 };
     47 
     48 static void BroadcastEventToRenderers(EventRouterForwarder* event_router,
     49                                       const std::string& event_name,
     50                                       const GURL& url) {
     51   scoped_ptr<base::ListValue> args(new base::ListValue());
     52   event_router->BroadcastEventToRenderers(event_name, args.Pass(), url);
     53 }
     54 
     55 static void DispatchEventToRenderers(EventRouterForwarder* event_router,
     56                                      const std::string& event_name,
     57                                      void* profile,
     58                                      bool use_profile_to_restrict_events,
     59                                      const GURL& url) {
     60   scoped_ptr<base::ListValue> args(new base::ListValue());
     61   event_router->DispatchEventToRenderers(event_name, args.Pass(), profile,
     62                                          use_profile_to_restrict_events, url);
     63 }
     64 
     65 static void BroadcastEventToExtension(EventRouterForwarder* event_router,
     66                                       const std::string& extension,
     67                                       const std::string& event_name,
     68                                       const GURL& url) {
     69   scoped_ptr<base::ListValue> args(new base::ListValue());
     70   event_router->BroadcastEventToExtension(extension, event_name, args.Pass(),
     71                                           url);
     72 }
     73 
     74 static void DispatchEventToExtension(EventRouterForwarder* event_router,
     75                                      const std::string& extension,
     76                                      const std::string& event_name,
     77                                      void* profile,
     78                                      bool use_profile_to_restrict_events,
     79                                      const GURL& url) {
     80   scoped_ptr<base::ListValue> args(new base::ListValue());
     81   event_router->DispatchEventToExtension(
     82       extension, event_name, args.Pass(), profile,
     83       use_profile_to_restrict_events, url);
     84 }
     85 
     86 }  // namespace
     87 
     88 class EventRouterForwarderTest : public testing::Test {
     89  protected:
     90   EventRouterForwarderTest()
     91       : ui_thread_(BrowserThread::UI, &message_loop_),
     92         io_thread_(BrowserThread::IO),
     93         profile_manager_(
     94             TestingBrowserProcess::GetGlobal()) {
     95 #if defined(OS_MACOSX)
     96     base::PowerMonitorDeviceSource::AllocateSystemIOPorts();
     97 #endif
     98     scoped_ptr<base::PowerMonitorSource> power_monitor_source(
     99       new base::PowerMonitorDeviceSource());
    100     dummy.reset(new base::PowerMonitor(power_monitor_source.Pass()));
    101   }
    102 
    103   virtual void SetUp() {
    104     ASSERT_TRUE(profile_manager_.SetUp());
    105 
    106     // Inject a BrowserProcess with a ProfileManager.
    107     ASSERT_TRUE(io_thread_.Start());
    108 
    109     profile1_ = profile_manager_.CreateTestingProfile("one");
    110     profile2_ = profile_manager_.CreateTestingProfile("two");
    111   }
    112 
    113   base::MessageLoopForUI message_loop_;
    114   content::TestBrowserThread ui_thread_;
    115   content::TestBrowserThread io_thread_;
    116   TestingProfileManager profile_manager_;
    117   scoped_ptr<base::PowerMonitor> dummy;
    118   // Profiles are weak pointers, owned by ProfileManager in |browser_process_|.
    119   TestingProfile* profile1_;
    120   TestingProfile* profile2_;
    121 };
    122 
    123 TEST_F(EventRouterForwarderTest, BroadcastRendererUI) {
    124   scoped_refptr<MockEventRouterForwarder> event_router(
    125       new MockEventRouterForwarder);
    126   GURL url;
    127   EXPECT_CALL(*event_router.get(),
    128               CallEventRouter(profile1_, "", kEventName, profile1_, url));
    129   EXPECT_CALL(*event_router.get(),
    130               CallEventRouter(profile2_, "", kEventName, profile2_, url));
    131   BroadcastEventToRenderers(event_router.get(), kEventName, url);
    132 }
    133 
    134 TEST_F(EventRouterForwarderTest, BroadcastRendererUIIncognito) {
    135   scoped_refptr<MockEventRouterForwarder> event_router(
    136       new MockEventRouterForwarder);
    137   using ::testing::_;
    138   GURL url;
    139   Profile* incognito = profile1_->GetOffTheRecordProfile();
    140   EXPECT_CALL(*event_router.get(),
    141               CallEventRouter(profile1_, "", kEventName, profile1_, url));
    142   EXPECT_CALL(*event_router.get(), CallEventRouter(incognito, _, _, _, _))
    143       .Times(0);
    144   EXPECT_CALL(*event_router.get(),
    145               CallEventRouter(profile2_, "", kEventName, profile2_, url));
    146   BroadcastEventToRenderers(event_router.get(), kEventName, url);
    147 }
    148 
    149 // This is the canonical test for passing control flow from the IO thread
    150 // to the UI thread. Repeating this for all public functions of
    151 // EventRouterForwarder would not increase coverage.
    152 TEST_F(EventRouterForwarderTest, BroadcastRendererIO) {
    153   scoped_refptr<MockEventRouterForwarder> event_router(
    154       new MockEventRouterForwarder);
    155   GURL url;
    156   EXPECT_CALL(*event_router.get(),
    157               CallEventRouter(profile1_, "", kEventName, profile1_, url));
    158   EXPECT_CALL(*event_router.get(),
    159               CallEventRouter(profile2_, "", kEventName, profile2_, url));
    160   BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
    161       base::Bind(
    162           &BroadcastEventToRenderers, base::Unretained(event_router.get()),
    163           kEventName, url));
    164 
    165   // Wait for IO thread's message loop to be processed
    166   scoped_refptr<base::ThreadTestHelper> helper(new base::ThreadTestHelper(
    167       BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get()));
    168   ASSERT_TRUE(helper->Run());
    169 
    170   base::MessageLoop::current()->RunUntilIdle();
    171 }
    172 
    173 TEST_F(EventRouterForwarderTest, UnicastRendererUIRestricted) {
    174   scoped_refptr<MockEventRouterForwarder> event_router(
    175       new MockEventRouterForwarder);
    176   using ::testing::_;
    177   GURL url;
    178   EXPECT_CALL(*event_router.get(),
    179               CallEventRouter(profile1_, "", kEventName, profile1_, url));
    180   EXPECT_CALL(*event_router.get(), CallEventRouter(profile2_, _, _, _, _))
    181       .Times(0);
    182   DispatchEventToRenderers(event_router.get(), kEventName, profile1_, true,
    183                            url);
    184 }
    185 
    186 TEST_F(EventRouterForwarderTest, UnicastRendererUIRestrictedIncognito1) {
    187   scoped_refptr<MockEventRouterForwarder> event_router(
    188       new MockEventRouterForwarder);
    189   Profile* incognito = profile1_->GetOffTheRecordProfile();
    190   using ::testing::_;
    191   GURL url;
    192   EXPECT_CALL(*event_router.get(),
    193               CallEventRouter(profile1_, "", kEventName, profile1_, url));
    194   EXPECT_CALL(*event_router.get(), CallEventRouter(incognito, _, _, _, _))
    195       .Times(0);
    196   EXPECT_CALL(*event_router.get(), CallEventRouter(profile2_, _, _, _, _))
    197       .Times(0);
    198   DispatchEventToRenderers(event_router.get(), kEventName, profile1_, true,
    199                            url);
    200 }
    201 
    202 TEST_F(EventRouterForwarderTest, UnicastRendererUIRestrictedIncognito2) {
    203   scoped_refptr<MockEventRouterForwarder> event_router(
    204       new MockEventRouterForwarder);
    205   Profile* incognito = profile1_->GetOffTheRecordProfile();
    206   using ::testing::_;
    207   GURL url;
    208   EXPECT_CALL(*event_router.get(), CallEventRouter(profile1_, _, _, _, _))
    209       .Times(0);
    210   EXPECT_CALL(*event_router.get(),
    211               CallEventRouter(incognito, "", kEventName, incognito, url));
    212   EXPECT_CALL(*event_router.get(), CallEventRouter(profile2_, _, _, _, _))
    213       .Times(0);
    214   DispatchEventToRenderers(event_router.get(), kEventName, incognito, true,
    215                            url);
    216 }
    217 
    218 TEST_F(EventRouterForwarderTest, UnicastRendererUIUnrestricted) {
    219   scoped_refptr<MockEventRouterForwarder> event_router(
    220       new MockEventRouterForwarder);
    221   using ::testing::_;
    222   GURL url;
    223   EXPECT_CALL(*event_router.get(),
    224               CallEventRouter(profile1_, "", kEventName, NULL, url));
    225   EXPECT_CALL(*event_router.get(), CallEventRouter(profile2_, _, _, _, _))
    226       .Times(0);
    227   DispatchEventToRenderers(event_router.get(), kEventName, profile1_, false,
    228                            url);
    229 }
    230 
    231 TEST_F(EventRouterForwarderTest, UnicastRendererUIUnrestrictedIncognito) {
    232   scoped_refptr<MockEventRouterForwarder> event_router(
    233       new MockEventRouterForwarder);
    234   Profile* incognito = profile1_->GetOffTheRecordProfile();
    235   using ::testing::_;
    236   GURL url;
    237   EXPECT_CALL(*event_router.get(),
    238               CallEventRouter(profile1_, "", kEventName, NULL, url));
    239   EXPECT_CALL(*event_router.get(), CallEventRouter(incognito, _, _, _, _))
    240       .Times(0);
    241   EXPECT_CALL(*event_router.get(), CallEventRouter(profile2_, _, _, _, _))
    242       .Times(0);
    243   DispatchEventToRenderers(event_router.get(), kEventName, profile1_, false,
    244                            url);
    245 }
    246 
    247 TEST_F(EventRouterForwarderTest, BroadcastExtensionUI) {
    248   scoped_refptr<MockEventRouterForwarder> event_router(
    249       new MockEventRouterForwarder);
    250   GURL url;
    251   EXPECT_CALL(*event_router.get(),
    252               CallEventRouter(profile1_, kExt, kEventName, profile1_, url));
    253   EXPECT_CALL(*event_router.get(),
    254               CallEventRouter(profile2_, kExt, kEventName, profile2_, url));
    255   BroadcastEventToExtension(event_router.get(), kExt, kEventName, url);
    256 }
    257 
    258 TEST_F(EventRouterForwarderTest, UnicastExtensionUIRestricted) {
    259   scoped_refptr<MockEventRouterForwarder> event_router(
    260       new MockEventRouterForwarder);
    261   using ::testing::_;
    262   GURL url;
    263   EXPECT_CALL(*event_router.get(),
    264               CallEventRouter(profile1_, kExt, kEventName, profile1_, url));
    265   EXPECT_CALL(*event_router.get(), CallEventRouter(profile2_, _, _, _, _))
    266       .Times(0);
    267   DispatchEventToExtension(event_router.get(), kExt, kEventName, profile1_,
    268                            true, url);
    269 }
    270 
    271 TEST_F(EventRouterForwarderTest, UnicastExtensionUIUnrestricted) {
    272   scoped_refptr<MockEventRouterForwarder> event_router(
    273       new MockEventRouterForwarder);
    274   using ::testing::_;
    275   GURL url;
    276   EXPECT_CALL(*event_router.get(),
    277               CallEventRouter(profile1_, kExt, kEventName, NULL, url));
    278   EXPECT_CALL(*event_router.get(), CallEventRouter(profile2_, _, _, _, _))
    279       .Times(0);
    280   DispatchEventToExtension(event_router.get(), kExt, kEventName, profile1_,
    281                            false, url);
    282 }
    283 
    284 }  // namespace extensions
    285