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 |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..0fffe1e88d9d544bd0a9745976644e15520ed059 |
| --- /dev/null |
| +++ b/content/renderer/presentation/presentation_dispatcher_unittest.cc |
| @@ -0,0 +1,403 @@ |
| +// Copyright 2014 The Chromium Authors. All rights reserved. |
|
mark a. foltz
2017/01/13 19:01:15
s/2014/2017/
|
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "base/macros.h" |
| +#include "base/run_loop.h" |
| +#include "content/renderer/presentation/presentation_dispatcher.h" |
| +#include "mojo/public/cpp/bindings/interface_ptr.h" |
| +#include "testing/gmock/include/gmock/gmock.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| +#include "third_party/WebKit/public/platform/modules/presentation/WebPresentationAvailabilityObserver.h" |
| +#include "third_party/WebKit/public/platform/modules/presentation/WebPresentationClient.h" |
| +#include "third_party/WebKit/public/platform/modules/presentation/WebPresentationError.h" |
| +#include "third_party/WebKit/public/platform/modules/presentation/presentation.mojom.h" |
| + |
| +using ::testing::_; |
| + |
| +namespace content { |
| + |
| +class MockPresentationService : public blink::mojom::PresentationService { |
| + public: |
| + void SetClient(blink::mojom::PresentationServiceClientPtr client) override { |
| + SetClient(*client); |
| + } |
| + MOCK_METHOD1(SetClient, void(const blink::mojom::PresentationServiceClient&)); |
| + MOCK_METHOD1(SetDefaultPresentationUrls, void(const std::vector<GURL>&)); |
| + MOCK_METHOD1(ListenForScreenAvailability, void(const GURL&)); |
| + MOCK_METHOD1(StopListeningForScreenAvailability, void(const GURL&)); |
| + MOCK_METHOD2(StartSession, |
| + void(const std::vector<GURL>&, const StartSessionCallback&)); |
| + MOCK_METHOD3(JoinSession, |
| + void(const std::vector<GURL>&, |
| + const base::Optional<std::string>&, |
| + const JoinSessionCallback&)); |
| + void SendConnectionMessage( |
| + blink::mojom::PresentationSessionInfoPtr sessionInfo, |
| + blink::mojom::ConnectionMessagePtr message_request, |
| + const SendConnectionMessageCallback& callback) override { |
| + SendConnectionMessage(*sessionInfo, *message_request, callback); |
| + } |
| + MOCK_METHOD3(SendConnectionMessage, |
| + void(blink::mojom::PresentationSessionInfo, |
| + blink::mojom::ConnectionMessage, |
| + const SendConnectionMessageCallback&)); |
| + MOCK_METHOD2(CloseConnection, void(const GURL&, const std::string&)); |
| + MOCK_METHOD2(Terminate, void(const GURL&, const std::string&)); |
| + void ListenForConnectionMessages( |
| + blink::mojom::PresentationSessionInfoPtr sessionInfo) override { |
| + ListenForConnectionMessages(*sessionInfo); |
| + } |
| + MOCK_METHOD1(ListenForConnectionMessages, |
| + void(const blink::mojom::PresentationSessionInfo&)); |
| +}; |
| + |
| +class MockPresentationAvailabilityCallbacks final |
| + : public blink::WebCallbacks<bool, const blink::WebPresentationError&> { |
| + public: |
| + MOCK_METHOD1(onSuccess, void(bool value)); |
| + MOCK_METHOD1(onError, void(const blink::WebPresentationError&)); |
| +}; |
| + |
| +class MockPresentationAvailabilityObserver |
| + : public blink::WebPresentationAvailabilityObserver { |
| + public: |
| + MockPresentationAvailabilityObserver( |
| + const blink::WebVector<blink::WebURL>& urls) |
| + : urls_(urls) {} |
| + |
| + MOCK_METHOD1(availabilityChanged, void(bool)); |
| + |
| + const blink::WebVector<blink::WebURL>& urls() const override { return urls_; } |
| + |
| + blink::WebVector<blink::WebURL> urls_; |
| +}; |
| + |
| +class PresentationDispatcherTest : public testing::Test { |
| + public: |
| + enum class URLState { Available, Unavailable, Unsupported, Unknown }; |
| + |
| + PresentationDispatcherTest() { |
| + urls_ = {GURL("http://example0.com/"), GURL("http://example1.com/"), |
| + GURL("http://example2.com/"), GURL("http://example3.com/")}; |
| + |
| + blink::WebVector<blink::WebURL> urls_1(static_cast<size_t>(3)); |
| + urls_1[0] = urls_[0]; |
| + urls_1[1] = urls_[1]; |
| + urls_1[2] = urls_[2]; |
| + |
| + blink::WebVector<blink::WebURL> urls_2(static_cast<size_t>(3)); |
| + urls_2[0] = urls_[1]; |
| + urls_2[1] = urls_[2]; |
| + urls_2[2] = urls_[3]; |
| + |
| + blink::WebVector<blink::WebURL> urls_3(static_cast<size_t>(2)); |
| + urls_3[0] = urls_[1]; |
| + urls_3[1] = urls_[3]; |
| + |
| + urls_set_ = {urls_1, urls_2, urls_3}; |
| + } |
| + |
| + ~PresentationDispatcherTest() override {} |
| + |
| + void SetUp() override { |
| + client_ = base::MakeUnique<PresentationDispatcher>(nullptr); |
| + |
| + blink::mojom::PresentationServicePtr service_ptr; |
| + service_binding_ = new mojo::Binding<blink::mojom::PresentationService>( |
| + &mock_presentation_service_, mojo::MakeRequest(&service_ptr)); |
| + client_->SetPresentationServiceForTest(std::move(service_ptr)); |
| + |
| + for (const auto& urls : urls_set_) { |
| + mock_observers_.push_back( |
| + base::MakeUnique<MockPresentationAvailabilityObserver>(urls)); |
| + } |
| + } |
| + |
| + void ChangeURLState(const GURL& url, URLState state) { |
| + switch (state) { |
| + case URLState::Available: |
| + client_->OnScreenAvailabilityUpdated(url, true); |
| + break; |
| + case URLState::Unavailable: |
| + client_->OnScreenAvailabilityUpdated(url, false); |
| + break; |
| + case URLState::Unsupported: |
| + client_->OnScreenAvailabilityNotSupported(url); |
| + break; |
| + case URLState::Unknown: |
| + break; |
| + } |
| + } |
| + |
| + void StartListening(MockPresentationAvailabilityObserver* observer) { |
| + client_->startListening(observer); |
| + } |
| + |
| + void StopListening(MockPresentationAvailabilityObserver* observer) { |
| + client_->stopListening(observer); |
| + } |
| + |
| + void TestGetAvailabilityKUrls( |
| + std::vector<URLState> states, |
| + MockPresentationAvailabilityCallbacks* mock_callback) { |
| + blink::WebVector<blink::WebURL> urls(states.size()); |
| + |
| + for (size_t i = 0; i < states.size(); i++) { |
| + GURL url("http://example" + std::to_string(i) + ".com/"); |
| + urls[i] = url; |
| + EXPECT_CALL(mock_presentation_service_, ListenForScreenAvailability(url)) |
| + .Times(1); |
| + EXPECT_CALL(mock_presentation_service_, |
| + StopListeningForScreenAvailability(url)) |
| + .Times(1); |
| + } |
| + |
| + base::RunLoop run_loop; |
| + |
| + client_->getAvailability(urls, base::WrapUnique(mock_callback)); |
| + for (size_t i = 0; i < states.size(); i++) |
| + ChangeURLState(urls[i], states[i]); |
| + |
| + for (const auto& url : urls) |
| + client_->StopListening(url); |
| + |
| + run_loop.RunUntilIdle(); |
| + } |
| + |
| + void StartListeningToMultipleRequests() { |
| + for (const auto& url : urls_) { |
| + EXPECT_CALL(mock_presentation_service_, ListenForScreenAvailability(url)) |
| + .Times(1); |
| + } |
| + |
| + base::RunLoop run_loop; |
| + |
| + for (const auto& urls : urls_set_) { |
| + auto* mock_callback = new MockPresentationAvailabilityCallbacks(); |
| + EXPECT_CALL(*mock_callback, onSuccess(false)).Times(1); |
| + client_->getAvailability(urls, base::WrapUnique(mock_callback)); |
| + } |
| + |
| + for (const auto& url : urls_) |
| + ChangeURLState(url, URLState::Unavailable); |
| + |
| + for (const auto& mock_observer : mock_observers_) |
| + StartListening(mock_observer.get()); |
| + |
| + run_loop.RunUntilIdle(); |
| + } |
| + |
| + blink::WebPresentationClient* client() { return client_.get(); } |
| + |
| + std::unique_ptr<PresentationDispatcher> client_; |
| + MockPresentationService mock_presentation_service_; |
| + mojo::Binding<blink::mojom::PresentationService>* service_binding_; |
| + base::MessageLoop message_loop_; |
| + |
| + std::vector<GURL> urls_; |
| + std::vector<blink::WebVector<blink::WebURL>> urls_set_; |
| + std::vector<std::unique_ptr<MockPresentationAvailabilityObserver>> |
| + mock_observers_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(PresentationDispatcherTest); |
| +}; |
| + |
| +TEST_F(PresentationDispatcherTest, GetAvailabilityOneUrlBecomesAvailable) { |
| + auto* mock_callback = new MockPresentationAvailabilityCallbacks(); |
| + EXPECT_CALL(*mock_callback, onSuccess(true)); |
| + std::vector<URLState> states = {URLState::Available}; |
| + TestGetAvailabilityKUrls(states, mock_callback); |
| +} |
| + |
| +TEST_F(PresentationDispatcherTest, GetAvailabilityOneUrlBecomesUnavailable) { |
| + auto* mock_callback = new MockPresentationAvailabilityCallbacks(); |
| + EXPECT_CALL(*mock_callback, onSuccess(false)); |
| + |
| + std::vector<URLState> states = {URLState::Unavailable}; |
| + TestGetAvailabilityKUrls(states, mock_callback); |
| +} |
| + |
| +TEST_F(PresentationDispatcherTest, GetAvailabilityOneUrlBecomesNotSupported) { |
| + auto* mock_callback = new MockPresentationAvailabilityCallbacks(); |
| + EXPECT_CALL(*mock_callback, onError(_)); |
| + |
| + std::vector<URLState> states = {URLState::Unsupported}; |
| + TestGetAvailabilityKUrls(states, mock_callback); |
| +} |
| + |
| +TEST_F(PresentationDispatcherTest, |
| + GetAvailabilityMultipleUrlsAllBecomesAvailable) { |
| + auto* mock_callback = new MockPresentationAvailabilityCallbacks(); |
| + EXPECT_CALL(*mock_callback, onSuccess(true)).Times(1); |
| + |
| + std::vector<URLState> state_seq = {URLState::Available, URLState::Available}; |
| + TestGetAvailabilityKUrls(state_seq, mock_callback); |
| +} |
| + |
| +TEST_F(PresentationDispatcherTest, |
| + GetAvailabilityMultipleUrlsOneBecomesUnavailable) { |
| + auto* mock_callback = new MockPresentationAvailabilityCallbacks(); |
| + EXPECT_CALL(*mock_callback, onSuccess(false)).Times(1); |
| + |
| + std::vector<URLState> state_seq = {URLState::Unavailable, URLState::Unknown}; |
| + TestGetAvailabilityKUrls(state_seq, mock_callback); |
| +} |
| + |
| +TEST_F(PresentationDispatcherTest, |
| + GetAvailabilityMultipleUrlsOneBecomesUnsupported) { |
| + auto* mock_callback = new MockPresentationAvailabilityCallbacks(); |
| + EXPECT_CALL(*mock_callback, onError(_)).Times(1); |
| + |
| + std::vector<URLState> state_seq = {URLState::Unsupported, |
| + URLState::Unavailable, URLState::Unknown}; |
| + TestGetAvailabilityKUrls(state_seq, mock_callback); |
| +} |
| + |
| +TEST_F(PresentationDispatcherTest, |
| + GetAvailabilityMultipleUrlsOneBecomesAvailable) { |
| + auto* mock_callback = new MockPresentationAvailabilityCallbacks(); |
| + EXPECT_CALL(*mock_callback, onSuccess(true)).Times(1); |
| + |
| + std::vector<URLState> state_seq = {URLState::Available, URLState::Unavailable, |
| + URLState::Unknown}; |
| + TestGetAvailabilityKUrls(state_seq, mock_callback); |
| +} |
| + |
| +TEST_F(PresentationDispatcherTest, |
| + GetAvailabilityInvokesOnSuccessForAlreadyListeningUrls) { |
| + // For first getAvailability() call. |
| + blink::WebVector<blink::WebURL> urls_1(static_cast<size_t>(3)); |
| + urls_1[0] = urls_[0]; |
| + urls_1[1] = urls_[1]; |
| + urls_1[2] = urls_[2]; |
| + |
| + for (const auto& url : urls_1) { |
| + EXPECT_CALL(mock_presentation_service_, |
| + ListenForScreenAvailability(static_cast<GURL>(url))) |
| + .Times(1); |
| + } |
| + |
| + auto* mock_callback_1 = new MockPresentationAvailabilityCallbacks(); |
| + EXPECT_CALL(*mock_callback_1, onSuccess(true)).Times(1); |
| + |
| + // For second getAvailability() call. |
| + blink::WebVector<blink::WebURL> urls_2(static_cast<size_t>(2)); |
| + urls_2[0] = urls_[0]; |
| + urls_2[1] = urls_[1]; |
| + |
| + auto* mock_callback_2 = new MockPresentationAvailabilityCallbacks(); |
| + EXPECT_CALL(*mock_callback_2, onSuccess(true)).Times(1); |
| + |
| + base::RunLoop run_loop; |
| + |
| + client()->getAvailability(urls_1, base::WrapUnique(mock_callback_1)); |
| + |
| + ChangeURLState(urls_1[0], URLState::Available); |
| + ChangeURLState(urls_1[1], URLState::Unavailable); |
| + ChangeURLState(urls_1[2], URLState::Available); |
| + |
| + client()->getAvailability(urls_2, base::WrapUnique(mock_callback_2)); |
| + |
| + run_loop.RunUntilIdle(); |
| +} |
| + |
| +TEST_F(PresentationDispatcherTest, |
| + GetAvailabilityInvokesOnErrorForAlreadyListeningUrls) { |
| + // For first getAvailability() call. |
| + blink::WebVector<blink::WebURL> urls_1(static_cast<size_t>(3)); |
| + urls_1[0] = urls_[0]; |
| + urls_1[1] = urls_[1]; |
| + |
| + for (const auto& url : urls_1) { |
| + EXPECT_CALL(mock_presentation_service_, |
| + ListenForScreenAvailability(static_cast<GURL>(url))) |
| + .Times(1); |
| + EXPECT_CALL(mock_presentation_service_, |
| + StopListeningForScreenAvailability(static_cast<GURL>(url))) |
| + .Times(1); |
| + } |
| + |
| + auto* mock_callback_1 = new MockPresentationAvailabilityCallbacks(); |
| + EXPECT_CALL(*mock_callback_1, onError(_)).Times(1); |
| + |
| + // For second getAvailability() call. |
| + blink::WebVector<blink::WebURL> urls_2(static_cast<size_t>(2)); |
| + urls_2[0] = urls_[1]; |
| + urls_2[1] = urls_[3]; |
| + |
| + EXPECT_CALL(mock_presentation_service_, |
| + ListenForScreenAvailability(static_cast<GURL>(urls_[3]))) |
| + .Times(0); |
| + |
| + auto* mock_callback_2 = new MockPresentationAvailabilityCallbacks(); |
| + EXPECT_CALL(*mock_callback_2, onError(_)).Times(1); |
| + |
| + base::RunLoop run_loop; |
| + |
| + client()->getAvailability(urls_1, base::WrapUnique(mock_callback_1)); |
| + |
| + ChangeURLState(urls_1[0], URLState::Unknown); |
| + ChangeURLState(urls_1[1], URLState::Unsupported); |
| + |
| + client()->getAvailability(urls_2, base::WrapUnique(mock_callback_2)); |
| + |
| + run_loop.RunUntilIdle(); |
| +} |
| + |
| +TEST_F(PresentationDispatcherTest, StartListeningListenToEachURLOnce) { |
| + StartListeningToMultipleRequests(); |
| +} |
| + |
| +TEST_F(PresentationDispatcherTest, StopListeningListenToEachURLOnce) { |
| + StartListeningToMultipleRequests(); |
| + |
| + for (const auto& url : urls_) { |
| + EXPECT_CALL(mock_presentation_service_, |
| + StopListeningForScreenAvailability(url)) |
| + .Times(1); |
| + } |
| + |
| + base::RunLoop run_loop; |
| + for (const auto& mock_observer : mock_observers_) |
| + StopListening(mock_observer.get()); |
| + run_loop.RunUntilIdle(); |
| +} |
| + |
| +TEST_F(PresentationDispatcherTest, |
| + StopListeningDoesNotStopIfURLListenedByOthers) { |
| + StartListeningToMultipleRequests(); |
| + |
| + EXPECT_CALL(mock_presentation_service_, |
| + StopListeningForScreenAvailability(urls_[0])) |
| + .Times(1); |
| + |
| + base::RunLoop run_loop; |
| + StopListening(mock_observers_[0].get()); |
| + run_loop.RunUntilIdle(); |
| +} |
| + |
| +TEST_F(PresentationDispatcherTest, |
| + OnScreenAvailabilityUpdatedInvokesAvailabilityChanged) { |
| + StartListeningToMultipleRequests(); |
| + |
| + EXPECT_CALL(*(mock_observers_[0]), availabilityChanged(true)); |
| + |
| + base::RunLoop run_loop; |
| + ChangeURLState(urls_[0], URLState::Available); |
| + run_loop.RunUntilIdle(); |
| +} |
| + |
| +TEST_F(PresentationDispatcherTest, |
| + OnScreenAvailabilityUpdatedInvokesMultipleAvailabilityChanged) { |
| + StartListeningToMultipleRequests(); |
| + |
| + for (const auto& mock_observer : mock_observers_) |
| + EXPECT_CALL(*mock_observer, availabilityChanged(true)); |
| + |
| + base::RunLoop run_loop; |
| + ChangeURLState(urls_[1], URLState::Available); |
| + run_loop.RunUntilIdle(); |
| +} |
| + |
| +} // namespace content |