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   TestingProfile* CreateIncognitoProfile(TestingProfile* base) {
    114     TestingProfile* incognito = new TestingProfile;  // Owned by |base|.
    115     incognito->set_incognito(true);
    116     base->SetOffTheRecordProfile(incognito);
    117     return incognito;
    118   }
    119 
    120   base::MessageLoopForUI message_loop_;
    121   content::TestBrowserThread ui_thread_;
    122   content::TestBrowserThread io_thread_;
    123   TestingProfileManager profile_manager_;
    124   scoped_ptr<base::PowerMonitor> dummy;
    125   // Profiles are weak pointers, owned by ProfileManager in |browser_process_|.
    126   TestingProfile* profile1_;
    127   TestingProfile* profile2_;
    128 };
    129 
    130 TEST_F(EventRouterForwarderTest, BroadcastRendererUI) {
    131   scoped_refptr<MockEventRouterForwarder> event_router(
    132       new MockEventRouterForwarder);
    133   GURL url;
    134   EXPECT_CALL(*event_router.get(),
    135               CallEventRouter(profile1_, "", kEventName, profile1_, url));
    136   EXPECT_CALL(*event_router.get(),
    137               CallEventRouter(profile2_, "", kEventName, profile2_, url));
    138   BroadcastEventToRenderers(event_router.get(), kEventName, url);
    139 }
    140 
    141 TEST_F(EventRouterForwarderTest, BroadcastRendererUIIncognito) {
    142   scoped_refptr<MockEventRouterForwarder> event_router(
    143       new MockEventRouterForwarder);
    144   using ::testing::_;
    145   GURL url;
    146   Profile* incognito = CreateIncognitoProfile(profile1_);
    147   EXPECT_CALL(*event_router.get(),
    148               CallEventRouter(profile1_, "", kEventName, profile1_, url));
    149   EXPECT_CALL(*event_router.get(), CallEventRouter(incognito, _, _, _, _))
    150       .Times(0);
    151   EXPECT_CALL(*event_router.get(),
    152               CallEventRouter(profile2_, "", kEventName, profile2_, url));
    153   BroadcastEventToRenderers(event_router.get(), kEventName, url);
    154 }
    155 
    156 // This is the canonical test for passing control flow from the IO thread
    157 // to the UI thread. Repeating this for all public functions of
    158 // EventRouterForwarder would not increase coverage.
    159 TEST_F(EventRouterForwarderTest, BroadcastRendererIO) {
    160   scoped_refptr<MockEventRouterForwarder> event_router(
    161       new MockEventRouterForwarder);
    162   GURL url;
    163   EXPECT_CALL(*event_router.get(),
    164               CallEventRouter(profile1_, "", kEventName, profile1_, url));
    165   EXPECT_CALL(*event_router.get(),
    166               CallEventRouter(profile2_, "", kEventName, profile2_, url));
    167   BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
    168       base::Bind(
    169           &BroadcastEventToRenderers, base::Unretained(event_router.get()),
    170           kEventName, url));
    171 
    172   // Wait for IO thread's message loop to be processed
    173   scoped_refptr<base::ThreadTestHelper> helper(new base::ThreadTestHelper(
    174       BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get()));
    175   ASSERT_TRUE(helper->Run());
    176 
    177   base::MessageLoop::current()->RunUntilIdle();
    178 }
    179 
    180 TEST_F(EventRouterForwarderTest, UnicastRendererUIRestricted) {
    181   scoped_refptr<MockEventRouterForwarder> event_router(
    182       new MockEventRouterForwarder);
    183   using ::testing::_;
    184   GURL url;
    185   EXPECT_CALL(*event_router.get(),
    186               CallEventRouter(profile1_, "", kEventName, profile1_, url));
    187   EXPECT_CALL(*event_router.get(), CallEventRouter(profile2_, _, _, _, _))
    188       .Times(0);
    189   DispatchEventToRenderers(event_router.get(), kEventName, profile1_, true,
    190                            url);
    191 }
    192 
    193 TEST_F(EventRouterForwarderTest, UnicastRendererUIRestrictedIncognito1) {
    194   scoped_refptr<MockEventRouterForwarder> event_router(
    195       new MockEventRouterForwarder);
    196   Profile* incognito = CreateIncognitoProfile(profile1_);
    197   using ::testing::_;
    198   GURL url;
    199   EXPECT_CALL(*event_router.get(),
    200               CallEventRouter(profile1_, "", kEventName, profile1_, url));
    201   EXPECT_CALL(*event_router.get(), CallEventRouter(incognito, _, _, _, _))
    202       .Times(0);
    203   EXPECT_CALL(*event_router.get(), CallEventRouter(profile2_, _, _, _, _))
    204       .Times(0);
    205   DispatchEventToRenderers(event_router.get(), kEventName, profile1_, true,
    206                            url);
    207 }
    208 
    209 TEST_F(EventRouterForwarderTest, UnicastRendererUIRestrictedIncognito2) {
    210   scoped_refptr<MockEventRouterForwarder> event_router(
    211       new MockEventRouterForwarder);
    212   Profile* incognito = CreateIncognitoProfile(profile1_);
    213   using ::testing::_;
    214   GURL url;
    215   EXPECT_CALL(*event_router.get(), CallEventRouter(profile1_, _, _, _, _))
    216       .Times(0);
    217   EXPECT_CALL(*event_router.get(),
    218               CallEventRouter(incognito, "", kEventName, incognito, url));
    219   EXPECT_CALL(*event_router.get(), CallEventRouter(profile2_, _, _, _, _))
    220       .Times(0);
    221   DispatchEventToRenderers(event_router.get(), kEventName, incognito, true,
    222                            url);
    223 }
    224 
    225 TEST_F(EventRouterForwarderTest, UnicastRendererUIUnrestricted) {
    226   scoped_refptr<MockEventRouterForwarder> event_router(
    227       new MockEventRouterForwarder);
    228   using ::testing::_;
    229   GURL url;
    230   EXPECT_CALL(*event_router.get(),
    231               CallEventRouter(profile1_, "", kEventName, NULL, url));
    232   EXPECT_CALL(*event_router.get(), CallEventRouter(profile2_, _, _, _, _))
    233       .Times(0);
    234   DispatchEventToRenderers(event_router.get(), kEventName, profile1_, false,
    235                            url);
    236 }
    237 
    238 TEST_F(EventRouterForwarderTest, UnicastRendererUIUnrestrictedIncognito) {
    239   scoped_refptr<MockEventRouterForwarder> event_router(
    240       new MockEventRouterForwarder);
    241   Profile* incognito = CreateIncognitoProfile(profile1_);
    242   using ::testing::_;
    243   GURL url;
    244   EXPECT_CALL(*event_router.get(),
    245               CallEventRouter(profile1_, "", kEventName, NULL, url));
    246   EXPECT_CALL(*event_router.get(), CallEventRouter(incognito, _, _, _, _))
    247       .Times(0);
    248   EXPECT_CALL(*event_router.get(), CallEventRouter(profile2_, _, _, _, _))
    249       .Times(0);
    250   DispatchEventToRenderers(event_router.get(), kEventName, profile1_, false,
    251                            url);
    252 }
    253 
    254 TEST_F(EventRouterForwarderTest, BroadcastExtensionUI) {
    255   scoped_refptr<MockEventRouterForwarder> event_router(
    256       new MockEventRouterForwarder);
    257   GURL url;
    258   EXPECT_CALL(*event_router.get(),
    259               CallEventRouter(profile1_, kExt, kEventName, profile1_, url));
    260   EXPECT_CALL(*event_router.get(),
    261               CallEventRouter(profile2_, kExt, kEventName, profile2_, url));
    262   BroadcastEventToExtension(event_router.get(), kExt, kEventName, url);
    263 }
    264 
    265 TEST_F(EventRouterForwarderTest, UnicastExtensionUIRestricted) {
    266   scoped_refptr<MockEventRouterForwarder> event_router(
    267       new MockEventRouterForwarder);
    268   using ::testing::_;
    269   GURL url;
    270   EXPECT_CALL(*event_router.get(),
    271               CallEventRouter(profile1_, kExt, kEventName, profile1_, url));
    272   EXPECT_CALL(*event_router.get(), CallEventRouter(profile2_, _, _, _, _))
    273       .Times(0);
    274   DispatchEventToExtension(event_router.get(), kExt, kEventName, profile1_,
    275                            true, url);
    276 }
    277 
    278 TEST_F(EventRouterForwarderTest, UnicastExtensionUIUnrestricted) {
    279   scoped_refptr<MockEventRouterForwarder> event_router(
    280       new MockEventRouterForwarder);
    281   using ::testing::_;
    282   GURL url;
    283   EXPECT_CALL(*event_router.get(),
    284               CallEventRouter(profile1_, kExt, kEventName, NULL, url));
    285   EXPECT_CALL(*event_router.get(), CallEventRouter(profile2_, _, _, _, _))
    286       .Times(0);
    287   DispatchEventToExtension(event_router.get(), kExt, kEventName, profile1_,
    288                            false, url);
    289 }
    290 
    291 }  // namespace extensions
    292