1 // Copyright 2017 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/common/media_router/discovery/media_sink_service_base.h"
6
7 #include "base/memory/ptr_util.h"
8 #include "base/test/mock_callback.h"
9 #include "base/timer/mock_timer.h"
10 #include "chrome/common/media_router/test/test_helper.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 using ::testing::_;
15 using ::testing::Return;
16
17 namespace {
18
CreateDialSinkExtraData(const std::string & model_name,const std::string & ip_address,const std::string & app_url)19 media_router::DialSinkExtraData CreateDialSinkExtraData(
20 const std::string& model_name,
21 const std::string& ip_address,
22 const std::string& app_url) {
23 media_router::DialSinkExtraData dial_extra_data;
24 EXPECT_TRUE(dial_extra_data.ip_address.AssignFromIPLiteral(ip_address));
25 dial_extra_data.model_name = model_name;
26 dial_extra_data.app_url = GURL(app_url);
27 return dial_extra_data;
28 }
29
CreateDialMediaSinks()30 std::vector<media_router::MediaSinkInternal> CreateDialMediaSinks() {
31 media_router::MediaSink sink1("sink1", "sink_name_1",
32 media_router::SinkIconType::CAST);
33 media_router::DialSinkExtraData extra_data1 = CreateDialSinkExtraData(
34 "model_name1", "192.168.1.1", "https://example1.com");
35
36 media_router::MediaSink sink2("sink2", "sink_name_2",
37 media_router::SinkIconType::CAST);
38 media_router::DialSinkExtraData extra_data2 = CreateDialSinkExtraData(
39 "model_name2", "192.168.1.2", "https://example2.com");
40
41 std::vector<media_router::MediaSinkInternal> sinks;
42 sinks.push_back(media_router::MediaSinkInternal(sink1, extra_data1));
43 sinks.push_back(media_router::MediaSinkInternal(sink2, extra_data2));
44 return sinks;
45 }
46
47 } // namespace
48
49 namespace media_router {
50
51 class MediaSinkServiceBaseTest : public ::testing::Test {
52 public:
MediaSinkServiceBaseTest()53 MediaSinkServiceBaseTest()
54 : media_sink_service_(mock_sink_discovered_cb_.Get()) {}
~MediaSinkServiceBaseTest()55 ~MediaSinkServiceBaseTest() override {}
56
PopulateSinks(const std::vector<MediaSinkInternal> & old_sinks,const std::vector<MediaSinkInternal> & new_sinks)57 void PopulateSinks(const std::vector<MediaSinkInternal>& old_sinks,
58 const std::vector<MediaSinkInternal>& new_sinks) {
59 media_sink_service_.previous_sinks_.clear();
60 for (const auto& old_sink : old_sinks)
61 media_sink_service_.previous_sinks_.emplace(old_sink.sink().id(),
62 old_sink);
63
64 media_sink_service_.sinks_.clear();
65 for (const auto& new_sink : new_sinks)
66 media_sink_service_.sinks_.emplace(new_sink.sink().id(), new_sink);
67 }
68
TestOnDiscoveryComplete(const std::vector<MediaSinkInternal> & old_sinks,const std::vector<MediaSinkInternal> & new_sinks)69 void TestOnDiscoveryComplete(
70 const std::vector<MediaSinkInternal>& old_sinks,
71 const std::vector<MediaSinkInternal>& new_sinks) {
72 PopulateSinks(old_sinks, new_sinks);
73 EXPECT_CALL(mock_sink_discovered_cb_, Run(new_sinks));
74 media_sink_service_.OnDiscoveryComplete();
75 }
76
77 protected:
78 base::MockCallback<OnSinksDiscoveredCallback> mock_sink_discovered_cb_;
79 TestMediaSinkService media_sink_service_;
80
81 DISALLOW_COPY_AND_ASSIGN(MediaSinkServiceBaseTest);
82 };
83
TEST_F(MediaSinkServiceBaseTest,TestOnDiscoveryComplete_SameSink)84 TEST_F(MediaSinkServiceBaseTest, TestOnDiscoveryComplete_SameSink) {
85 std::vector<MediaSinkInternal> old_sinks;
86 std::vector<MediaSinkInternal> new_sinks = CreateDialMediaSinks();
87 TestOnDiscoveryComplete(old_sinks, new_sinks);
88
89 // Same sink
90 EXPECT_CALL(mock_sink_discovered_cb_, Run(new_sinks)).Times(0);
91 media_sink_service_.OnDiscoveryComplete();
92 }
93
TEST_F(MediaSinkServiceBaseTest,TestOnDiscoveryComplete_SameSinkDifferentOrders)94 TEST_F(MediaSinkServiceBaseTest,
95 TestOnDiscoveryComplete_SameSinkDifferentOrders) {
96 std::vector<MediaSinkInternal> old_sinks = CreateDialMediaSinks();
97 std::vector<MediaSinkInternal> new_sinks = CreateDialMediaSinks();
98 std::reverse(new_sinks.begin(), new_sinks.end());
99
100 PopulateSinks(old_sinks, new_sinks);
101 EXPECT_CALL(mock_sink_discovered_cb_, Run(new_sinks)).Times(0);
102 media_sink_service_.OnDiscoveryComplete();
103 }
104
TEST_F(MediaSinkServiceBaseTest,TestOnDiscoveryComplete_OneNewSink)105 TEST_F(MediaSinkServiceBaseTest, TestOnDiscoveryComplete_OneNewSink) {
106 std::vector<MediaSinkInternal> old_sinks = CreateDialMediaSinks();
107 std::vector<MediaSinkInternal> new_sinks = CreateDialMediaSinks();
108 MediaSink sink3("sink3", "sink_name_3", SinkIconType::CAST);
109 DialSinkExtraData extra_data3 = CreateDialSinkExtraData(
110 "model_name3", "192.168.1.3", "https://example3.com");
111 new_sinks.push_back(MediaSinkInternal(sink3, extra_data3));
112 TestOnDiscoveryComplete(old_sinks, new_sinks);
113 }
114
TEST_F(MediaSinkServiceBaseTest,TestOnDiscoveryComplete_RemovedOneSink)115 TEST_F(MediaSinkServiceBaseTest, TestOnDiscoveryComplete_RemovedOneSink) {
116 std::vector<MediaSinkInternal> old_sinks = CreateDialMediaSinks();
117 std::vector<MediaSinkInternal> new_sinks = CreateDialMediaSinks();
118 new_sinks.erase(new_sinks.begin());
119 TestOnDiscoveryComplete(old_sinks, new_sinks);
120 }
121
TEST_F(MediaSinkServiceBaseTest,TestOnDiscoveryComplete_UpdatedOneSink)122 TEST_F(MediaSinkServiceBaseTest, TestOnDiscoveryComplete_UpdatedOneSink) {
123 std::vector<MediaSinkInternal> old_sinks = CreateDialMediaSinks();
124 std::vector<MediaSinkInternal> new_sinks = CreateDialMediaSinks();
125 new_sinks[0].sink().set_name("sink_name_4");
126 TestOnDiscoveryComplete(old_sinks, new_sinks);
127 }
128
TEST_F(MediaSinkServiceBaseTest,TestOnDiscoveryComplete_Mixed)129 TEST_F(MediaSinkServiceBaseTest, TestOnDiscoveryComplete_Mixed) {
130 std::vector<MediaSinkInternal> old_sinks = CreateDialMediaSinks();
131
132 MediaSink sink1("sink1", "sink_name_1", SinkIconType::CAST);
133 DialSinkExtraData extra_data2 = CreateDialSinkExtraData(
134 "model_name2", "192.168.1.2", "https://example2.com");
135
136 MediaSink sink3("sink3", "sink_name_3", SinkIconType::CAST);
137 DialSinkExtraData extra_data3 = CreateDialSinkExtraData(
138 "model_name3", "192.168.1.3", "https://example3.com");
139
140 std::vector<MediaSinkInternal> new_sinks;
141 new_sinks.push_back(MediaSinkInternal(sink1, extra_data2));
142 new_sinks.push_back(MediaSinkInternal(sink3, extra_data3));
143
144 TestOnDiscoveryComplete(old_sinks, new_sinks);
145 }
146
147 } // namespace media_router
148