Chromium Code Reviews| Index: content/renderer/presentation/presentation_dispatcher_unittest.cc |
| diff --git a/content/renderer/presentation/presentation_dispatcher_unittest.cc b/content/renderer/presentation/presentation_dispatcher_unittest.cc |
| index 65b3a8979899d814a372736c8bac20a4e1e90911..11a9cbfccf0b82085e991dd1997479ca7bd753fc 100644 |
| --- a/content/renderer/presentation/presentation_dispatcher_unittest.cc |
| +++ b/content/renderer/presentation/presentation_dispatcher_unittest.cc |
| @@ -47,8 +47,8 @@ namespace content { |
| class MockPresentationAvailabilityObserver |
| : public WebPresentationAvailabilityObserver { |
| public: |
| - explicit MockPresentationAvailabilityObserver(const WebVector<WebURL>& urls) |
| - : urls_(urls) {} |
| + explicit MockPresentationAvailabilityObserver(const std::vector<GURL>& gurls) |
|
mark a. foltz
2017/01/17 21:04:24
Nit: s/gurls/urls/ for consistency
zhaobin
2017/01/18 03:38:57
Done.
|
| + : urls_(gurls) {} |
| ~MockPresentationAvailabilityObserver() override {} |
| MOCK_METHOD1(availabilityChanged, void(bool is_available)); |
| @@ -105,6 +105,13 @@ class MockPresentationService : public PresentationService { |
| void(PresentationSessionInfo* session_info)); |
| }; |
| +class MockPresentationAvailabilityCallbacks |
| + : public blink::WebCallbacks<bool, const blink::WebPresentationError&> { |
| + public: |
| + MOCK_METHOD1(onSuccess, void(bool value)); |
| + MOCK_METHOD1(onError, void(const blink::WebPresentationError&)); |
| +}; |
| + |
| class TestWebPresentationConnectionCallback |
| : public WebPresentationConnectionCallback { |
| public: |
| @@ -172,17 +179,28 @@ class TestPresentationDispatcher : public PresentationDispatcher { |
| class PresentationDispatcherTest : public ::testing::Test { |
| public: |
| + enum class URLState { Available, Unavailable, Unsupported, Unknown }; |
| + |
| PresentationDispatcherTest() |
| : gurl1_(GURL("https://www.example.com/1.html")), |
| gurl2_(GURL("https://www.example.com/2.html")), |
| - gurls_({gurl1_, gurl2_}), |
| + gurl3_(GURL("https://www.example.com/3.html")), |
| + gurl4_(GURL("https://www.example.com/4.html")), |
| + gurls_({gurl1_, gurl2_, gurl3_, gurl4_}), |
| url1_(WebURL(gurl1_)), |
| url2_(WebURL(gurl2_)), |
| + url3_(WebURL(gurl3_)), |
| + url4_(WebURL(gurl4_)), |
| urls_(WebVector<WebURL>(gurls_)), |
| presentation_id_(WebString::fromUTF8("test-id")), |
| array_buffer_(WebArrayBuffer::create(4, 1)), |
| - observer_(urls_), |
| + observer_(gurls_), |
| + mock_observer1_({gurl1_, gurl2_, gurl3_}), |
| + mock_observer2_({gurl2_, gurl3_, gurl4_}), |
| + mock_observer3_({gurl2_, gurl3_}), |
| + mock_observers_({&mock_observer1_, &mock_observer2_, &mock_observer3_}), |
| dispatcher_(&presentation_service_) {} |
| + |
| ~PresentationDispatcherTest() override {} |
| void SetUp() override { |
| @@ -194,16 +212,65 @@ class PresentationDispatcherTest : public ::testing::Test { |
| return static_cast<uint8_t*>(array_buffer_.data()); |
| } |
| + void ChangeURLState(const GURL& url, URLState state) { |
| + switch (state) { |
| + case URLState::Available: |
| + dispatcher_.OnScreenAvailabilityUpdated(url, true); |
| + break; |
| + case URLState::Unavailable: |
| + dispatcher_.OnScreenAvailabilityUpdated(url, false); |
| + break; |
| + case URLState::Unsupported: |
| + dispatcher_.OnScreenAvailabilityNotSupported(url); |
| + break; |
| + case URLState::Unknown: |
| + break; |
| + } |
| + } |
| + |
| + // Tests that PresenationService is called for getAvailability(urls), after |
| + // |urls| change state to |states|. |
| + void TestGetAvailability( |
| + const std::vector<GURL>& urls, |
| + const std::vector<URLState>& states, |
| + MockPresentationAvailabilityCallbacks* mock_callback) { |
| + DCHECK_EQ(urls.size(), states.size()); |
| + |
| + for (const auto& url : urls) { |
| + EXPECT_CALL(presentation_service_, ListenForScreenAvailability(url)) |
| + .Times(1); |
| + } |
| + |
| + base::RunLoop run_loop; |
| + // This function takes ownership of |mock_callback|. |
|
mark a. foltz
2017/01/17 21:04:24
This comment probably belongs with the function-le
zhaobin
2017/01/18 03:38:57
Done.
|
| + client()->getAvailability(urls, base::WrapUnique(mock_callback)); |
| + for (size_t i = 0; i < urls.size(); i++) |
| + ChangeURLState(urls[i], states[i]); |
| + |
| + run_loop.RunUntilIdle(); |
| + } |
| + |
| + blink::WebPresentationClient* client() { return &dispatcher_; } |
| + |
| protected: |
| const GURL gurl1_; |
| const GURL gurl2_; |
| + const GURL gurl3_; |
| + const GURL gurl4_; |
| const std::vector<GURL> gurls_; |
| const WebURL url1_; |
| const WebURL url2_; |
| + const WebURL url3_; |
| + const WebURL url4_; |
| const WebVector<WebURL> urls_; |
| const WebString presentation_id_; |
| const WebArrayBuffer array_buffer_; |
| MockPresentationAvailabilityObserver observer_; |
| + MockPresentationAvailabilityObserver mock_observer1_; |
| + MockPresentationAvailabilityObserver mock_observer2_; |
| + MockPresentationAvailabilityObserver mock_observer3_; |
| + std::vector<MockPresentationAvailabilityObserver*> mock_observers_; |
| + |
| MockPresentationService presentation_service_; |
| TestPresentationDispatcher dispatcher_; |
| @@ -223,7 +290,7 @@ TEST_F(PresentationDispatcherTest, TestStartSession) { |
| session_info->id = presentation_id_.utf8(); |
| callback.Run(std::move(session_info), PresentationErrorPtr()); |
| })); |
| - dispatcher_.startSession( |
| + client()->startSession( |
| urls_, base::MakeUnique<TestWebPresentationConnectionCallback>( |
| url1_, presentation_id_)); |
| run_loop.RunUntilIdle(); |
| @@ -242,7 +309,7 @@ TEST_F(PresentationDispatcherTest, TestStartSessionError) { |
| error->message = error_message.utf8(); |
| callback.Run(PresentationSessionInfoPtr(), std::move(error)); |
| })); |
| - dispatcher_.startSession( |
| + client()->startSession( |
| urls_, |
| base::MakeUnique<TestWebPresentationConnectionErrorCallback>( |
| WebPresentationError::ErrorTypeNoAvailableScreens, error_message)); |
| @@ -372,15 +439,15 @@ TEST_F(PresentationDispatcherTest, TestTerminateSession) { |
| TEST_F(PresentationDispatcherTest, TestListenForScreenAvailability) { |
| base::RunLoop run_loop1; |
| - EXPECT_CALL(presentation_service_, ListenForScreenAvailability(gurl1_)); |
| + for (const auto& gurl : gurls_) |
| + EXPECT_CALL(presentation_service_, ListenForScreenAvailability(gurl)); |
| dispatcher_.getAvailability( |
| urls_, base::MakeUnique<WebPresentationAvailabilityCallbacks>()); |
| dispatcher_.OnScreenAvailabilityUpdated(url1_, true); |
| run_loop1.RunUntilIdle(); |
| base::RunLoop run_loop2; |
| - EXPECT_CALL(presentation_service_, ListenForScreenAvailability(gurl1_)); |
| - dispatcher_.startListening(&observer_); |
| + client()->startListening(&observer_); |
| run_loop2.RunUntilIdle(); |
| base::RunLoop run_loop3; |
| @@ -388,9 +455,11 @@ TEST_F(PresentationDispatcherTest, TestListenForScreenAvailability) { |
| dispatcher_.OnScreenAvailabilityUpdated(url1_, false); |
| EXPECT_CALL(observer_, availabilityChanged(true)); |
| dispatcher_.OnScreenAvailabilityUpdated(url1_, true); |
| - EXPECT_CALL(presentation_service_, |
| - StopListeningForScreenAvailability(gurl1_)); |
| - dispatcher_.stopListening(&observer_); |
| + for (const auto& gurl : gurls_) { |
| + EXPECT_CALL(presentation_service_, |
| + StopListeningForScreenAvailability(gurl)); |
| + } |
| + client()->stopListening(&observer_); |
| run_loop3.RunUntilIdle(); |
| // After stopListening(), |observer_| should no longer be notified. |
| @@ -407,4 +476,214 @@ TEST_F(PresentationDispatcherTest, TestSetDefaultPresentationUrls) { |
| run_loop.RunUntilIdle(); |
| } |
| +TEST_F(PresentationDispatcherTest, GetAvailabilityOneUrlNoAvailabilityChange) { |
| + auto* mock_callback = |
| + new testing::StrictMock<MockPresentationAvailabilityCallbacks>(); |
| + TestGetAvailability({url1_}, {URLState::Unknown}, mock_callback); |
| +} |
| + |
| +TEST_F(PresentationDispatcherTest, GetAvailabilityOneUrlBecomesAvailable) { |
| + auto* mock_callback = new MockPresentationAvailabilityCallbacks(); |
| + EXPECT_CALL(*mock_callback, onSuccess(true)); |
| + |
| + TestGetAvailability({url1_}, {URLState::Available}, mock_callback); |
| +} |
| + |
| +TEST_F(PresentationDispatcherTest, GetAvailabilityOneUrlBecomesUnavailable) { |
| + auto* mock_callback = new MockPresentationAvailabilityCallbacks(); |
| + EXPECT_CALL(*mock_callback, onSuccess(false)); |
| + |
| + TestGetAvailability({url1_}, {URLState::Unavailable}, mock_callback); |
| +} |
| + |
| +TEST_F(PresentationDispatcherTest, GetAvailabilityOneUrlBecomesNotSupported) { |
| + auto* mock_callback = new MockPresentationAvailabilityCallbacks(); |
| + EXPECT_CALL(*mock_callback, onError(_)); |
| + EXPECT_CALL(presentation_service_, |
| + StopListeningForScreenAvailability(gurl1_)); |
| + |
| + TestGetAvailability({url1_}, {URLState::Unsupported}, mock_callback); |
| +} |
| + |
| +TEST_F(PresentationDispatcherTest, |
| + GetAvailabilityMultipleUrlsAllBecomesAvailable) { |
| + auto* mock_callback = new MockPresentationAvailabilityCallbacks(); |
| + EXPECT_CALL(*mock_callback, onSuccess(true)).Times(1); |
| + |
| + TestGetAvailability({url1_, url2_}, |
| + {URLState::Available, URLState::Available}, |
| + mock_callback); |
| +} |
| + |
| +TEST_F(PresentationDispatcherTest, |
| + GetAvailabilityMultipleUrlsAllBecomesUnavailable) { |
| + auto* mock_callback = new MockPresentationAvailabilityCallbacks(); |
| + EXPECT_CALL(*mock_callback, onSuccess(false)).Times(1); |
| + |
| + TestGetAvailability({url1_, url2_}, |
| + {URLState::Unavailable, URLState::Unavailable}, |
| + mock_callback); |
| +} |
| + |
| +TEST_F(PresentationDispatcherTest, |
| + GetAvailabilityMultipleUrlsAllBecomesUnsupported) { |
| + auto* mock_callback = new MockPresentationAvailabilityCallbacks(); |
| + EXPECT_CALL(*mock_callback, onError(_)).Times(1); |
| + EXPECT_CALL(presentation_service_, |
| + StopListeningForScreenAvailability(gurl1_)); |
| + EXPECT_CALL(presentation_service_, |
| + StopListeningForScreenAvailability(gurl2_)); |
| + |
| + TestGetAvailability({url1_, url2_}, |
| + {URLState::Unsupported, URLState::Unsupported}, |
| + mock_callback); |
| +} |
| + |
| +TEST_F(PresentationDispatcherTest, |
| + GetAvailabilityReturnsDirectlyForAlreadyListeningUrls) { |
| + auto* mock_callback_1 = new MockPresentationAvailabilityCallbacks(); |
| + EXPECT_CALL(*mock_callback_1, onSuccess(false)).Times(1); |
| + |
| + std::vector<URLState> state_seq = {URLState::Unavailable, URLState::Available, |
| + URLState::Unavailable}; |
| + TestGetAvailability({url1_, url2_, url3_}, state_seq, mock_callback_1); |
| + |
| + auto* mock_callback_2 = new MockPresentationAvailabilityCallbacks(); |
| + EXPECT_CALL(*mock_callback_2, onSuccess(true)).Times(1); |
| + |
| + base::RunLoop run_loop; |
| + client()->getAvailability(mock_observer3_.urls(), |
| + base::WrapUnique(mock_callback_2)); |
| + run_loop.RunUntilIdle(); |
| +} |
| + |
| +TEST_F(PresentationDispatcherTest, StartListeningListenToEachURLOnce) { |
| + for (const auto& gurl : gurls_) { |
| + EXPECT_CALL(presentation_service_, ListenForScreenAvailability(gurl)) |
| + .Times(1); |
| + } |
| + |
| + base::RunLoop run_loop; |
| + for (auto* mock_observer : mock_observers_) { |
| + client()->getAvailability( |
| + mock_observer->urls(), |
| + base::MakeUnique<WebPresentationAvailabilityCallbacks>()); |
| + client()->startListening(mock_observer); |
| + } |
| + run_loop.RunUntilIdle(); |
| +} |
| + |
| +TEST_F(PresentationDispatcherTest, StopListeningListenToEachURLOnce) { |
| + for (const auto& gurl : gurls_) { |
| + EXPECT_CALL(presentation_service_, ListenForScreenAvailability(gurl)) |
| + .Times(1); |
| + EXPECT_CALL(presentation_service_, StopListeningForScreenAvailability(gurl)) |
| + .Times(1); |
| + } |
| + |
| + // Set up |availability_set_| and |listening_status_| |
| + base::RunLoop run_loop; |
| + for (auto* mock_observer : mock_observers_) { |
| + client()->getAvailability( |
| + mock_observer->urls(), |
| + base::MakeUnique<WebPresentationAvailabilityCallbacks>()); |
| + } |
| + // Clean up callbacks. |
| + ChangeURLState(gurl2_, URLState::Unavailable); |
| + |
| + for (auto* mock_observer : mock_observers_) |
| + client()->startListening(mock_observer); |
| + for (auto* mock_observer : mock_observers_) |
| + client()->stopListening(mock_observer); |
| + |
| + run_loop.RunUntilIdle(); |
| +} |
| + |
| +TEST_F(PresentationDispatcherTest, |
| + StopListeningDoesNotStopIfURLListenedByOthers) { |
| + for (const auto& gurl : gurls_) { |
| + EXPECT_CALL(presentation_service_, ListenForScreenAvailability(gurl)) |
| + .Times(1); |
| + } |
| + EXPECT_CALL(presentation_service_, StopListeningForScreenAvailability(gurl1_)) |
| + .Times(1); |
| + EXPECT_CALL(presentation_service_, StopListeningForScreenAvailability(gurl2_)) |
| + .Times(0); |
| + EXPECT_CALL(presentation_service_, StopListeningForScreenAvailability(gurl3_)) |
| + .Times(0); |
| + |
| + // Set up |availability_set_| and |listening_status_| |
| + base::RunLoop run_loop; |
| + for (auto& mock_observer : mock_observers_) { |
| + client()->getAvailability( |
| + mock_observer->urls(), |
| + base::MakeUnique<WebPresentationAvailabilityCallbacks>()); |
| + } |
| + |
| + for (auto* mock_observer : mock_observers_) |
| + client()->startListening(mock_observer); |
| + |
| + EXPECT_CALL(mock_observer1_, availabilityChanged(false)); |
| + EXPECT_CALL(mock_observer2_, availabilityChanged(false)); |
| + |
| + // Clean up callbacks. |
| + ChangeURLState(gurl2_, URLState::Unavailable); |
| + client()->stopListening(&mock_observer1_); |
| + run_loop.RunUntilIdle(); |
| +} |
| + |
| +TEST_F(PresentationDispatcherTest, |
| + OnScreenAvailabilityUpdatedInvokesAvailabilityChanged) { |
| + for (const auto& gurl : gurls_) { |
| + EXPECT_CALL(presentation_service_, ListenForScreenAvailability(gurl)) |
| + .Times(1); |
| + } |
| + EXPECT_CALL(mock_observer1_, availabilityChanged(true)); |
| + |
| + base::RunLoop run_loop; |
| + for (auto* mock_observer : mock_observers_) { |
| + client()->getAvailability( |
| + mock_observer->urls(), |
| + base::MakeUnique<WebPresentationAvailabilityCallbacks>()); |
| + client()->startListening(mock_observer); |
| + } |
| + |
| + ChangeURLState(gurl1_, URLState::Available); |
| + run_loop.RunUntilIdle(); |
| + |
| + EXPECT_CALL(mock_observer1_, availabilityChanged(false)); |
| + |
| + base::RunLoop run_loop_2; |
| + ChangeURLState(gurl1_, URLState::Unavailable); |
| + run_loop_2.RunUntilIdle(); |
| +} |
| + |
| +TEST_F(PresentationDispatcherTest, |
| + OnScreenAvailabilityUpdatedInvokesMultipleAvailabilityChanged) { |
| + for (const auto& gurl : gurls_) { |
| + EXPECT_CALL(presentation_service_, ListenForScreenAvailability(gurl)) |
| + .Times(1); |
| + } |
| + for (auto* mock_observer : mock_observers_) |
| + EXPECT_CALL(*mock_observer, availabilityChanged(true)); |
| + |
| + base::RunLoop run_loop; |
| + for (auto* mock_observer : mock_observers_) { |
| + client()->getAvailability( |
| + mock_observer->urls(), |
| + base::MakeUnique<WebPresentationAvailabilityCallbacks>()); |
| + client()->startListening(mock_observer); |
| + } |
| + |
| + ChangeURLState(gurl2_, URLState::Available); |
| + run_loop.RunUntilIdle(); |
| + |
| + for (auto* mock_observer : mock_observers_) |
| + EXPECT_CALL(*mock_observer, availabilityChanged(false)); |
| + |
| + base::RunLoop run_loop_2; |
| + ChangeURLState(gurl2_, URLState::Unavailable); |
| + run_loop_2.RunUntilIdle(); |
| +} |
| + |
| } // namespace content |