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 21using content::BrowserThread; 22 23namespace extensions { 24 25namespace { 26 27const char kEventName[] = "event_name"; 28const char kExt[] = "extension"; 29 30class 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 48static 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 55static 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 65static 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 74static 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 88class 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 130TEST_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 141TEST_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. 159TEST_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 180TEST_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 193TEST_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 209TEST_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 225TEST_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 238TEST_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 254TEST_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 265TEST_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 278TEST_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