1// Copyright (c) 2011 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/extension_event_router_forwarder.h"
6
7#include "base/message_loop.h"
8#include "chrome/browser/profiles/profile_manager.h"
9#include "chrome/test/testing_browser_process_test.h"
10#include "chrome/test/testing_profile.h"
11#include "chrome/test/thread_test_helper.h"
12#include "content/browser/browser_thread.h"
13#include "googleurl/src/gurl.h"
14#include "testing/gmock/include/gmock/gmock.h"
15#include "testing/gtest/include/gtest/gtest.h"
16#include "ui/base/system_monitor/system_monitor.h"
17
18namespace {
19
20const char kEventName[] = "event_name";
21const char kEventArgs[] = "event_args";
22const char kExt[] = "extension";
23
24class MockExtensionEventRouterForwarder : public ExtensionEventRouterForwarder {
25 public:
26  virtual ~MockExtensionEventRouterForwarder() {}
27
28  MOCK_METHOD6(CallExtensionEventRouter,
29      void(Profile*, const std::string&, const std::string&, const std::string&,
30           Profile*, const GURL&));
31};
32
33}  // namespace
34
35class ExtensionEventRouterForwarderTest : public TestingBrowserProcessTest {
36 protected:
37  ExtensionEventRouterForwarderTest()
38      : ui_thread_(BrowserThread::UI, &message_loop_),
39        io_thread_(BrowserThread::IO) {
40  }
41
42  ~ExtensionEventRouterForwarderTest() {
43  }
44
45  virtual void SetUp() {
46    // Inject a BrowserProcess with a ProfileManager.
47    ASSERT_TRUE(io_thread_.Start());
48
49    TestingBrowserProcess* browser_process = testing_browser_process_.get();
50    browser_process->SetProfileManager(new ProfileManager);
51
52    profile1_ = new TestingProfile();
53    profile2_ = new TestingProfile();
54
55    browser_process->profile_manager()->RegisterProfile(profile1_, true);
56    browser_process->profile_manager()->RegisterProfile(profile2_, true);
57  }
58
59  TestingProfile* CreateIncognitoProfile(TestingProfile* base) {
60    TestingProfile* incognito = new TestingProfile();
61    incognito->set_incognito(true);
62    base->SetOffTheRecordProfile(incognito);
63    return incognito;
64  }
65
66  MessageLoopForUI message_loop_;
67  BrowserThread ui_thread_;
68  BrowserThread io_thread_;
69  ui::SystemMonitor dummy;
70  // Profiles are weak pointers, owned by ProfileManager in |browser_process_|.
71  TestingProfile* profile1_;
72  TestingProfile* profile2_;
73};
74
75TEST_F(ExtensionEventRouterForwarderTest, BroadcastRendererUI) {
76  scoped_refptr<MockExtensionEventRouterForwarder> event_router(
77      new MockExtensionEventRouterForwarder);
78  GURL url;
79  EXPECT_CALL(*event_router,
80      CallExtensionEventRouter(
81          profile1_, "", kEventName, kEventArgs, profile1_, url));
82  EXPECT_CALL(*event_router,
83      CallExtensionEventRouter(
84          profile2_, "", kEventName, kEventArgs, profile2_, url));
85  event_router->BroadcastEventToRenderers(kEventName, kEventArgs, url);
86}
87
88TEST_F(ExtensionEventRouterForwarderTest, BroadcastRendererUIIncognito) {
89  scoped_refptr<MockExtensionEventRouterForwarder> event_router(
90      new MockExtensionEventRouterForwarder);
91  using ::testing::_;
92  GURL url;
93  Profile* incognito = CreateIncognitoProfile(profile1_);
94  EXPECT_CALL(*event_router,
95      CallExtensionEventRouter(
96          profile1_, "", kEventName, kEventArgs, profile1_, url));
97  EXPECT_CALL(*event_router,
98      CallExtensionEventRouter(incognito, _, _, _, _, _)).Times(0);
99  EXPECT_CALL(*event_router,
100      CallExtensionEventRouter(
101          profile2_, "", kEventName, kEventArgs, profile2_, url));
102  event_router->BroadcastEventToRenderers(kEventName, kEventArgs, url);
103}
104
105// This is the canonical test for passing control flow from the IO thread
106// to the UI thread. Repeating this for all public functions of
107// ExtensionEventRouterForwarder would not increase coverage.
108TEST_F(ExtensionEventRouterForwarderTest, BroadcastRendererIO) {
109  scoped_refptr<MockExtensionEventRouterForwarder> event_router(
110      new MockExtensionEventRouterForwarder);
111  GURL url;
112  EXPECT_CALL(*event_router,
113      CallExtensionEventRouter(
114          profile1_, "", kEventName, kEventArgs, profile1_, url));
115  EXPECT_CALL(*event_router,
116      CallExtensionEventRouter(
117          profile2_, "", kEventName, kEventArgs, profile2_, url));
118  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
119      NewRunnableMethod(
120          event_router.get(),
121          &MockExtensionEventRouterForwarder::BroadcastEventToRenderers,
122          std::string(kEventName), std::string(kEventArgs), url));
123
124  // Wait for IO thread's message loop to be processed
125  scoped_refptr<ThreadTestHelper> helper(
126      new ThreadTestHelper(BrowserThread::IO));
127  ASSERT_TRUE(helper->Run());
128
129  MessageLoop::current()->RunAllPending();
130}
131
132TEST_F(ExtensionEventRouterForwarderTest, UnicastRendererUIRestricted) {
133  scoped_refptr<MockExtensionEventRouterForwarder> event_router(
134      new MockExtensionEventRouterForwarder);
135  using ::testing::_;
136  GURL url;
137  EXPECT_CALL(*event_router,
138      CallExtensionEventRouter(
139          profile1_, "", kEventName, kEventArgs, profile1_, url));
140  EXPECT_CALL(*event_router,
141      CallExtensionEventRouter(profile2_, _, _, _, _, _)).Times(0);
142  event_router->DispatchEventToRenderers(kEventName, kEventArgs,
143                                         profile1_->GetRuntimeId(),
144                                         true, url);
145}
146
147TEST_F(ExtensionEventRouterForwarderTest,
148       UnicastRendererUIRestrictedIncognito1) {
149  scoped_refptr<MockExtensionEventRouterForwarder> event_router(
150      new MockExtensionEventRouterForwarder);
151  Profile* incognito = CreateIncognitoProfile(profile1_);
152  using ::testing::_;
153  GURL url;
154  EXPECT_CALL(*event_router,
155      CallExtensionEventRouter(
156          profile1_, "", kEventName, kEventArgs, profile1_, url));
157  EXPECT_CALL(*event_router,
158      CallExtensionEventRouter(incognito, _, _, _, _, _)).Times(0);
159  EXPECT_CALL(*event_router,
160      CallExtensionEventRouter(profile2_, _, _, _, _, _)).Times(0);
161  event_router->DispatchEventToRenderers(kEventName, kEventArgs,
162                                         profile1_->GetRuntimeId(),
163                                         true, url);
164}
165
166TEST_F(ExtensionEventRouterForwarderTest,
167       UnicastRendererUIRestrictedIncognito2) {
168  scoped_refptr<MockExtensionEventRouterForwarder> event_router(
169      new MockExtensionEventRouterForwarder);
170  Profile* incognito = CreateIncognitoProfile(profile1_);
171  using ::testing::_;
172  GURL url;
173  EXPECT_CALL(*event_router,
174      CallExtensionEventRouter(profile1_, _, _, _, _, _)).Times(0);
175  EXPECT_CALL(*event_router,
176      CallExtensionEventRouter(
177          incognito, "", kEventName, kEventArgs, incognito, url));
178  EXPECT_CALL(*event_router,
179      CallExtensionEventRouter(profile2_, _, _, _, _, _)).Times(0);
180  event_router->DispatchEventToRenderers(kEventName, kEventArgs,
181                                         incognito->GetRuntimeId(),
182                                         true, url);
183}
184
185TEST_F(ExtensionEventRouterForwarderTest, UnicastRendererUIUnrestricted) {
186  scoped_refptr<MockExtensionEventRouterForwarder> event_router(
187      new MockExtensionEventRouterForwarder);
188  using ::testing::_;
189  GURL url;
190  EXPECT_CALL(*event_router,
191      CallExtensionEventRouter(
192          profile1_, "", kEventName, kEventArgs, NULL, url));
193  EXPECT_CALL(*event_router,
194      CallExtensionEventRouter(profile2_, _, _, _, _, _)).Times(0);
195  event_router->DispatchEventToRenderers(kEventName, kEventArgs,
196                                         profile1_->GetRuntimeId(),
197                                         false, url);
198}
199
200TEST_F(ExtensionEventRouterForwarderTest,
201       UnicastRendererUIUnrestrictedIncognito) {
202  scoped_refptr<MockExtensionEventRouterForwarder> event_router(
203      new MockExtensionEventRouterForwarder);
204  Profile* incognito = CreateIncognitoProfile(profile1_);
205  using ::testing::_;
206  GURL url;
207  EXPECT_CALL(*event_router,
208      CallExtensionEventRouter(
209          profile1_, "", kEventName, kEventArgs, NULL, url));
210  EXPECT_CALL(*event_router,
211      CallExtensionEventRouter(incognito, _, _, _, _, _)).Times(0);
212  EXPECT_CALL(*event_router,
213      CallExtensionEventRouter(profile2_, _, _, _, _, _)).Times(0);
214  event_router->DispatchEventToRenderers(kEventName, kEventArgs,
215                                         profile1_->GetRuntimeId(),
216                                         false, url);
217}
218
219TEST_F(ExtensionEventRouterForwarderTest, BroadcastExtensionUI) {
220  scoped_refptr<MockExtensionEventRouterForwarder> event_router(
221      new MockExtensionEventRouterForwarder);
222  GURL url;
223  EXPECT_CALL(*event_router,
224      CallExtensionEventRouter(
225          profile1_, kExt, kEventName, kEventArgs, profile1_, url));
226  EXPECT_CALL(*event_router,
227      CallExtensionEventRouter(
228          profile2_, kExt, kEventName, kEventArgs, profile2_, url));
229  event_router->BroadcastEventToExtension(kExt, kEventName, kEventArgs, url);
230}
231
232TEST_F(ExtensionEventRouterForwarderTest, UnicastExtensionUIRestricted) {
233  scoped_refptr<MockExtensionEventRouterForwarder> event_router(
234      new MockExtensionEventRouterForwarder);
235  using ::testing::_;
236  GURL url;
237  EXPECT_CALL(*event_router,
238      CallExtensionEventRouter(
239          profile1_, kExt, kEventName, kEventArgs, profile1_, url));
240  EXPECT_CALL(*event_router,
241      CallExtensionEventRouter(profile2_, _, _, _, _, _)).Times(0);
242  event_router->DispatchEventToExtension(kExt, kEventName, kEventArgs,
243                                         profile1_->GetRuntimeId(),
244                                         true, url);
245}
246
247TEST_F(ExtensionEventRouterForwarderTest, UnicastExtensionUIUnrestricted) {
248  scoped_refptr<MockExtensionEventRouterForwarder> event_router(
249      new MockExtensionEventRouterForwarder);
250  using ::testing::_;
251  GURL url;
252  EXPECT_CALL(*event_router,
253      CallExtensionEventRouter(
254          profile1_, kExt, kEventName, kEventArgs, NULL, url));
255  EXPECT_CALL(*event_router,
256      CallExtensionEventRouter(profile2_, _, _, _, _, _)).Times(0);
257  event_router->DispatchEventToExtension(kExt, kEventName, kEventArgs,
258                                         profile1_->GetRuntimeId(),
259                                         false, url);
260}
261