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