1 // Copyright 2015 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.
5 #include "chrome/browser/ui/browser_commands.h"
6 #include "chrome/browser/ui/tabs/tab_strip_model.h"
7 #include "chrome/browser/ui/toolbar/media_router_action.h"
8 #include "chrome/browser/ui/toolbar/toolbar_action_view_delegate.h"
9 #include "chrome/browser/ui/webui/media_router/media_router_dialog_controller_impl.h"
10 #include "chrome/browser/ui/webui/media_router/media_router_test.h"
11 #include "chrome/grit/generated_resources.h"
12 #include "content/public/browser/site_instance.h"
13 #include "content/public/test/test_utils.h"
14 #include "grit/theme_resources.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "ui/base/l10n/l10n_util.h"
17 #include "ui/base/resource/resource_bundle.h"
18 #include "ui/gfx/image/image_unittest_util.h"
20 using content::WebContents
;
21 using media_router::MediaRouterDialogControllerImpl
;
23 class MockToolbarActionViewDelegate
: public ToolbarActionViewDelegate
{
25 MockToolbarActionViewDelegate() {}
26 ~MockToolbarActionViewDelegate() {}
28 MOCK_CONST_METHOD0(GetCurrentWebContents
, content::WebContents
*());
29 MOCK_METHOD0(UpdateState
, void());
30 MOCK_CONST_METHOD0(IsMenuRunning
, bool());
31 MOCK_METHOD1(OnPopupShown
, void(bool by_user
));
32 MOCK_METHOD0(OnPopupClosed
, void());
35 class TestMediaRouterAction
: public MediaRouterAction
{
37 explicit TestMediaRouterAction(Browser
* browser
)
38 : MediaRouterAction(browser
),
39 web_contents_(WebContents::Create(WebContents::CreateParams(
40 browser
->profile()))),
42 platform_delegate_(nullptr) {}
43 ~TestMediaRouterAction() override
{}
45 void SetMediaRouterDialogController(
46 MediaRouterDialogControllerImpl
* controller
) {
48 controller_
= controller
;
52 MediaRouterDialogControllerImpl
* GetMediaRouterDialogController()
57 MediaRouterActionPlatformDelegate
* GetPlatformDelegate() override
{
58 return platform_delegate_
;
61 scoped_ptr
<WebContents
> web_contents_
;
62 MediaRouterDialogControllerImpl
* controller_
;
63 MediaRouterActionPlatformDelegate
* platform_delegate_
;
66 class MediaRouterActionUnitTest
: public MediaRouterTest
{
68 MediaRouterActionUnitTest()
69 : fake_issue_notification_(media_router::Issue(
71 "message notification",
72 media_router::IssueAction(media_router::IssueAction::TYPE_DISMISS
),
73 std::vector
<media_router::IssueAction
>(),
75 media_router::Issue::NOTIFICATION
,
79 media_router::Issue("title warning",
81 media_router::IssueAction(
82 media_router::IssueAction::TYPE_LEARN_MORE
),
83 std::vector
<media_router::IssueAction
>(),
85 media_router::Issue::WARNING
,
88 fake_issue_fatal_(media_router::Issue(
91 media_router::IssueAction(media_router::IssueAction::TYPE_DISMISS
),
92 std::vector
<media_router::IssueAction
>(),
94 media_router::Issue::FATAL
,
97 fake_source1_("fakeSource1"),
98 fake_source2_("fakeSource2"),
99 fake_route_local_("route1",
106 fake_route_remote_("route2",
113 active_icon_(ui::ResourceBundle::GetSharedInstance().GetImageNamed(
114 IDR_MEDIA_ROUTER_ACTIVE_ICON
)),
115 error_icon_(ui::ResourceBundle::GetSharedInstance().GetImageNamed(
116 IDR_MEDIA_ROUTER_ERROR_ICON
)),
117 idle_icon_(ui::ResourceBundle::GetSharedInstance().GetImageNamed(
118 IDR_MEDIA_ROUTER_IDLE_ICON
)),
119 warning_icon_(ui::ResourceBundle::GetSharedInstance().GetImageNamed(
120 IDR_MEDIA_ROUTER_WARNING_ICON
)) {}
122 ~MediaRouterActionUnitTest() override
{}
124 // BrowserWithTestWindowTest:
125 void SetUp() override
{
126 BrowserWithTestWindowTest::SetUp();
127 action_
.reset(new TestMediaRouterAction(browser()));
130 void TearDown() override
{
132 BrowserWithTestWindowTest::TearDown();
135 TestMediaRouterAction
* action() { return action_
.get(); }
136 const media_router::Issue
* fake_issue_notification() {
137 return &fake_issue_notification_
;
139 const media_router::Issue
* fake_issue_warning() {
140 return &fake_issue_warning_
;
142 const media_router::Issue
* fake_issue_fatal() {
143 return &fake_issue_fatal_
;
145 const media_router::MediaRoute
fake_route_local() {
146 return fake_route_local_
;
148 const media_router::MediaRoute
fake_route_remote() {
149 return fake_route_remote_
;
151 const gfx::Image
active_icon() { return active_icon_
; }
152 const gfx::Image
error_icon() { return error_icon_
; }
153 const gfx::Image
idle_icon() { return idle_icon_
; }
154 const gfx::Image
warning_icon() { return warning_icon_
; }
157 scoped_ptr
<TestMediaRouterAction
> action_
;
160 const media_router::Issue fake_issue_notification_
;
161 const media_router::Issue fake_issue_warning_
;
162 const media_router::Issue fake_issue_fatal_
;
164 // Fake Sources, used for the Routes.
165 const media_router::MediaSource fake_source1_
;
166 const media_router::MediaSource fake_source2_
;
169 const media_router::MediaRoute fake_route_local_
;
170 const media_router::MediaRoute fake_route_remote_
;
173 const gfx::Image active_icon_
;
174 const gfx::Image error_icon_
;
175 const gfx::Image idle_icon_
;
176 const gfx::Image warning_icon_
;
178 DISALLOW_COPY_AND_ASSIGN(MediaRouterActionUnitTest
);
181 // Tests the initial state of MediaRouterAction after construction.
182 TEST_F(MediaRouterActionUnitTest
, Initialization
) {
183 EXPECT_EQ("media_router_action", action()->GetId());
184 EXPECT_EQ(l10n_util::GetStringUTF16(IDS_MEDIA_ROUTER_TITLE
),
185 action()->GetActionName());
186 EXPECT_TRUE(gfx::test::IsEqual(idle_icon(),
187 action()->GetIcon(nullptr, gfx::Size())));
190 // Tests the MediaRouterAction icon based on updates to issues.
191 TEST_F(MediaRouterActionUnitTest
, UpdateIssues
) {
192 // Initially, there are no issues.
193 EXPECT_TRUE(gfx::test::IsEqual(idle_icon(),
194 action()->GetIcon(nullptr, gfx::Size())));
196 // Don't update |current_icon_| since the issue is only a notification.
197 action()->OnIssueUpdated(fake_issue_notification());
198 EXPECT_TRUE(gfx::test::IsEqual(idle_icon(),
199 action()->GetIcon(nullptr, gfx::Size())));
201 // Update |current_icon_| since the issue is a warning.
202 action()->OnIssueUpdated(fake_issue_warning());
203 EXPECT_TRUE(gfx::test::IsEqual(warning_icon(),
204 action()->GetIcon(nullptr, gfx::Size())));
206 // Update |current_icon_| since the issue is fatal.
207 action()->OnIssueUpdated(fake_issue_fatal());
208 EXPECT_TRUE(gfx::test::IsEqual(error_icon(),
209 action()->GetIcon(nullptr, gfx::Size())));
212 action()->OnIssueUpdated(nullptr);
213 EXPECT_TRUE(gfx::test::IsEqual(idle_icon(),
214 action()->GetIcon(nullptr, gfx::Size())));
217 // Tests the MediaRouterAction state based on updates to routes.
218 TEST_F(MediaRouterActionUnitTest
, UpdateRoutes
) {
219 scoped_ptr
<std::vector
<media_router::MediaRoute
>> routes(
220 new std::vector
<media_router::MediaRoute
>());
222 // Initially, there are no routes.
223 EXPECT_TRUE(gfx::test::IsEqual(idle_icon(),
224 action()->GetIcon(nullptr, gfx::Size())));
226 // Update |current_icon_| since there is a local route.
227 routes
->push_back(fake_route_local());
228 routes
->push_back(fake_route_remote());
229 action()->OnRoutesUpdated(*routes
.get());
230 EXPECT_TRUE(gfx::test::IsEqual(active_icon(),
231 action()->GetIcon(nullptr, gfx::Size())));
233 // Update |current_icon_| since there are no more local routes.
235 routes
->push_back(fake_route_remote());
236 action()->OnRoutesUpdated(*routes
.get());
237 EXPECT_TRUE(gfx::test::IsEqual(idle_icon(),
238 action()->GetIcon(nullptr, gfx::Size())));
240 // |current_icon_| stays the same if there are no local routes or no routes.
242 action()->OnRoutesUpdated(*routes
.get());
243 EXPECT_TRUE(gfx::test::IsEqual(idle_icon(),
244 action()->GetIcon(nullptr, gfx::Size())));
247 // Tests the MediaRouterAction icon based on updates to both issues and routes.
248 TEST_F(MediaRouterActionUnitTest
, UpdateIssuesAndRoutes
) {
249 scoped_ptr
<std::vector
<media_router::MediaRoute
>> routes(
250 new std::vector
<media_router::MediaRoute
>());
252 // Initially, there are no issues or routes.
253 EXPECT_TRUE(gfx::test::IsEqual(idle_icon(),
254 action()->GetIcon(nullptr, gfx::Size())));
256 // There is no change in |current_icon_| since notification issues do not
258 action()->OnIssueUpdated(fake_issue_notification());
259 EXPECT_TRUE(gfx::test::IsEqual(idle_icon(),
260 action()->GetIcon(nullptr, gfx::Size())));
262 // Non-local routes also do not have an effect on |current_icon_|.
263 routes
->push_back(fake_route_remote());
264 action()->OnRoutesUpdated(*routes
.get());
265 EXPECT_TRUE(gfx::test::IsEqual(idle_icon(),
266 action()->GetIcon(nullptr, gfx::Size())));
268 // Update |current_icon_| since there is a local route.
270 routes
->push_back(fake_route_local());
271 action()->OnRoutesUpdated(*routes
.get());
272 EXPECT_TRUE(gfx::test::IsEqual(active_icon(),
273 action()->GetIcon(nullptr, gfx::Size())));
275 // Update |current_icon_|, with a priority to reflect the warning issue
276 // rather than the local route.
277 action()->OnIssueUpdated(fake_issue_warning());
278 EXPECT_TRUE(gfx::test::IsEqual(warning_icon(),
279 action()->GetIcon(nullptr, gfx::Size())));
281 // Swapping the local route for a non-local one makes no difference to the
284 routes
->push_back(fake_route_remote());
285 action()->OnRoutesUpdated(*routes
.get());
286 EXPECT_TRUE(gfx::test::IsEqual(warning_icon(),
287 action()->GetIcon(nullptr, gfx::Size())));
289 // Update |current_icon_| since the issue has been updated to fatal.
290 action()->OnIssueUpdated(fake_issue_fatal());
291 EXPECT_TRUE(gfx::test::IsEqual(error_icon(),
292 action()->GetIcon(nullptr, gfx::Size())));
294 // Fatal issues still take precedent over local routes.
296 routes
->push_back(fake_route_local());
297 action()->OnRoutesUpdated(*routes
.get());
298 EXPECT_TRUE(gfx::test::IsEqual(error_icon(),
299 action()->GetIcon(nullptr, gfx::Size())));
301 // When the fatal issue is dismissed, |current_icon_| reflects the existing
303 action()->OnIssueUpdated(nullptr);
304 EXPECT_TRUE(gfx::test::IsEqual(active_icon(),
305 action()->GetIcon(nullptr, gfx::Size())));
307 // Update |current_icon_| when the local route is swapped out for a non-local
310 routes
->push_back(fake_route_remote());
311 action()->OnRoutesUpdated(*routes
.get());
312 EXPECT_TRUE(gfx::test::IsEqual(idle_icon(),
313 action()->GetIcon(nullptr, gfx::Size())));
316 TEST_F(MediaRouterActionUnitTest
, IconPressedState
) {
317 // Start with one window with one tab.
318 EXPECT_EQ(0, browser()->tab_strip_model()->count());
319 chrome::NewTab(browser());
320 EXPECT_EQ(1, browser()->tab_strip_model()->count());
322 // Create a reference to initiator contents.
323 WebContents
* initiator_
=
324 browser()->tab_strip_model()->GetActiveWebContents();
326 MediaRouterDialogControllerImpl::CreateForWebContents(initiator_
);
327 MediaRouterDialogControllerImpl
* dialog_controller_
=
328 MediaRouterDialogControllerImpl::FromWebContents(initiator_
);
329 ASSERT_TRUE(dialog_controller_
);
331 // Sets the controller to use for TestMediaRouterAction.
332 action()->SetMediaRouterDialogController(dialog_controller_
);
334 // Create a ToolbarActionViewDelegate to use for MediaRouterAction.
335 scoped_ptr
<MockToolbarActionViewDelegate
> mock_delegate(
336 new MockToolbarActionViewDelegate());
338 EXPECT_CALL(*mock_delegate
, GetCurrentWebContents()).WillOnce(
339 testing::Return(initiator_
));
340 EXPECT_CALL(*mock_delegate
, OnPopupClosed()).WillOnce(testing::Return());
341 action()->SetDelegate(mock_delegate
.get());
343 EXPECT_CALL(*mock_delegate
, OnPopupShown(true)).WillOnce(testing::Return());
344 action()->ExecuteAction(true);
346 EXPECT_CALL(*mock_delegate
, OnPopupClosed()).WillOnce(testing::Return());
347 dialog_controller_
->CloseMediaRouterDialog();
349 EXPECT_CALL(*mock_delegate
, OnPopupClosed()).WillOnce(testing::Return());
350 dialog_controller_
->Reset();
352 EXPECT_CALL(*mock_delegate
, OnPopupShown(true)).WillOnce(testing::Return());
353 dialog_controller_
->CreateMediaRouterDialog();
355 EXPECT_CALL(*mock_delegate
, OnPopupClosed()).WillOnce(testing::Return());
356 dialog_controller_
->CloseMediaRouterDialog();