1 // Copyright 2020 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 "cast/sender/cast_app_availability_tracker.h"
6
7 #include "gmock/gmock.h"
8 #include "gtest/gtest.h"
9 #include "platform/test/fake_clock.h"
10
11 namespace openscreen {
12 namespace cast {
13 namespace {
14
15 using ::testing::UnorderedElementsAreArray;
16
17 MATCHER_P(CastMediaSourcesEqual, expected, "") {
18 if (expected.size() != arg.size())
19 return false;
20 return std::equal(
21 expected.begin(), expected.end(), arg.begin(),
__anonf90f4ca60202(const CastMediaSource& source1, const CastMediaSource& source2) 22 [](const CastMediaSource& source1, const CastMediaSource& source2) {
23 return source1.source_id() == source2.source_id();
24 });
25 }
26
27 } // namespace
28
29 class CastAppAvailabilityTrackerTest : public ::testing::Test {
30 public:
CastAppAvailabilityTrackerTest()31 CastAppAvailabilityTrackerTest() : clock_(Clock::now()) {}
32 ~CastAppAvailabilityTrackerTest() override = default;
33
Now() const34 Clock::time_point Now() const { return clock_.now(); }
35
36 protected:
37 FakeClock clock_;
38 CastAppAvailabilityTracker tracker_;
39 };
40
TEST_F(CastAppAvailabilityTrackerTest,RegisterSource)41 TEST_F(CastAppAvailabilityTrackerTest, RegisterSource) {
42 CastMediaSource source1("cast:AAA?clientId=1", {"AAA"});
43 CastMediaSource source2("cast:AAA?clientId=2", {"AAA"});
44
45 std::vector<std::string> expected_app_ids = {"AAA"};
46 EXPECT_EQ(expected_app_ids, tracker_.RegisterSource(source1));
47
48 EXPECT_EQ(std::vector<std::string>{}, tracker_.RegisterSource(source1));
49 EXPECT_EQ(std::vector<std::string>{}, tracker_.RegisterSource(source2));
50
51 tracker_.UnregisterSource(source1);
52 tracker_.UnregisterSource(source2);
53
54 EXPECT_EQ(expected_app_ids, tracker_.RegisterSource(source1));
55 EXPECT_EQ(expected_app_ids, tracker_.GetRegisteredApps());
56 }
57
TEST_F(CastAppAvailabilityTrackerTest,RegisterSourceReturnsMultipleAppIds)58 TEST_F(CastAppAvailabilityTrackerTest, RegisterSourceReturnsMultipleAppIds) {
59 CastMediaSource source1("urn:x-org.chromium.media:source:tab:1",
60 {"0F5096E8", "85CDB22F"});
61
62 // Mirorring app ids.
63 std::vector<std::string> expected_app_ids = {"0F5096E8", "85CDB22F"};
64 EXPECT_THAT(tracker_.RegisterSource(source1),
65 UnorderedElementsAreArray(expected_app_ids));
66 EXPECT_THAT(tracker_.GetRegisteredApps(),
67 UnorderedElementsAreArray(expected_app_ids));
68 }
69
TEST_F(CastAppAvailabilityTrackerTest,MultipleAppIdsAlreadyTrackingOne)70 TEST_F(CastAppAvailabilityTrackerTest, MultipleAppIdsAlreadyTrackingOne) {
71 // One of the mirroring app IDs.
72 CastMediaSource source1("cast:0F5096E8?clientId=123", {"0F5096E8"});
73
74 std::vector<std::string> new_app_ids = {"0F5096E8"};
75 std::vector<std::string> registered_app_ids = {"0F5096E8"};
76 EXPECT_EQ(new_app_ids, tracker_.RegisterSource(source1));
77 EXPECT_EQ(registered_app_ids, tracker_.GetRegisteredApps());
78
79 CastMediaSource source2("urn:x-org.chromium.media:source:tab:1",
80 {"0F5096E8", "85CDB22F"});
81
82 new_app_ids = {"85CDB22F"};
83 registered_app_ids = {"0F5096E8", "85CDB22F"};
84
85 EXPECT_EQ(new_app_ids, tracker_.RegisterSource(source2));
86 EXPECT_THAT(tracker_.GetRegisteredApps(),
87 UnorderedElementsAreArray(registered_app_ids));
88 }
89
TEST_F(CastAppAvailabilityTrackerTest,UpdateAppAvailability)90 TEST_F(CastAppAvailabilityTrackerTest, UpdateAppAvailability) {
91 CastMediaSource source1("cast:AAA?clientId=1", {"AAA"});
92 CastMediaSource source2("cast:AAA?clientId=2", {"AAA"});
93 CastMediaSource source3("cast:BBB?clientId=3", {"BBB"});
94
95 tracker_.RegisterSource(source3);
96
97 // |source3| not affected.
98 EXPECT_THAT(
99 tracker_.UpdateAppAvailability(
100 "deviceId1", "AAA", {AppAvailabilityResult::kAvailable, Now()}),
101 CastMediaSourcesEqual(std::vector<CastMediaSource>()));
102
103 std::vector<std::string> devices_1 = {"deviceId1"};
104 std::vector<std::string> devices_1_2 = {"deviceId1", "deviceId2"};
105 std::vector<CastMediaSource> sources_1 = {source1};
106 std::vector<CastMediaSource> sources_1_2 = {source1, source2};
107
108 // Tracker returns available devices even though sources aren't registered.
109 EXPECT_EQ(devices_1, tracker_.GetAvailableDevices(source1));
110 EXPECT_EQ(devices_1, tracker_.GetAvailableDevices(source2));
111 EXPECT_TRUE(tracker_.GetAvailableDevices(source3).empty());
112
113 tracker_.RegisterSource(source1);
114 // Only |source1| is registered for this app.
115 EXPECT_THAT(
116 tracker_.UpdateAppAvailability(
117 "deviceId2", "AAA", {AppAvailabilityResult::kAvailable, Now()}),
118 CastMediaSourcesEqual(sources_1));
119 EXPECT_THAT(tracker_.GetAvailableDevices(source1),
120 UnorderedElementsAreArray(devices_1_2));
121 EXPECT_THAT(tracker_.GetAvailableDevices(source2),
122 UnorderedElementsAreArray(devices_1_2));
123 EXPECT_TRUE(tracker_.GetAvailableDevices(source3).empty());
124
125 tracker_.RegisterSource(source2);
126 EXPECT_THAT(
127 tracker_.UpdateAppAvailability(
128 "deviceId2", "AAA", {AppAvailabilityResult::kUnavailable, Now()}),
129 CastMediaSourcesEqual(sources_1_2));
130 EXPECT_EQ(devices_1, tracker_.GetAvailableDevices(source1));
131 EXPECT_EQ(devices_1, tracker_.GetAvailableDevices(source2));
132 EXPECT_TRUE(tracker_.GetAvailableDevices(source3).empty());
133 }
134
TEST_F(CastAppAvailabilityTrackerTest,RemoveResultsForDevice)135 TEST_F(CastAppAvailabilityTrackerTest, RemoveResultsForDevice) {
136 CastMediaSource source1("cast:AAA?clientId=1", {"AAA"});
137
138 tracker_.UpdateAppAvailability("deviceId1", "AAA",
139 {AppAvailabilityResult::kAvailable, Now()});
140 EXPECT_EQ(AppAvailabilityResult::kAvailable,
141 tracker_.GetAvailability("deviceId1", "AAA").availability);
142
143 std::vector<std::string> expected_device_ids = {"deviceId1"};
144 EXPECT_EQ(expected_device_ids, tracker_.GetAvailableDevices(source1));
145
146 // Unrelated device ID.
147 tracker_.RemoveResultsForDevice("deviceId2");
148 EXPECT_EQ(AppAvailabilityResult::kAvailable,
149 tracker_.GetAvailability("deviceId1", "AAA").availability);
150 EXPECT_EQ(expected_device_ids, tracker_.GetAvailableDevices(source1));
151
152 tracker_.RemoveResultsForDevice("deviceId1");
153 EXPECT_EQ(AppAvailabilityResult::kUnknown,
154 tracker_.GetAvailability("deviceId1", "AAA").availability);
155 EXPECT_EQ(std::vector<std::string>{}, tracker_.GetAvailableDevices(source1));
156 }
157
158 } // namespace cast
159 } // namespace openscreen
160