| Index: chrome/browser/media/router/media_router_mojo_impl_unittest.cc
|
| diff --git a/chrome/browser/media/router/media_router_mojo_impl_unittest.cc b/chrome/browser/media/router/media_router_mojo_impl_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..620c7eb705f4681e9a5cd582e2d33bd4936d6b11
|
| --- /dev/null
|
| +++ b/chrome/browser/media/router/media_router_mojo_impl_unittest.cc
|
| @@ -0,0 +1,256 @@
|
| +// Copyright 2015 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include <string>
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/bind_helpers.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| +#include "base/run_loop.h"
|
| +#include "base/synchronization/waitable_event.h"
|
| +#include "chrome/browser/media/router/media_route.h"
|
| +#include "chrome/browser/media/router/media_router_mojo_test.h"
|
| +#include "chrome/browser/media/router/mock_media_router.h"
|
| +#include "chrome/browser/media/router/test_helper.h"
|
| +#include "chrome/test/base/chrome_render_view_host_test_harness.h"
|
| +#include "chrome/test/base/testing_profile.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +using testing::_;
|
| +using testing::Eq;
|
| +using testing::Invoke;
|
| +using testing::Pointee;
|
| +using testing::Return;
|
| +using testing::ReturnRef;
|
| +using testing::SaveArg;
|
| +
|
| +const char kDescription[] = "description";
|
| +const char kError[] = "error";
|
| +const char kMessage[] = "message";
|
| +const char kSource[] = "source1";
|
| +const char kSource2[] = "source2";
|
| +const char kRouteId[] = "routeId";
|
| +const char kRouteId2[] = "routeId2";
|
| +const char kSink[] = "sink";
|
| +const char kSink2[] = "sink2";
|
| +const char kSinkName[] = "sinkName";
|
| +
|
| +namespace media_router {
|
| +
|
| +// Adapts Invoke(), which takes a move-only scoped_ptr parameter (not mockable)
|
| +// to a variant that accepts raw pointers instead (mock friendly).
|
| +class RouteResponseCallbackHandler {
|
| + public:
|
| + void Invoke(scoped_ptr<MediaRoute> route, const std::string& error_text) {
|
| + InvokeObserver(route.get(), error_text);
|
| + }
|
| +
|
| + MOCK_METHOD2(InvokeObserver,
|
| + void(MediaRoute* route, const std::string& error_text));
|
| +};
|
| +
|
| +template <typename T>
|
| +void StoreAndRun(T* result, const base::Closure& closure, const T& result_val) {
|
| + *result = result_val;
|
| + closure.Run();
|
| +}
|
| +
|
| +class MediaRouterMojoImplTest : public MediaRouterMojoTest {
|
| + public:
|
| + MediaRouterMojoImplTest() {}
|
| + ~MediaRouterMojoImplTest() override {}
|
| +};
|
| +
|
| +TEST_F(MediaRouterMojoImplTest, CreateRoute) {
|
| + MediaRoute expected_route(kRouteId, MediaSource(std::string(kSource)),
|
| + MediaSink(kSink, kSinkName), "", false);
|
| + interfaces::MediaRoutePtr route = interfaces::MediaRoute::New();
|
| + route->media_source = kSource;
|
| + route->media_sink = interfaces::MediaSink::New();
|
| + route->media_sink->sink_id = kSink;
|
| + route->media_sink->name = kSinkName;
|
| + route->media_route_id = kRouteId;
|
| + route->description = kDescription;
|
| +
|
| + // Use a lambda function as an invocation target here to work around
|
| + // a limitation with GMock::Invoke that prevents it from using move-only types
|
| + // in runnable parameter lists.
|
| + EXPECT_CALL(mock_mrpm_host_,
|
| + CreateRoute(mojo::String(kSource), mojo::String(kSink), _))
|
| + .WillOnce(Invoke(
|
| + [&route](const mojo::String& source, const mojo::String& sink,
|
| + const interfaces::MediaRouter::CreateRouteCallback& cb) {
|
| + cb.Run(route.Pass(), mojo::String());
|
| + }));
|
| +
|
| + RouteResponseCallbackHandler handler;
|
| + EXPECT_CALL(handler, InvokeObserver(Pointee(Equals(expected_route)), ""));
|
| + observer_impl_->CreateRoute(kSource, kSink,
|
| + base::Bind(&RouteResponseCallbackHandler::Invoke,
|
| + base::Unretained(&handler)));
|
| + ProcessEventLoop();
|
| +}
|
| +
|
| +TEST_F(MediaRouterMojoImplTest, CreateRouteFails) {
|
| + EXPECT_CALL(mock_mrpm_host_,
|
| + CreateRoute(mojo::String(kSource), mojo::String(kSink), _))
|
| + .WillOnce(
|
| + Invoke([](const mojo::String& source, const mojo::String& sink,
|
| + const interfaces::MediaRouter::CreateRouteCallback& cb) {
|
| + cb.Run(interfaces::MediaRoutePtr(), mojo::String(kError));
|
| + }));
|
| +
|
| + RouteResponseCallbackHandler handler;
|
| + EXPECT_CALL(handler, InvokeObserver(nullptr, kError));
|
| + observer_impl_->CreateRoute(kSource, kSink,
|
| + base::Bind(&RouteResponseCallbackHandler::Invoke,
|
| + base::Unretained(&handler)));
|
| + ProcessEventLoop();
|
| +}
|
| +
|
| +TEST_F(MediaRouterMojoImplTest, CloseRoute) {
|
| + EXPECT_CALL(mock_mrpm_host_, CloseRoute(mojo::String(kRouteId)));
|
| + observer_impl_->CloseRoute(kRouteId);
|
| + ProcessEventLoop();
|
| +}
|
| +
|
| +TEST_F(MediaRouterMojoImplTest, RegisterAndUnregisterMediaSinksObserver) {
|
| + MediaSource media_source(kSource);
|
| +
|
| + MockMediaRouter mock_router;
|
| + EXPECT_CALL(mock_mrpm_host_, StartObservingMediaSinks(mojo::String(kSource)));
|
| + EXPECT_CALL(mock_mrpm_host_,
|
| + StartObservingMediaSinks(mojo::String(kSource2)));
|
| +
|
| + MediaSinksObserver* captured_observer;
|
| + EXPECT_CALL(mock_router, RegisterMediaSinksObserver(_))
|
| + .Times(3)
|
| + .WillRepeatedly(DoAll(SaveArg<0>(&captured_observer), Return(true)));
|
| +
|
| + MockMediaSinksObserver sinks_observer(&mock_router, media_source);
|
| + EXPECT_EQ(&sinks_observer, captured_observer);
|
| + observer_impl_->RegisterMediaSinksObserver(&sinks_observer);
|
| + MockMediaSinksObserver extra_sinks_observer(&mock_router, media_source);
|
| + EXPECT_EQ(&extra_sinks_observer, captured_observer);
|
| + observer_impl_->RegisterMediaSinksObserver(&extra_sinks_observer);
|
| + MockMediaSinksObserver unrelated_sinks_observer(&mock_router,
|
| + MediaSource(kSource2));
|
| + EXPECT_EQ(&unrelated_sinks_observer, captured_observer);
|
| + observer_impl_->RegisterMediaSinksObserver(&unrelated_sinks_observer);
|
| +
|
| + std::vector<MediaSink> expected_sinks;
|
| + expected_sinks.push_back(MediaSink(kSink, kSinkName));
|
| + expected_sinks.push_back(MediaSink(kSink2, kSinkName));
|
| +
|
| + mojo::Array<interfaces::MediaSinkPtr> mojo_sinks(2);
|
| + mojo_sinks[0] = interfaces::MediaSink::New();
|
| + mojo_sinks[0]->sink_id = kSink;
|
| + mojo_sinks[0]->name = kSink;
|
| + mojo_sinks[1] = interfaces::MediaSink::New();
|
| + mojo_sinks[1]->sink_id = kSink2;
|
| + mojo_sinks[1]->name = kSink2;
|
| +
|
| + EXPECT_CALL(sinks_observer, OnSinksReceived(SequenceEquals(expected_sinks)));
|
| + EXPECT_CALL(extra_sinks_observer,
|
| + OnSinksReceived(SequenceEquals(expected_sinks)));
|
| + observer_proxy_->OnSinksReceived(media_source.id(), mojo_sinks.Pass());
|
| + ProcessEventLoop();
|
| +
|
| + EXPECT_CALL(mock_router, UnregisterMediaSinksObserver(&sinks_observer));
|
| + EXPECT_CALL(mock_router, UnregisterMediaSinksObserver(&extra_sinks_observer));
|
| + EXPECT_CALL(mock_router,
|
| + UnregisterMediaSinksObserver(&unrelated_sinks_observer));
|
| + EXPECT_CALL(mock_mrpm_host_, StopObservingMediaSinks(mojo::String(kSource)));
|
| + EXPECT_CALL(mock_mrpm_host_, StopObservingMediaSinks(mojo::String(kSource2)));
|
| + observer_impl_->UnregisterMediaSinksObserver(&sinks_observer);
|
| + observer_impl_->UnregisterMediaSinksObserver(&extra_sinks_observer);
|
| + observer_impl_->UnregisterMediaSinksObserver(&unrelated_sinks_observer);
|
| + ProcessEventLoop();
|
| +}
|
| +
|
| +TEST_F(MediaRouterMojoImplTest, RegisterAndUnregisterMediaRoutesObserver) {
|
| + MockMediaRouter mock_router;
|
| + EXPECT_CALL(mock_mrpm_host_, StartObservingMediaRoutes());
|
| +
|
| + MediaRoutesObserver* observer_captured;
|
| + EXPECT_CALL(mock_router, RegisterMediaRoutesObserver(_))
|
| + .Times(2)
|
| + .WillRepeatedly(DoAll(SaveArg<0>(&observer_captured), Return(true)));
|
| + MockMediaRoutesObserver routes_observer(&mock_router);
|
| + EXPECT_EQ(observer_captured, &routes_observer);
|
| + MockMediaRoutesObserver extra_routes_observer(&mock_router);
|
| + EXPECT_EQ(observer_captured, &extra_routes_observer);
|
| + observer_impl_->RegisterMediaRoutesObserver(&routes_observer);
|
| + observer_impl_->RegisterMediaRoutesObserver(&extra_routes_observer);
|
| +
|
| + std::vector<MediaRoute> expected_routes;
|
| + expected_routes.push_back(MediaRoute(kRouteId, MediaSource(kSource),
|
| + MediaSink(kSink, kSink), kDescription,
|
| + false));
|
| + expected_routes.push_back(MediaRoute(kRouteId2, MediaSource(kSource),
|
| + MediaSink(kSink, kSink), kDescription,
|
| + false));
|
| +
|
| + mojo::Array<interfaces::MediaRoutePtr> mojo_routes(2);
|
| + mojo_routes[0] = interfaces::MediaRoute::New();
|
| + mojo_routes[0]->media_route_id = kRouteId;
|
| + mojo_routes[0]->media_source = kSource;
|
| + mojo_routes[0]->media_sink = interfaces::MediaSink::New();
|
| + mojo_routes[0]->media_sink->sink_id = kSink;
|
| + mojo_routes[0]->media_sink->name = kSink;
|
| + mojo_routes[0]->description = kDescription;
|
| + mojo_routes[0]->is_local = false;
|
| + mojo_routes[1] = interfaces::MediaRoute::New();
|
| + mojo_routes[1]->media_route_id = kRouteId2;
|
| + mojo_routes[1]->media_source = kSource;
|
| + mojo_routes[1]->media_sink = interfaces::MediaSink::New();
|
| + mojo_routes[1]->media_sink->sink_id = kSink;
|
| + mojo_routes[1]->media_sink->name = kSink;
|
| + mojo_routes[1]->description = kDescription;
|
| + mojo_routes[1]->is_local = false;
|
| +
|
| + EXPECT_CALL(routes_observer,
|
| + OnRoutesUpdated(SequenceEquals(expected_routes)));
|
| + EXPECT_CALL(extra_routes_observer,
|
| + OnRoutesUpdated(SequenceEquals(expected_routes)));
|
| + observer_proxy_->OnRoutesUpdated(mojo_routes.Pass());
|
| + ProcessEventLoop();
|
| +
|
| + EXPECT_CALL(mock_router, UnregisterMediaRoutesObserver(&routes_observer));
|
| + EXPECT_CALL(mock_router,
|
| + UnregisterMediaRoutesObserver(&extra_routes_observer));
|
| + observer_impl_->UnregisterMediaRoutesObserver(&routes_observer);
|
| + observer_impl_->UnregisterMediaRoutesObserver(&extra_routes_observer);
|
| + EXPECT_CALL(mock_mrpm_host_, StopObservingMediaRoutes());
|
| + ProcessEventLoop();
|
| +}
|
| +
|
| +TEST_F(MediaRouterMojoImplTest, PostMessage) {
|
| + EXPECT_CALL(mock_mrpm_host_,
|
| + PostMessage(mojo::String(kRouteId), mojo::String(kMessage)));
|
| + observer_impl_->PostMessage(kRouteId, kMessage);
|
| + ProcessEventLoop();
|
| +}
|
| +
|
| +TEST_F(MediaRouterMojoImplTest, QueuedWhileAsleep) {
|
| + EXPECT_CALL(mock_event_page_tracker_, IsEventPageSuspended(extension_id_))
|
| + .Times(2)
|
| + .WillRepeatedly(Return(true));
|
| + EXPECT_CALL(mock_event_page_tracker_, WakeEventPage(extension_id_, _))
|
| + .Times(2)
|
| + .WillRepeatedly(Return(true));
|
| + observer_impl_->CloseRoute(kRouteId);
|
| + observer_impl_->CloseRoute(kRouteId2);
|
| + ProcessEventLoop();
|
| + EXPECT_CALL(mock_event_page_tracker_, IsEventPageSuspended(extension_id_))
|
| + .Times(1)
|
| + .WillRepeatedly(Return(false));
|
| + EXPECT_CALL(mock_mrpm_host_, CloseRoute(mojo::String(kRouteId)));
|
| + EXPECT_CALL(mock_mrpm_host_, CloseRoute(mojo::String(kRouteId2)));
|
| + ConnectProviderManagerService();
|
| + ProcessEventLoop();
|
| +}
|
| +
|
| +} // namespace media_router
|
|
|