| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2014 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 "base/macros.h" |
| 6 #include "base/run_loop.h" |
| 7 #include "content/renderer/presentation/presentation_dispatcher.h" |
| 8 #include "mojo/public/cpp/bindings/interface_ptr.h" |
| 9 #include "testing/gmock/include/gmock/gmock.h" |
| 10 #include "testing/gtest/include/gtest/gtest.h" |
| 11 #include "third_party/WebKit/public/platform/modules/presentation/WebPresentatio
nAvailabilityObserver.h" |
| 12 #include "third_party/WebKit/public/platform/modules/presentation/WebPresentatio
nClient.h" |
| 13 #include "third_party/WebKit/public/platform/modules/presentation/WebPresentatio
nError.h" |
| 14 #include "third_party/WebKit/public/platform/modules/presentation/presentation.m
ojom.h" |
| 15 |
| 16 using ::testing::_; |
| 17 |
| 18 namespace content { |
| 19 |
| 20 class MockPresentationService : public blink::mojom::PresentationService { |
| 21 public: |
| 22 void SetClient(blink::mojom::PresentationServiceClientPtr client) override { |
| 23 SetClient(*client); |
| 24 } |
| 25 MOCK_METHOD1(SetClient, void(const blink::mojom::PresentationServiceClient&)); |
| 26 MOCK_METHOD1(SetDefaultPresentationUrls, void(const std::vector<GURL>&)); |
| 27 MOCK_METHOD1(ListenForScreenAvailability, void(const GURL&)); |
| 28 MOCK_METHOD1(StopListeningForScreenAvailability, void(const GURL&)); |
| 29 MOCK_METHOD2(StartSession, |
| 30 void(const std::vector<GURL>&, const StartSessionCallback&)); |
| 31 MOCK_METHOD3(JoinSession, |
| 32 void(const std::vector<GURL>&, |
| 33 const base::Optional<std::string>&, |
| 34 const JoinSessionCallback&)); |
| 35 void SendConnectionMessage( |
| 36 blink::mojom::PresentationSessionInfoPtr sessionInfo, |
| 37 blink::mojom::ConnectionMessagePtr message_request, |
| 38 const SendConnectionMessageCallback& callback) override { |
| 39 SendConnectionMessage(*sessionInfo, *message_request, callback); |
| 40 } |
| 41 MOCK_METHOD3(SendConnectionMessage, |
| 42 void(blink::mojom::PresentationSessionInfo, |
| 43 blink::mojom::ConnectionMessage, |
| 44 const SendConnectionMessageCallback&)); |
| 45 MOCK_METHOD2(CloseConnection, void(const GURL&, const std::string&)); |
| 46 MOCK_METHOD2(Terminate, void(const GURL&, const std::string&)); |
| 47 void ListenForConnectionMessages( |
| 48 blink::mojom::PresentationSessionInfoPtr sessionInfo) override { |
| 49 ListenForConnectionMessages(*sessionInfo); |
| 50 } |
| 51 MOCK_METHOD1(ListenForConnectionMessages, |
| 52 void(const blink::mojom::PresentationSessionInfo&)); |
| 53 }; |
| 54 |
| 55 class MockPresentationAvailabilityCallbacks final |
| 56 : public blink::WebCallbacks<bool, const blink::WebPresentationError&> { |
| 57 public: |
| 58 MOCK_METHOD1(onSuccess, void(bool value)); |
| 59 MOCK_METHOD1(onError, void(const blink::WebPresentationError&)); |
| 60 }; |
| 61 |
| 62 class MockPresentationAvailabilityObserver |
| 63 : public blink::WebPresentationAvailabilityObserver { |
| 64 public: |
| 65 MockPresentationAvailabilityObserver( |
| 66 const blink::WebVector<blink::WebURL>& urls) |
| 67 : urls_(urls) {} |
| 68 |
| 69 MOCK_METHOD1(availabilityChanged, void(bool)); |
| 70 |
| 71 const blink::WebVector<blink::WebURL>& urls() const override { return urls_; } |
| 72 |
| 73 blink::WebVector<blink::WebURL> urls_; |
| 74 }; |
| 75 |
| 76 class PresentationDispatcherTest : public testing::Test { |
| 77 public: |
| 78 enum class URLState { Available, Unavailable, Unsupported }; |
| 79 |
| 80 PresentationDispatcherTest() { |
| 81 urls_ = {GURL("http://example0.com/"), GURL("http://example1.com/"), |
| 82 GURL("http://example2.com/"), GURL("http://example3.com/")}; |
| 83 |
| 84 blink::WebVector<blink::WebURL> urls_1(static_cast<size_t>(3)); |
| 85 urls_1[0] = urls_[0]; |
| 86 urls_1[1] = urls_[1]; |
| 87 urls_1[2] = urls_[2]; |
| 88 |
| 89 blink::WebVector<blink::WebURL> urls_2(static_cast<size_t>(3)); |
| 90 urls_2[0] = urls_[1]; |
| 91 urls_2[1] = urls_[2]; |
| 92 urls_2[2] = urls_[3]; |
| 93 |
| 94 blink::WebVector<blink::WebURL> urls_3(static_cast<size_t>(2)); |
| 95 urls_3[0] = urls_[1]; |
| 96 urls_3[1] = urls_[3]; |
| 97 |
| 98 urls_set_ = {urls_1, urls_2, urls_3}; |
| 99 } |
| 100 |
| 101 ~PresentationDispatcherTest() override {} |
| 102 |
| 103 void SetUp() override { |
| 104 client_ = base::MakeUnique<PresentationDispatcher>(nullptr); |
| 105 |
| 106 blink::mojom::PresentationServicePtr service_ptr; |
| 107 service_binding_ = new mojo::Binding<blink::mojom::PresentationService>( |
| 108 &mock_presentation_service_, mojo::GetProxy(&service_ptr)); |
| 109 client_->SetPresentationServiceForTest(std::move(service_ptr)); |
| 110 |
| 111 for (const auto& urls : urls_set_) { |
| 112 mock_observers_.push_back( |
| 113 base::MakeUnique<MockPresentationAvailabilityObserver>(urls)); |
| 114 } |
| 115 } |
| 116 |
| 117 void ChangeURLState(const GURL& url, URLState state) { |
| 118 switch (state) { |
| 119 case URLState::Available: |
| 120 client_->OnScreenAvailabilityUpdated(url, true); |
| 121 break; |
| 122 case URLState::Unavailable: |
| 123 client_->OnScreenAvailabilityUpdated(url, false); |
| 124 break; |
| 125 case URLState::Unsupported: |
| 126 client_->OnScreenAvailabilityNotSupported(url); |
| 127 break; |
| 128 } |
| 129 } |
| 130 |
| 131 void StartListening(MockPresentationAvailabilityObserver* observer) { |
| 132 client_->startListening(observer); |
| 133 } |
| 134 |
| 135 void StopListening(MockPresentationAvailabilityObserver* observer) { |
| 136 client_->stopListening(observer); |
| 137 } |
| 138 |
| 139 void TestGetAvailabilityKUrls( |
| 140 size_t k, |
| 141 std::vector<URLState> states, |
| 142 MockPresentationAvailabilityCallbacks* mock_callback) { |
| 143 blink::WebVector<blink::WebURL> urls(k); |
| 144 |
| 145 for (size_t i = 0; i < k; i++) { |
| 146 GURL url("http://example" + std::to_string(i) + ".com/"); |
| 147 urls[i] = url; |
| 148 EXPECT_CALL(mock_presentation_service_, ListenForScreenAvailability(url)) |
| 149 .Times(1); |
| 150 if (states.size() == k) { |
| 151 EXPECT_CALL(mock_presentation_service_, |
| 152 StopListeningForScreenAvailability(url)) |
| 153 .Times(1); |
| 154 } |
| 155 } |
| 156 |
| 157 base::RunLoop run_loop; |
| 158 |
| 159 client()->getAvailability(urls, base::WrapUnique(mock_callback)); |
| 160 for (size_t i = 0; i < std::min(k, states.size()); i++) |
| 161 ChangeURLState(urls[i], states[i]); |
| 162 |
| 163 run_loop.RunUntilIdle(); |
| 164 } |
| 165 |
| 166 void StartListeningToMultipleRequests() { |
| 167 for (const auto& url : urls_) { |
| 168 EXPECT_CALL(mock_presentation_service_, ListenForScreenAvailability(url)) |
| 169 .Times(1); |
| 170 EXPECT_CALL(mock_presentation_service_, |
| 171 StopListeningForScreenAvailability(url)) |
| 172 .Times(1); |
| 173 } |
| 174 |
| 175 base::RunLoop run_loop; |
| 176 |
| 177 for (const auto& urls : urls_set_) { |
| 178 auto* mock_callback = new MockPresentationAvailabilityCallbacks(); |
| 179 EXPECT_CALL(*mock_callback, onSuccess(false)).Times(1); |
| 180 client()->getAvailability(urls, base::WrapUnique(mock_callback)); |
| 181 } |
| 182 |
| 183 // Clean up callbacks. |
| 184 for (const auto& url : urls_) |
| 185 ChangeURLState(url, URLState::Unavailable); |
| 186 |
| 187 run_loop.RunUntilIdle(); |
| 188 |
| 189 for (const auto& url : urls_) { |
| 190 EXPECT_CALL(mock_presentation_service_, ListenForScreenAvailability(url)) |
| 191 .Times(1); |
| 192 } |
| 193 |
| 194 base::RunLoop run_loop_2; |
| 195 for (const auto& mock_observer : mock_observers_) |
| 196 StartListening(mock_observer.get()); |
| 197 run_loop_2.RunUntilIdle(); |
| 198 } |
| 199 |
| 200 blink::WebPresentationClient* client() { return client_.get(); } |
| 201 |
| 202 std::unique_ptr<PresentationDispatcher> client_; |
| 203 MockPresentationService mock_presentation_service_; |
| 204 mojo::Binding<blink::mojom::PresentationService>* service_binding_; |
| 205 base::MessageLoop message_loop_; |
| 206 |
| 207 std::vector<GURL> urls_; |
| 208 std::vector<blink::WebVector<blink::WebURL>> urls_set_; |
| 209 std::vector<std::unique_ptr<MockPresentationAvailabilityObserver>> |
| 210 mock_observers_; |
| 211 |
| 212 DISALLOW_COPY_AND_ASSIGN(PresentationDispatcherTest); |
| 213 }; |
| 214 |
| 215 TEST_F(PresentationDispatcherTest, GetAvailabilityOneUrlNoAvailabilityChange) { |
| 216 auto* mock_callback = new MockPresentationAvailabilityCallbacks(); |
| 217 std::vector<URLState> states; |
| 218 TestGetAvailabilityKUrls(1, states, mock_callback); |
| 219 } |
| 220 |
| 221 TEST_F(PresentationDispatcherTest, GetAvailabilityOneUrlBecomesAvailable) { |
| 222 auto* mock_callback = new MockPresentationAvailabilityCallbacks(); |
| 223 EXPECT_CALL(*mock_callback, onSuccess(true)); |
| 224 std::vector<URLState> states = {URLState::Available}; |
| 225 TestGetAvailabilityKUrls(1, states, mock_callback); |
| 226 } |
| 227 |
| 228 TEST_F(PresentationDispatcherTest, GetAvailabilityOneUrlBecomesUnavailable) { |
| 229 auto* mock_callback = new MockPresentationAvailabilityCallbacks(); |
| 230 EXPECT_CALL(*mock_callback, onSuccess(false)); |
| 231 |
| 232 std::vector<URLState> states = {URLState::Unavailable}; |
| 233 TestGetAvailabilityKUrls(1, states, mock_callback); |
| 234 } |
| 235 |
| 236 TEST_F(PresentationDispatcherTest, GetAvailabilityOneUrlBecomesNotSupported) { |
| 237 auto* mock_callback = new MockPresentationAvailabilityCallbacks(); |
| 238 EXPECT_CALL(*mock_callback, onError(_)); |
| 239 |
| 240 std::vector<URLState> states = {URLState::Unsupported}; |
| 241 TestGetAvailabilityKUrls(1, states, mock_callback); |
| 242 } |
| 243 |
| 244 TEST_F(PresentationDispatcherTest, |
| 245 GetAvailabilityMultipleUrlsAllBecomesAvailable) { |
| 246 auto* mock_callback = new MockPresentationAvailabilityCallbacks(); |
| 247 EXPECT_CALL(*mock_callback, onSuccess(true)).Times(1); |
| 248 |
| 249 std::vector<URLState> state_seq = {URLState::Available, URLState::Available}; |
| 250 TestGetAvailabilityKUrls(2, state_seq, mock_callback); |
| 251 } |
| 252 |
| 253 TEST_F(PresentationDispatcherTest, |
| 254 GetAvailabilityMultipleUrlsAllBecomesUnavailable) { |
| 255 auto* mock_callback = new MockPresentationAvailabilityCallbacks(); |
| 256 EXPECT_CALL(*mock_callback, onSuccess(false)).Times(1); |
| 257 |
| 258 std::vector<URLState> state_seq = {URLState::Unavailable, |
| 259 URLState::Unavailable}; |
| 260 TestGetAvailabilityKUrls(2, state_seq, mock_callback); |
| 261 } |
| 262 |
| 263 TEST_F(PresentationDispatcherTest, |
| 264 GetAvailabilityMultipleUrlsAllBecomesUnsupported) { |
| 265 auto* mock_callback = new MockPresentationAvailabilityCallbacks(); |
| 266 EXPECT_CALL(*mock_callback, onError(_)).Times(1); |
| 267 |
| 268 std::vector<URLState> state_seq = {URLState::Available, |
| 269 URLState::Unsupported}; |
| 270 TestGetAvailabilityKUrls(2, state_seq, mock_callback); |
| 271 } |
| 272 |
| 273 TEST_F(PresentationDispatcherTest, |
| 274 GetAvailabilityMultipleUrlsOneBecomesAvailable) { |
| 275 auto* mock_callback = new MockPresentationAvailabilityCallbacks(); |
| 276 EXPECT_CALL(*mock_callback, onSuccess(true)).Times(1); |
| 277 |
| 278 std::vector<URLState> state_seq = {URLState::Unavailable, |
| 279 URLState::Available}; |
| 280 TestGetAvailabilityKUrls(2, state_seq, mock_callback); |
| 281 } |
| 282 |
| 283 TEST_F(PresentationDispatcherTest, |
| 284 GetAvailabilityReturnsDirectlyForAlreadyListeningUrls) { |
| 285 auto* mock_callback_1 = new MockPresentationAvailabilityCallbacks(); |
| 286 EXPECT_CALL(*mock_callback_1, onSuccess(true)).Times(1); |
| 287 |
| 288 std::vector<URLState> state_seq = {URLState::Available, URLState::Unavailable, |
| 289 URLState::Unavailable}; |
| 290 TestGetAvailabilityKUrls(3, state_seq, mock_callback_1); |
| 291 |
| 292 base::RunLoop run_loop; |
| 293 |
| 294 blink::WebVector<blink::WebURL> urls(static_cast<size_t>(2)); |
| 295 urls[0] = GURL("http://example0.com"); |
| 296 urls[1] = GURL("http://example1.com"); |
| 297 |
| 298 auto* mock_callback_2 = new MockPresentationAvailabilityCallbacks(); |
| 299 EXPECT_CALL(*mock_callback_2, onSuccess(true)).Times(1); |
| 300 |
| 301 client()->getAvailability(urls, base::WrapUnique(mock_callback_2)); |
| 302 |
| 303 run_loop.RunUntilIdle(); |
| 304 } |
| 305 |
| 306 TEST_F(PresentationDispatcherTest, StartListeningListenToEachURLOnce) { |
| 307 StartListeningToMultipleRequests(); |
| 308 } |
| 309 |
| 310 TEST_F(PresentationDispatcherTest, StopListeningListenToEachURLOnce) { |
| 311 StartListeningToMultipleRequests(); |
| 312 |
| 313 for (const auto& url : urls_) { |
| 314 EXPECT_CALL(mock_presentation_service_, |
| 315 StopListeningForScreenAvailability(url)) |
| 316 .Times(1); |
| 317 } |
| 318 |
| 319 base::RunLoop run_loop; |
| 320 for (const auto& mock_observer : mock_observers_) |
| 321 StopListening(mock_observer.get()); |
| 322 run_loop.RunUntilIdle(); |
| 323 } |
| 324 |
| 325 TEST_F(PresentationDispatcherTest, |
| 326 StopListeningDoesNotStopIfURLListenedByOthers) { |
| 327 StartListeningToMultipleRequests(); |
| 328 |
| 329 EXPECT_CALL(mock_presentation_service_, |
| 330 StopListeningForScreenAvailability(urls_[0])) |
| 331 .Times(1); |
| 332 |
| 333 base::RunLoop run_loop; |
| 334 StopListening(mock_observers_[0].get()); |
| 335 run_loop.RunUntilIdle(); |
| 336 } |
| 337 |
| 338 TEST_F(PresentationDispatcherTest, |
| 339 OnScreenAvailabilityUpdatedInvokesAvailabilityChanged) { |
| 340 StartListeningToMultipleRequests(); |
| 341 |
| 342 EXPECT_CALL(*(mock_observers_[0]), availabilityChanged(true)); |
| 343 |
| 344 base::RunLoop run_loop; |
| 345 ChangeURLState(urls_[0], URLState::Available); |
| 346 run_loop.RunUntilIdle(); |
| 347 } |
| 348 |
| 349 TEST_F(PresentationDispatcherTest, |
| 350 OnScreenAvailabilityUpdatedInvokesMultipleAvailabilityChanged) { |
| 351 StartListeningToMultipleRequests(); |
| 352 |
| 353 for (const auto& mock_observer : mock_observers_) |
| 354 EXPECT_CALL(*mock_observer, availabilityChanged(true)); |
| 355 |
| 356 base::RunLoop run_loop; |
| 357 ChangeURLState(urls_[1], URLState::Available); |
| 358 run_loop.RunUntilIdle(); |
| 359 } |
| 360 |
| 361 } // namespace content |
| OLD | NEW |