Add ability to gather metrics to BubbleManager.
[chromium-blink-merge.git] / components / bubble / bubble_manager_unittest.cc
blob23e3e5b7ef7ffbad5559625259b941f4dcf03f74
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 "components/bubble/bubble_manager.h"
7 #include "components/bubble/bubble_controller.h"
8 #include "components/bubble/bubble_delegate.h"
9 #include "components/bubble/bubble_reference.h"
10 #include "components/bubble/bubble_ui.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
14 namespace {
16 class MockBubbleUi : public BubbleUi {
17 public:
18 MockBubbleUi() {}
19 ~MockBubbleUi() override { Destroyed(); }
21 MOCK_METHOD1(Show, void(BubbleReference));
22 MOCK_METHOD0(Close, void());
23 MOCK_METHOD0(UpdateAnchorPosition, void());
25 // To verify destructor call.
26 MOCK_METHOD0(Destroyed, void());
28 private:
29 DISALLOW_COPY_AND_ASSIGN(MockBubbleUi);
32 class MockBubbleDelegate : public BubbleDelegate {
33 public:
34 MockBubbleDelegate() {}
35 ~MockBubbleDelegate() override { Destroyed(); }
37 // Default bubble shows UI and closes when asked to close.
38 static scoped_ptr<MockBubbleDelegate> Default();
40 // Stubborn bubble shows UI and doesn't want to close.
41 static scoped_ptr<MockBubbleDelegate> Stubborn();
43 MOCK_METHOD1(ShouldClose, bool(BubbleCloseReason reason));
45 // A scoped_ptr can't be returned in MOCK_METHOD.
46 MOCK_METHOD0(BuildBubbleUiMock, BubbleUi*());
47 scoped_ptr<BubbleUi> BuildBubbleUi() override {
48 return make_scoped_ptr(BuildBubbleUiMock());
51 MOCK_METHOD1(UpdateBubbleUi, bool(BubbleUi*));
53 MOCK_CONST_METHOD0(GetName, std::string());
55 // To verify destructor call.
56 MOCK_METHOD0(Destroyed, void());
58 private:
59 DISALLOW_COPY_AND_ASSIGN(MockBubbleDelegate);
62 // static
63 scoped_ptr<MockBubbleDelegate> MockBubbleDelegate::Default() {
64 MockBubbleDelegate* delegate = new MockBubbleDelegate;
65 EXPECT_CALL(*delegate, BuildBubbleUiMock())
66 .WillOnce(testing::Return(new MockBubbleUi));
67 EXPECT_CALL(*delegate, ShouldClose(testing::_))
68 .WillOnce(testing::Return(true));
69 return make_scoped_ptr(delegate);
72 // static
73 scoped_ptr<MockBubbleDelegate> MockBubbleDelegate::Stubborn() {
74 MockBubbleDelegate* delegate = new MockBubbleDelegate;
75 EXPECT_CALL(*delegate, BuildBubbleUiMock())
76 .WillOnce(testing::Return(new MockBubbleUi));
77 EXPECT_CALL(*delegate, ShouldClose(testing::_))
78 .WillRepeatedly(testing::Return(false));
79 return make_scoped_ptr(delegate);
82 // Helper class used to test chaining another bubble.
83 class DelegateChainHelper {
84 public:
85 DelegateChainHelper(BubbleManager* manager,
86 scoped_ptr<BubbleDelegate> next_delegate);
88 // Will show the bubble in |next_delegate_|.
89 void Chain() { manager_->ShowBubble(next_delegate_.Pass()); }
91 // True if the bubble was taken by the bubble manager.
92 bool BubbleWasTaken() { return !next_delegate_; }
94 private:
95 BubbleManager* manager_; // Weak.
96 scoped_ptr<BubbleDelegate> next_delegate_;
98 DISALLOW_COPY_AND_ASSIGN(DelegateChainHelper);
101 DelegateChainHelper::DelegateChainHelper(
102 BubbleManager* manager,
103 scoped_ptr<BubbleDelegate> next_delegate)
104 : manager_(manager), next_delegate_(next_delegate.Pass()) {}
106 class MockBubbleManagerObserver : public BubbleManager::BubbleManagerObserver {
107 public:
108 MockBubbleManagerObserver() {}
109 ~MockBubbleManagerObserver() override {}
111 MOCK_METHOD1(OnBubbleNeverShown, void(BubbleReference));
112 MOCK_METHOD2(OnBubbleClosed, void(BubbleReference, BubbleCloseReason));
114 private:
115 DISALLOW_COPY_AND_ASSIGN(MockBubbleManagerObserver);
118 class BubbleManagerTest : public testing::Test {
119 public:
120 BubbleManagerTest();
121 ~BubbleManagerTest() override {}
123 void SetUp() override;
124 void TearDown() override;
126 protected:
127 scoped_ptr<BubbleManager> manager_;
129 private:
130 DISALLOW_COPY_AND_ASSIGN(BubbleManagerTest);
133 BubbleManagerTest::BubbleManagerTest() {}
135 void BubbleManagerTest::SetUp() {
136 testing::Test::SetUp();
137 manager_.reset(new BubbleManager);
140 void BubbleManagerTest::TearDown() {
141 manager_.reset();
142 testing::Test::TearDown();
145 TEST_F(BubbleManagerTest, ManagerShowsBubbleUi) {
146 // Manager will delete bubble_ui.
147 MockBubbleUi* bubble_ui = new MockBubbleUi;
148 EXPECT_CALL(*bubble_ui, Destroyed());
149 EXPECT_CALL(*bubble_ui, Show(testing::_));
150 EXPECT_CALL(*bubble_ui, Close());
151 EXPECT_CALL(*bubble_ui, UpdateAnchorPosition()).Times(0);
153 // Manager will delete delegate.
154 MockBubbleDelegate* delegate = new MockBubbleDelegate;
155 EXPECT_CALL(*delegate, Destroyed());
156 EXPECT_CALL(*delegate, BuildBubbleUiMock())
157 .WillOnce(testing::Return(bubble_ui));
158 EXPECT_CALL(*delegate, ShouldClose(testing::_))
159 .WillOnce(testing::Return(true));
161 manager_->ShowBubble(make_scoped_ptr(delegate));
164 TEST_F(BubbleManagerTest, ManagerUpdatesBubbleUi) {
165 // Manager will delete bubble_ui.
166 MockBubbleUi* bubble_ui = new MockBubbleUi;
167 EXPECT_CALL(*bubble_ui, Destroyed());
168 EXPECT_CALL(*bubble_ui, Show(testing::_));
169 EXPECT_CALL(*bubble_ui, Close());
170 EXPECT_CALL(*bubble_ui, UpdateAnchorPosition());
172 // Manager will delete delegate.
173 MockBubbleDelegate* delegate = new MockBubbleDelegate;
174 EXPECT_CALL(*delegate, Destroyed());
175 EXPECT_CALL(*delegate, BuildBubbleUiMock())
176 .WillOnce(testing::Return(bubble_ui));
177 EXPECT_CALL(*delegate, ShouldClose(testing::_))
178 .WillOnce(testing::Return(true));
180 manager_->ShowBubble(make_scoped_ptr(delegate));
181 manager_->UpdateAllBubbleAnchors();
184 TEST_F(BubbleManagerTest, CloseOnReferenceInvalidatesReference) {
185 BubbleReference ref = manager_->ShowBubble(MockBubbleDelegate::Default());
187 ASSERT_TRUE(ref->CloseBubble(BUBBLE_CLOSE_FOCUS_LOST));
189 ASSERT_FALSE(ref);
192 TEST_F(BubbleManagerTest, CloseOnStubbornReferenceDoesNotInvalidate) {
193 BubbleReference ref = manager_->ShowBubble(MockBubbleDelegate::Stubborn());
195 ASSERT_FALSE(ref->CloseBubble(BUBBLE_CLOSE_FOCUS_LOST));
197 ASSERT_TRUE(ref);
200 TEST_F(BubbleManagerTest, CloseInvalidatesReference) {
201 BubbleReference ref = manager_->ShowBubble(MockBubbleDelegate::Default());
203 ASSERT_TRUE(manager_->CloseBubble(ref, BUBBLE_CLOSE_FOCUS_LOST));
205 ASSERT_FALSE(ref);
208 TEST_F(BubbleManagerTest, CloseAllInvalidatesReference) {
209 BubbleReference ref = manager_->ShowBubble(MockBubbleDelegate::Default());
211 manager_->CloseAllBubbles(BUBBLE_CLOSE_FOCUS_LOST);
213 ASSERT_FALSE(ref);
216 TEST_F(BubbleManagerTest, DestroyInvalidatesReference) {
217 BubbleReference ref = manager_->ShowBubble(MockBubbleDelegate::Default());
219 manager_.reset();
221 ASSERT_FALSE(ref);
224 TEST_F(BubbleManagerTest, CloseInvalidatesStubbornReference) {
225 BubbleReference ref = manager_->ShowBubble(MockBubbleDelegate::Stubborn());
227 ASSERT_TRUE(manager_->CloseBubble(ref, BUBBLE_CLOSE_FORCED));
229 ASSERT_FALSE(ref);
232 TEST_F(BubbleManagerTest, CloseAllInvalidatesStubbornReference) {
233 BubbleReference ref = manager_->ShowBubble(MockBubbleDelegate::Stubborn());
235 manager_->CloseAllBubbles(BUBBLE_CLOSE_FORCED);
237 ASSERT_FALSE(ref);
240 TEST_F(BubbleManagerTest, DestroyInvalidatesStubbornReference) {
241 BubbleReference ref = manager_->ShowBubble(MockBubbleDelegate::Stubborn());
243 manager_.reset();
245 ASSERT_FALSE(ref);
248 TEST_F(BubbleManagerTest, CloseDoesNotInvalidateStubbornReference) {
249 BubbleReference ref = manager_->ShowBubble(MockBubbleDelegate::Stubborn());
251 ASSERT_FALSE(manager_->CloseBubble(ref, BUBBLE_CLOSE_FOCUS_LOST));
253 ASSERT_TRUE(ref);
256 TEST_F(BubbleManagerTest, CloseAllDoesNotInvalidateStubbornReference) {
257 BubbleReference ref = manager_->ShowBubble(MockBubbleDelegate::Stubborn());
259 manager_->CloseAllBubbles(BUBBLE_CLOSE_FOCUS_LOST);
261 ASSERT_TRUE(ref);
264 TEST_F(BubbleManagerTest, CloseAllInvalidatesMixAppropriately) {
265 BubbleReference stubborn_ref1 =
266 manager_->ShowBubble(MockBubbleDelegate::Stubborn());
267 BubbleReference normal_ref1 =
268 manager_->ShowBubble(MockBubbleDelegate::Default());
269 BubbleReference stubborn_ref2 =
270 manager_->ShowBubble(MockBubbleDelegate::Stubborn());
271 BubbleReference normal_ref2 =
272 manager_->ShowBubble(MockBubbleDelegate::Default());
273 BubbleReference stubborn_ref3 =
274 manager_->ShowBubble(MockBubbleDelegate::Stubborn());
275 BubbleReference normal_ref3 =
276 manager_->ShowBubble(MockBubbleDelegate::Default());
278 manager_->CloseAllBubbles(BUBBLE_CLOSE_FOCUS_LOST);
280 ASSERT_TRUE(stubborn_ref1);
281 ASSERT_TRUE(stubborn_ref2);
282 ASSERT_TRUE(stubborn_ref3);
283 ASSERT_FALSE(normal_ref1);
284 ASSERT_FALSE(normal_ref2);
285 ASSERT_FALSE(normal_ref3);
288 TEST_F(BubbleManagerTest, UpdateAllShouldWorkWithoutBubbles) {
289 // Manager shouldn't crash if bubbles have never been added.
290 manager_->UpdateAllBubbleAnchors();
292 // Add a bubble and close it.
293 BubbleReference ref = manager_->ShowBubble(MockBubbleDelegate::Default());
294 ASSERT_TRUE(manager_->CloseBubble(ref, BUBBLE_CLOSE_FORCED));
296 // Bubble should NOT get an update event because it's already closed.
297 manager_->UpdateAllBubbleAnchors();
300 TEST_F(BubbleManagerTest, CloseAllShouldWorkWithoutBubbles) {
301 // Manager shouldn't crash if bubbles have never been added.
302 manager_->CloseAllBubbles(BUBBLE_CLOSE_FOCUS_LOST);
304 // Add a bubble and close it.
305 BubbleReference ref = manager_->ShowBubble(MockBubbleDelegate::Default());
306 ASSERT_TRUE(manager_->CloseBubble(ref, BUBBLE_CLOSE_FORCED));
308 // Bubble should NOT get a close event because it's already closed.
309 manager_->CloseAllBubbles(BUBBLE_CLOSE_FOCUS_LOST);
312 TEST_F(BubbleManagerTest, AllowBubbleChainingOnClose) {
313 scoped_ptr<BubbleDelegate> chained_delegate = MockBubbleDelegate::Default();
314 DelegateChainHelper chain_helper(manager_.get(), chained_delegate.Pass());
316 // Manager will delete delegate.
317 MockBubbleDelegate* delegate = new MockBubbleDelegate;
318 EXPECT_CALL(*delegate, BuildBubbleUiMock())
319 .WillOnce(testing::Return(new MockBubbleUi));
320 EXPECT_CALL(*delegate, ShouldClose(testing::_))
321 .WillOnce(testing::DoAll(testing::InvokeWithoutArgs(
322 &chain_helper, &DelegateChainHelper::Chain),
323 testing::Return(true)));
325 BubbleReference ref = manager_->ShowBubble(make_scoped_ptr(delegate));
326 ASSERT_TRUE(manager_->CloseBubble(ref, BUBBLE_CLOSE_FORCED));
328 ASSERT_TRUE(chain_helper.BubbleWasTaken());
331 TEST_F(BubbleManagerTest, AllowBubbleChainingOnCloseAll) {
332 scoped_ptr<BubbleDelegate> chained_delegate = MockBubbleDelegate::Default();
333 DelegateChainHelper chain_helper(manager_.get(), chained_delegate.Pass());
335 // Manager will delete delegate.
336 MockBubbleDelegate* delegate = new MockBubbleDelegate;
337 EXPECT_CALL(*delegate, BuildBubbleUiMock())
338 .WillOnce(testing::Return(new MockBubbleUi));
339 EXPECT_CALL(*delegate, ShouldClose(testing::_))
340 .WillOnce(testing::DoAll(testing::InvokeWithoutArgs(
341 &chain_helper, &DelegateChainHelper::Chain),
342 testing::Return(true)));
344 manager_->ShowBubble(make_scoped_ptr(delegate));
345 manager_->CloseAllBubbles(BUBBLE_CLOSE_FORCED);
347 ASSERT_TRUE(chain_helper.BubbleWasTaken());
350 TEST_F(BubbleManagerTest, BubblesDoNotChainOnDestroy) {
351 // Manager will delete delegate.
352 MockBubbleDelegate* chained_delegate = new MockBubbleDelegate;
353 EXPECT_CALL(*chained_delegate, BuildBubbleUiMock()).Times(0);
354 EXPECT_CALL(*chained_delegate, ShouldClose(testing::_)).Times(0);
356 DelegateChainHelper chain_helper(manager_.get(),
357 make_scoped_ptr(chained_delegate));
359 // Manager will delete delegate.
360 MockBubbleDelegate* delegate = new MockBubbleDelegate;
361 EXPECT_CALL(*delegate, BuildBubbleUiMock())
362 .WillOnce(testing::Return(new MockBubbleUi));
363 EXPECT_CALL(*delegate, ShouldClose(testing::_))
364 .WillOnce(testing::DoAll(testing::InvokeWithoutArgs(
365 &chain_helper, &DelegateChainHelper::Chain),
366 testing::Return(true)));
368 manager_->ShowBubble(make_scoped_ptr(delegate));
369 manager_.reset();
371 // The manager will take the bubble, but not show it.
372 ASSERT_TRUE(chain_helper.BubbleWasTaken());
375 TEST_F(BubbleManagerTest, BubbleUpdatesTrue) {
376 MockBubbleUi* bubble_ui = new MockBubbleUi;
377 MockBubbleDelegate* delegate = new MockBubbleDelegate;
378 EXPECT_CALL(*delegate, BuildBubbleUiMock())
379 .WillOnce(testing::Return(bubble_ui));
380 EXPECT_CALL(*delegate, ShouldClose(testing::_))
381 .WillOnce(testing::Return(true));
382 EXPECT_CALL(*delegate, UpdateBubbleUi(bubble_ui))
383 .WillOnce(testing::Return(true));
385 BubbleReference ref = manager_->ShowBubble(make_scoped_ptr(delegate));
386 ASSERT_TRUE(ref->UpdateBubbleUi());
389 TEST_F(BubbleManagerTest, BubbleUpdatesFalse) {
390 MockBubbleUi* bubble_ui = new MockBubbleUi;
391 MockBubbleDelegate* delegate = new MockBubbleDelegate;
392 EXPECT_CALL(*delegate, BuildBubbleUiMock())
393 .WillOnce(testing::Return(bubble_ui));
394 EXPECT_CALL(*delegate, ShouldClose(testing::_))
395 .WillOnce(testing::Return(true));
396 EXPECT_CALL(*delegate, UpdateBubbleUi(bubble_ui))
397 .WillOnce(testing::Return(false));
399 BubbleReference ref = manager_->ShowBubble(make_scoped_ptr(delegate));
400 ASSERT_FALSE(ref->UpdateBubbleUi());
403 TEST_F(BubbleManagerTest, BubbleCloseReasonIsCalled) {
404 MockBubbleManagerObserver metrics;
405 EXPECT_CALL(metrics, OnBubbleNeverShown(testing::_)).Times(0);
406 EXPECT_CALL(metrics, OnBubbleClosed(testing::_, BUBBLE_CLOSE_ACCEPTED));
407 manager_->AddBubbleManagerObserver(&metrics);
409 BubbleReference ref = manager_->ShowBubble(MockBubbleDelegate::Default());
410 ref->CloseBubble(BUBBLE_CLOSE_ACCEPTED);
412 // Destroy to verify no events are sent to |metrics| in destructor.
413 manager_.reset();
416 TEST_F(BubbleManagerTest, BubbleCloseNeverShownIsCalled) {
417 MockBubbleManagerObserver metrics;
418 // |chained_delegate| should never be shown.
419 EXPECT_CALL(metrics, OnBubbleNeverShown(testing::_));
420 // |delegate| should be forced to close when the manager is destroyed.
421 EXPECT_CALL(metrics, OnBubbleClosed(testing::_, BUBBLE_CLOSE_FORCED));
422 manager_->AddBubbleManagerObserver(&metrics);
424 // Manager will delete delegate.
425 MockBubbleDelegate* chained_delegate = new MockBubbleDelegate;
426 EXPECT_CALL(*chained_delegate, BuildBubbleUiMock()).Times(0);
427 EXPECT_CALL(*chained_delegate, ShouldClose(testing::_)).Times(0);
429 DelegateChainHelper chain_helper(manager_.get(),
430 make_scoped_ptr(chained_delegate));
432 // Manager will delete delegate.
433 MockBubbleDelegate* delegate = new MockBubbleDelegate;
434 EXPECT_CALL(*delegate, BuildBubbleUiMock())
435 .WillOnce(testing::Return(new MockBubbleUi));
436 EXPECT_CALL(*delegate, ShouldClose(testing::_))
437 .WillOnce(testing::DoAll(testing::InvokeWithoutArgs(
438 &chain_helper, &DelegateChainHelper::Chain),
439 testing::Return(true)));
441 manager_->ShowBubble(make_scoped_ptr(delegate));
442 manager_.reset();
444 // The manager will take the bubble, but not show it.
445 ASSERT_TRUE(chain_helper.BubbleWasTaken());
448 } // namespace