Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2696)

Unified Diff: content/renderer/presentation/presentation_dispatcher_unittest.cc

Issue 2598063002: [Presentation API] Handle multiple Presentation URLs in PresentationRequest::getAvailability() (Closed)
Patch Set: resolve code review comments from Mark Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698