1 // Copyright 2019 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 <memory>
6 #include <tuple>
7 #include <utility>
8 #include <vector>
9 
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/test/mock_callback.h"
12 #include "chrome/browser/media/webrtc/desktop_media_picker.h"
13 #include "chrome/browser/media/webrtc/desktop_media_picker_controller.h"
14 #include "chrome/browser/media/webrtc/desktop_media_picker_factory_impl.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 
18 using testing::_;
19 using testing::AnyNumber;
20 using testing::ByMove;
21 using testing::InvokeArgument;
22 using testing::Ne;
23 using testing::Return;
24 using testing::ReturnRef;
25 using testing::WithArg;
26 
27 class MockDesktopMediaPicker : public DesktopMediaPicker {
28  public:
29   MOCK_METHOD3(Show,
30                void(const Params& params,
31                     std::vector<std::unique_ptr<DesktopMediaList>> source_lists,
32                     DoneCallback done_callback));
33 };
34 
35 class MockDesktopMediaList : public DesktopMediaList {
36  public:
37   MOCK_METHOD1(SetUpdatePeriod, void(base::TimeDelta period));
38   MOCK_METHOD1(SetThumbnailSize, void(const gfx::Size& thumbnail_size));
39   MOCK_METHOD1(SetViewDialogWindowId, void(content::DesktopMediaID dialog_id));
40   MOCK_METHOD1(StartUpdating, void(DesktopMediaListObserver* observer));
41   MOCK_METHOD1(Update, void(UpdateCallback callback));
42   MOCK_CONST_METHOD0(GetSourceCount, int());
43   MOCK_CONST_METHOD1(GetSource, Source&(int index));
44   MOCK_CONST_METHOD0(GetMediaListType, content::DesktopMediaID::Type());
45 };
46 
47 class MockDesktopMediaPickerFactory : public DesktopMediaPickerFactory {
48  public:
49   MOCK_METHOD0(CreatePicker, std::unique_ptr<DesktopMediaPicker>());
50   MOCK_METHOD1(CreateMediaList,
51                std::vector<std::unique_ptr<DesktopMediaList>>(
52                    const std::vector<content::DesktopMediaID::Type>& types));
53 };
54 
55 class DesktopMediaPickerControllerTest : public testing::Test {
56  public:
SetUp()57   void SetUp() override {
58     ON_CALL(factory_, CreatePicker).WillByDefault([this]() {
59       return std::unique_ptr<DesktopMediaPicker>(std::move(picker_));
60     });
61     ON_CALL(factory_, CreateMediaList).WillByDefault([this](const auto& types) {
62       std::vector<std::unique_ptr<DesktopMediaList>> lists;
63       lists.push_back(std::move(media_list_));
64       return lists;
65     });
66   }
67 
68  protected:
69   DesktopMediaPickerController::Params picker_params_;
70   base::MockCallback<DesktopMediaPickerController::DoneCallback> done_;
71   std::vector<content::DesktopMediaID::Type> source_types_{
72       content::DesktopMediaID::TYPE_SCREEN};
73   content::DesktopMediaID media_id_{content::DesktopMediaID::TYPE_SCREEN, 42};
74   std::unique_ptr<MockDesktopMediaPicker> picker_ =
75       std::make_unique<MockDesktopMediaPicker>();
76   std::unique_ptr<MockDesktopMediaList> media_list_ =
77       std::make_unique<MockDesktopMediaList>();
78   MockDesktopMediaPickerFactory factory_;
79 };
80 
81 // Test that the picker dialog is shown and the selected media ID is returned.
TEST_F(DesktopMediaPickerControllerTest,ShowPicker)82 TEST_F(DesktopMediaPickerControllerTest, ShowPicker) {
83   EXPECT_CALL(factory_, CreatePicker());
84   EXPECT_CALL(factory_, CreateMediaList(source_types_));
85   EXPECT_CALL(done_, Run("", media_id_));
86   EXPECT_CALL(*picker_, Show)
87       .WillOnce(WithArg<2>([&](DesktopMediaPicker::DoneCallback cb) {
88         std::move(cb).Run(media_id_);
89       }));
90   EXPECT_CALL(*media_list_, Update).Times(0);
91 
92   DesktopMediaPickerController controller(&factory_);
93   controller.Show(picker_params_, source_types_, done_.Get());
94 }
95 
96 // Test that a null result is returned in response to WebContentsDestroyed().
TEST_F(DesktopMediaPickerControllerTest,WebContentsDestroyed)97 TEST_F(DesktopMediaPickerControllerTest, WebContentsDestroyed) {
98   EXPECT_CALL(factory_, CreatePicker());
99   EXPECT_CALL(factory_, CreateMediaList(source_types_));
100   EXPECT_CALL(done_, Run("", content::DesktopMediaID()));
101   EXPECT_CALL(*picker_, Show);
102 
103   DesktopMediaPickerController controller(&factory_);
104   controller.Show(picker_params_, source_types_, done_.Get());
105   controller.WebContentsDestroyed();
106 }
107 
108 // Test that the picker dialog can be bypassed.
TEST_F(DesktopMediaPickerControllerTest,ShowSingleScreen)109 TEST_F(DesktopMediaPickerControllerTest, ShowSingleScreen) {
110   picker_params_.select_only_screen = true;
111 
112   DesktopMediaList::Source source;
113   source.id = media_id_;
114   source.name = base::ASCIIToUTF16("fake name");
115 
116   EXPECT_CALL(factory_, CreatePicker()).Times(0);
117   EXPECT_CALL(factory_, CreateMediaList(source_types_));
118   EXPECT_CALL(done_, Run("", source.id));
119   EXPECT_CALL(*picker_, Show).Times(0);
120   EXPECT_CALL(*media_list_, Update)
121       .WillOnce(
122           [](DesktopMediaList::UpdateCallback cb) { std::move(cb).Run(); });
123   EXPECT_CALL(*media_list_, GetSourceCount)
124       .Times(AnyNumber())
125       .WillRepeatedly(Return(1));
126   EXPECT_CALL(*media_list_, GetSource(0))
127       .Times(AnyNumber())
128       .WillRepeatedly(ReturnRef(source));
129 
130   DesktopMediaPickerController controller(&factory_);
131   controller.Show(picker_params_, source_types_, done_.Get());
132 }
133 
134 // Test that an error is reported when no sources are found.
TEST_F(DesktopMediaPickerControllerTest,EmptySourceList)135 TEST_F(DesktopMediaPickerControllerTest, EmptySourceList) {
136   EXPECT_CALL(factory_, CreateMediaList)
137       .WillOnce(
138           Return(ByMove(std::vector<std::unique_ptr<DesktopMediaList>>())));
139   EXPECT_CALL(done_, Run(Ne(""), content::DesktopMediaID()));
140 
141   DesktopMediaPickerController controller(&factory_);
142   controller.Show(picker_params_, source_types_, done_.Get());
143 }
144 
145 // Test that an error is reported when no picker can be created.
TEST_F(DesktopMediaPickerControllerTest,NoPicker)146 TEST_F(DesktopMediaPickerControllerTest, NoPicker) {
147   EXPECT_CALL(factory_, CreatePicker)
148       .WillOnce(Return(ByMove(std::unique_ptr<DesktopMediaPicker>())));
149   EXPECT_CALL(done_, Run(Ne(""), content::DesktopMediaID()));
150   EXPECT_CALL(factory_, CreateMediaList).Times(AnyNumber());
151 
152   DesktopMediaPickerController controller(&factory_);
153   controller.Show(picker_params_, source_types_, done_.Get());
154 }
155