ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / content / browser / presentation / presentation_service_impl_unittest.cc
blob89a6b3c779aa02419bb6b210c2d8f33c1e779ae4
1 // Copyright 2015 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.
5 #include "base/memory/scoped_ptr.h"
6 #include "base/message_loop/message_loop.h"
7 #include "base/run_loop.h"
8 #include "content/browser/presentation/presentation_service_impl.h"
9 #include "content/public/browser/presentation_service_delegate.h"
10 #include "content/test/test_render_frame_host.h"
11 #include "content/test/test_render_view_host.h"
12 #include "content/test/test_web_contents.h"
13 #include "mojo/public/cpp/bindings/interface_ptr.h"
14 #include "testing/gmock/include/gmock/gmock.h"
16 using ::testing::_;
17 using ::testing::Eq;
18 using ::testing::InvokeWithoutArgs;
19 using ::testing::Mock;
20 using ::testing::Return;
22 namespace content {
24 class MockPresentationServiceDelegate : public PresentationServiceDelegate {
25 public:
26 MOCK_METHOD1(AddObserver,
27 void(PresentationServiceDelegate::Observer* observer));
28 MOCK_METHOD1(RemoveObserver,
29 void(PresentationServiceDelegate::Observer* observer));
30 MOCK_METHOD3(AddScreenAvailabilityListener,
31 bool(
32 int render_process_id,
33 int routing_id,
34 PresentationScreenAvailabilityListener* listener));
35 MOCK_METHOD3(RemoveScreenAvailabilityListener,
36 void(
37 int render_process_id,
38 int routing_id,
39 PresentationScreenAvailabilityListener* listener));
40 MOCK_METHOD2(RemoveAllScreenAvailabilityListeners,
41 void(
42 int render_process_id,
43 int routing_id));
46 class PresentationServiceImplTest : public RenderViewHostImplTestHarness {
47 public:
48 PresentationServiceImplTest() : callback_count_(0) {}
50 void SetUp() override {
51 RenderViewHostImplTestHarness::SetUp();
53 EXPECT_CALL(mock_delegate_, AddObserver(_)).Times(1);
54 service_impl_.reset(mojo::WeakBindToProxy(
55 new PresentationServiceImpl(
56 contents()->GetMainFrame(), contents(), &mock_delegate_),
57 &service_ptr_));
60 void TearDown() override {
61 service_ptr_.reset();
63 EXPECT_CALL(mock_delegate_, RemoveObserver(Eq(service_impl_.get())))
64 .Times(1);
65 service_impl_.reset();
67 RenderViewHostImplTestHarness::TearDown();
70 void GetScreenAvailabilityAndWait(
71 const std::string& presentation_url,
72 const base::Callback<void(bool)>& callback,
73 bool delegate_success) {
74 VLOG(1) << "GetScreenAvailabilityAndWait for " << presentation_url;
75 base::RunLoop run_loop;
76 // This will call to |service_impl_| via mojo. Process the message
77 // using RunLoop.
78 // The callback shouldn't be invoked since there is no availability
79 // result yet.
80 EXPECT_CALL(mock_delegate_, AddScreenAvailabilityListener(_, _, _))
81 .WillOnce(DoAll(
82 InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit),
83 Return(delegate_success)));
84 service_ptr_->GetScreenAvailability(presentation_url, callback);
85 run_loop.Run();
87 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&mock_delegate_));
90 void ExpectListenerDoesNotExist(const std::string& presentation_url) {
91 const auto& contexts = service_impl_->availability_contexts_;
92 auto it = contexts.find(presentation_url);
93 EXPECT_TRUE(it == contexts.end());
96 void RunLoopFor(base::TimeDelta duration) {
97 base::RunLoop run_loop;
98 base::MessageLoop::current()->PostDelayedTask(
99 FROM_HERE, run_loop.QuitClosure(), duration);
100 run_loop.Run();
103 void SaveQuitClosureAndRunLoop() {
104 base::RunLoop run_loop;
105 run_loop_quit_closure_ = run_loop.QuitClosure();
106 run_loop.Run();
107 run_loop_quit_closure_.Reset();
110 void ShouldNotBeCalled(bool available) {
111 FAIL() << "Callback unexpectedly invoked with available = " << available;
114 void SimulateScreenAvailabilityChange(
115 const std::string& presentation_url, bool available) {
116 const auto& contexts = service_impl_->availability_contexts_;
117 auto it = contexts.find(presentation_url);
118 ASSERT_TRUE(it != contexts.end());
119 it->second->OnScreenAvailabilityChanged(available);
122 void ScreenAvailabilityChangedCallback(bool expected, bool available) {
123 ++callback_count_;
124 EXPECT_EQ(expected, available);
125 if (!run_loop_quit_closure_.is_null())
126 run_loop_quit_closure_.Run();
129 MockPresentationServiceDelegate mock_delegate_;
130 scoped_ptr<PresentationServiceImpl> service_impl_;
131 mojo::InterfacePtr<presentation::PresentationService> service_ptr_;
132 base::Closure run_loop_quit_closure_;
133 int callback_count_;
136 TEST_F(PresentationServiceImplTest, GetScreenAvailability) {
137 std::string presentation_url("http://fooUrl");
138 GetScreenAvailabilityAndWait(
139 presentation_url,
140 base::Bind(
141 &PresentationServiceImplTest::ScreenAvailabilityChangedCallback,
142 base::Unretained(this), true),
143 true);
145 // Different presentation URL.
146 GetScreenAvailabilityAndWait(
147 "http://barUrl",
148 base::Bind(&PresentationServiceImplTest::ShouldNotBeCalled,
149 base::Unretained(this)),
150 true);
152 // Result now available; callback will be invoked with availability result.
153 SimulateScreenAvailabilityChange(presentation_url, true);
154 SaveQuitClosureAndRunLoop();
156 EXPECT_EQ(1, callback_count_);
158 // Result updated but callback not invoked since it's been erased.
159 SimulateScreenAvailabilityChange(presentation_url, false);
161 // Register another callback which should immediately invoke callback
162 // since updated result is available.
163 service_ptr_->GetScreenAvailability(
164 presentation_url,
165 base::Bind(
166 &PresentationServiceImplTest::ScreenAvailabilityChangedCallback,
167 base::Unretained(this),
168 false));
169 SaveQuitClosureAndRunLoop();
170 EXPECT_EQ(2, callback_count_);
173 TEST_F(PresentationServiceImplTest, RemoveAllListeners) {
174 std::string presentation_url("http://fooUrl");
175 GetScreenAvailabilityAndWait(
176 presentation_url,
177 base::Bind(&PresentationServiceImplTest::ShouldNotBeCalled,
178 base::Unretained(this)),
179 true);
181 service_impl_->RemoveAllListeners();
183 ExpectListenerDoesNotExist(presentation_url);
185 EXPECT_EQ(0, callback_count_);
188 TEST_F(PresentationServiceImplTest, DidNavigateThisFrame) {
189 std::string presentation_url("http://fooUrl");
190 GetScreenAvailabilityAndWait(
191 presentation_url,
192 base::Bind(&PresentationServiceImplTest::ShouldNotBeCalled,
193 base::Unretained(this)),
194 true);
196 service_impl_->DidNavigateAnyFrame(
197 contents()->GetMainFrame(),
198 content::LoadCommittedDetails(),
199 content::FrameNavigateParams());
201 ExpectListenerDoesNotExist(presentation_url);
204 TEST_F(PresentationServiceImplTest, DidNavigateNotThisFrame) {
205 std::string presentation_url("http://fooUrl");
206 GetScreenAvailabilityAndWait(
207 presentation_url,
208 base::Bind(
209 &PresentationServiceImplTest::ScreenAvailabilityChangedCallback,
210 base::Unretained(this),
211 true),
212 true);
214 // TODO(imcheng): How to get a different RenderFrameHost?
215 service_impl_->DidNavigateAnyFrame(
216 nullptr,
217 content::LoadCommittedDetails(),
218 content::FrameNavigateParams());
220 // Availability is reported and callback is invoked since it was not
221 // removed.
222 SimulateScreenAvailabilityChange(presentation_url, true);
223 SaveQuitClosureAndRunLoop();
224 EXPECT_EQ(1, callback_count_);
227 TEST_F(PresentationServiceImplTest, ThisRenderFrameDeleted) {
228 std::string presentation_url("http://fooUrl");
229 GetScreenAvailabilityAndWait(
230 presentation_url,
231 base::Bind(&PresentationServiceImplTest::ShouldNotBeCalled,
232 base::Unretained(this)),
233 true);
235 service_impl_->RenderFrameDeleted(contents()->GetMainFrame());
237 ExpectListenerDoesNotExist(presentation_url);
240 TEST_F(PresentationServiceImplTest, NotThisRenderFrameDeleted) {
241 std::string presentation_url("http://fooUrl");
242 GetScreenAvailabilityAndWait(
243 presentation_url,
244 base::Bind(
245 &PresentationServiceImplTest::ScreenAvailabilityChangedCallback,
246 base::Unretained(this),
247 true),
248 true);
250 // TODO(imcheng): How to get a different RenderFrameHost?
251 service_impl_->RenderFrameDeleted(nullptr);
253 // Availability is reported and callback should be invoked since listener
254 // has not been deleted.
255 SimulateScreenAvailabilityChange(presentation_url, true);
256 SaveQuitClosureAndRunLoop();
257 EXPECT_EQ(1, callback_count_);
260 TEST_F(PresentationServiceImplTest, GetScreenAvailabilityTwice) {
261 std::string presentation_url("http://fooUrl");
262 GetScreenAvailabilityAndWait(
263 presentation_url,
264 base::Bind(&PresentationServiceImplTest::ShouldNotBeCalled,
265 base::Unretained(this)),
266 true);
268 // Second call should overwrite the callback from first call.
269 // It shouldn't result in an extra call to delegate.
270 service_ptr_->GetScreenAvailability(
271 presentation_url,
272 base::Bind(
273 &PresentationServiceImplTest::ScreenAvailabilityChangedCallback,
274 base::Unretained(this),
275 false));
277 // Cannot use GetScreenAvailabilityAndWait here since the mock delegate
278 // won't be triggered again to quit the RunLoop.
279 RunLoopFor(base::TimeDelta::FromMilliseconds(50));
281 // Result now available; callback will be invoked with availability result.
282 SimulateScreenAvailabilityChange(presentation_url, false);
283 SaveQuitClosureAndRunLoop();
285 EXPECT_EQ(1, callback_count_);
288 TEST_F(PresentationServiceImplTest, DelegateFails) {
289 std::string presentation_url("http://fooUrl");
290 GetScreenAvailabilityAndWait(
291 presentation_url,
292 base::Bind(&PresentationServiceImplTest::ShouldNotBeCalled,
293 base::Unretained(this)),
294 false);
296 ExpectListenerDoesNotExist(presentation_url);
299 } // namespace content