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_manager_mocks.h"
9 #include "testing/gtest/include/gtest/gtest.h"
13 // Helper class used to test chaining another bubble.
14 class DelegateChainHelper
{
16 DelegateChainHelper(BubbleManager
* manager
,
17 scoped_ptr
<BubbleDelegate
> next_delegate
);
19 // Will show the bubble in |next_delegate_|.
20 void Chain() { manager_
->ShowBubble(next_delegate_
.Pass()); }
22 // True if the bubble was taken by the bubble manager.
23 bool BubbleWasTaken() { return !next_delegate_
; }
26 BubbleManager
* manager_
; // Weak.
27 scoped_ptr
<BubbleDelegate
> next_delegate_
;
29 DISALLOW_COPY_AND_ASSIGN(DelegateChainHelper
);
32 DelegateChainHelper::DelegateChainHelper(
33 BubbleManager
* manager
,
34 scoped_ptr
<BubbleDelegate
> next_delegate
)
35 : manager_(manager
), next_delegate_(next_delegate
.Pass()) {}
37 class MockBubbleManagerObserver
: public BubbleManager::BubbleManagerObserver
{
39 MockBubbleManagerObserver() {}
40 ~MockBubbleManagerObserver() override
{}
42 MOCK_METHOD1(OnBubbleNeverShown
, void(BubbleReference
));
43 MOCK_METHOD2(OnBubbleClosed
, void(BubbleReference
, BubbleCloseReason
));
46 DISALLOW_COPY_AND_ASSIGN(MockBubbleManagerObserver
);
49 class BubbleManagerTest
: public testing::Test
{
52 ~BubbleManagerTest() override
{}
54 void SetUp() override
;
55 void TearDown() override
;
58 scoped_ptr
<BubbleManager
> manager_
;
61 DISALLOW_COPY_AND_ASSIGN(BubbleManagerTest
);
64 BubbleManagerTest::BubbleManagerTest() {}
66 void BubbleManagerTest::SetUp() {
67 testing::Test::SetUp();
68 manager_
.reset(new BubbleManager
);
71 void BubbleManagerTest::TearDown() {
73 testing::Test::TearDown();
76 TEST_F(BubbleManagerTest
, ManagerShowsBubbleUi
) {
77 // Manager will delete bubble_ui.
78 MockBubbleUi
* bubble_ui
= new MockBubbleUi
;
79 EXPECT_CALL(*bubble_ui
, Destroyed());
80 EXPECT_CALL(*bubble_ui
, Show(testing::_
));
81 EXPECT_CALL(*bubble_ui
, Close());
82 EXPECT_CALL(*bubble_ui
, UpdateAnchorPosition()).Times(0);
84 // Manager will delete delegate.
85 MockBubbleDelegate
* delegate
= new MockBubbleDelegate
;
86 EXPECT_CALL(*delegate
, Destroyed());
87 EXPECT_CALL(*delegate
, BuildBubbleUiMock())
88 .WillOnce(testing::Return(bubble_ui
));
89 EXPECT_CALL(*delegate
, ShouldClose(testing::_
))
90 .WillOnce(testing::Return(true));
92 manager_
->ShowBubble(make_scoped_ptr(delegate
));
95 TEST_F(BubbleManagerTest
, ManagerUpdatesBubbleUi
) {
96 // Manager will delete bubble_ui.
97 MockBubbleUi
* bubble_ui
= new MockBubbleUi
;
98 EXPECT_CALL(*bubble_ui
, Destroyed());
99 EXPECT_CALL(*bubble_ui
, Show(testing::_
));
100 EXPECT_CALL(*bubble_ui
, Close());
101 EXPECT_CALL(*bubble_ui
, UpdateAnchorPosition());
103 // Manager will delete delegate.
104 MockBubbleDelegate
* delegate
= new MockBubbleDelegate
;
105 EXPECT_CALL(*delegate
, Destroyed());
106 EXPECT_CALL(*delegate
, BuildBubbleUiMock())
107 .WillOnce(testing::Return(bubble_ui
));
108 EXPECT_CALL(*delegate
, ShouldClose(testing::_
))
109 .WillOnce(testing::Return(true));
111 manager_
->ShowBubble(make_scoped_ptr(delegate
));
112 manager_
->UpdateAllBubbleAnchors();
115 TEST_F(BubbleManagerTest
, CloseOnReferenceInvalidatesReference
) {
116 BubbleReference ref
= manager_
->ShowBubble(MockBubbleDelegate::Default());
118 ASSERT_TRUE(ref
->CloseBubble(BUBBLE_CLOSE_FOCUS_LOST
));
123 TEST_F(BubbleManagerTest
, CloseOnStubbornReferenceDoesNotInvalidate
) {
124 BubbleReference ref
= manager_
->ShowBubble(MockBubbleDelegate::Stubborn());
126 ASSERT_FALSE(ref
->CloseBubble(BUBBLE_CLOSE_FOCUS_LOST
));
131 TEST_F(BubbleManagerTest
, CloseInvalidatesReference
) {
132 BubbleReference ref
= manager_
->ShowBubble(MockBubbleDelegate::Default());
134 ASSERT_TRUE(manager_
->CloseBubble(ref
, BUBBLE_CLOSE_FOCUS_LOST
));
139 TEST_F(BubbleManagerTest
, CloseAllInvalidatesReference
) {
140 BubbleReference ref
= manager_
->ShowBubble(MockBubbleDelegate::Default());
142 manager_
->CloseAllBubbles(BUBBLE_CLOSE_FOCUS_LOST
);
147 TEST_F(BubbleManagerTest
, DestroyInvalidatesReference
) {
148 BubbleReference ref
= manager_
->ShowBubble(MockBubbleDelegate::Default());
155 TEST_F(BubbleManagerTest
, CloseInvalidatesStubbornReference
) {
156 BubbleReference ref
= manager_
->ShowBubble(MockBubbleDelegate::Stubborn());
158 ASSERT_TRUE(manager_
->CloseBubble(ref
, BUBBLE_CLOSE_FORCED
));
163 TEST_F(BubbleManagerTest
, CloseAllInvalidatesStubbornReference
) {
164 BubbleReference ref
= manager_
->ShowBubble(MockBubbleDelegate::Stubborn());
166 manager_
->CloseAllBubbles(BUBBLE_CLOSE_FORCED
);
171 TEST_F(BubbleManagerTest
, DestroyInvalidatesStubbornReference
) {
172 BubbleReference ref
= manager_
->ShowBubble(MockBubbleDelegate::Stubborn());
179 TEST_F(BubbleManagerTest
, CloseDoesNotInvalidateStubbornReference
) {
180 BubbleReference ref
= manager_
->ShowBubble(MockBubbleDelegate::Stubborn());
182 ASSERT_FALSE(manager_
->CloseBubble(ref
, BUBBLE_CLOSE_FOCUS_LOST
));
187 TEST_F(BubbleManagerTest
, CloseAllDoesNotInvalidateStubbornReference
) {
188 BubbleReference ref
= manager_
->ShowBubble(MockBubbleDelegate::Stubborn());
190 manager_
->CloseAllBubbles(BUBBLE_CLOSE_FOCUS_LOST
);
195 TEST_F(BubbleManagerTest
, CloseAllInvalidatesMixAppropriately
) {
196 BubbleReference stubborn_ref1
=
197 manager_
->ShowBubble(MockBubbleDelegate::Stubborn());
198 BubbleReference normal_ref1
=
199 manager_
->ShowBubble(MockBubbleDelegate::Default());
200 BubbleReference stubborn_ref2
=
201 manager_
->ShowBubble(MockBubbleDelegate::Stubborn());
202 BubbleReference normal_ref2
=
203 manager_
->ShowBubble(MockBubbleDelegate::Default());
204 BubbleReference stubborn_ref3
=
205 manager_
->ShowBubble(MockBubbleDelegate::Stubborn());
206 BubbleReference normal_ref3
=
207 manager_
->ShowBubble(MockBubbleDelegate::Default());
209 manager_
->CloseAllBubbles(BUBBLE_CLOSE_FOCUS_LOST
);
211 ASSERT_TRUE(stubborn_ref1
);
212 ASSERT_TRUE(stubborn_ref2
);
213 ASSERT_TRUE(stubborn_ref3
);
214 ASSERT_FALSE(normal_ref1
);
215 ASSERT_FALSE(normal_ref2
);
216 ASSERT_FALSE(normal_ref3
);
219 TEST_F(BubbleManagerTest
, UpdateAllShouldWorkWithoutBubbles
) {
220 // Manager shouldn't crash if bubbles have never been added.
221 manager_
->UpdateAllBubbleAnchors();
223 // Add a bubble and close it.
224 BubbleReference ref
= manager_
->ShowBubble(MockBubbleDelegate::Default());
225 ASSERT_TRUE(manager_
->CloseBubble(ref
, BUBBLE_CLOSE_FORCED
));
227 // Bubble should NOT get an update event because it's already closed.
228 manager_
->UpdateAllBubbleAnchors();
231 TEST_F(BubbleManagerTest
, CloseAllShouldWorkWithoutBubbles
) {
232 // Manager shouldn't crash if bubbles have never been added.
233 manager_
->CloseAllBubbles(BUBBLE_CLOSE_FOCUS_LOST
);
235 // Add a bubble and close it.
236 BubbleReference ref
= manager_
->ShowBubble(MockBubbleDelegate::Default());
237 ASSERT_TRUE(manager_
->CloseBubble(ref
, BUBBLE_CLOSE_FORCED
));
239 // Bubble should NOT get a close event because it's already closed.
240 manager_
->CloseAllBubbles(BUBBLE_CLOSE_FOCUS_LOST
);
243 TEST_F(BubbleManagerTest
, AllowBubbleChainingOnClose
) {
244 scoped_ptr
<BubbleDelegate
> chained_delegate
= MockBubbleDelegate::Default();
245 DelegateChainHelper
chain_helper(manager_
.get(), chained_delegate
.Pass());
247 // Manager will delete delegate.
248 MockBubbleDelegate
* delegate
= new MockBubbleDelegate
;
249 EXPECT_CALL(*delegate
, BuildBubbleUiMock())
250 .WillOnce(testing::Return(new MockBubbleUi
));
251 EXPECT_CALL(*delegate
, ShouldClose(testing::_
))
252 .WillOnce(testing::DoAll(testing::InvokeWithoutArgs(
253 &chain_helper
, &DelegateChainHelper::Chain
),
254 testing::Return(true)));
256 BubbleReference ref
= manager_
->ShowBubble(make_scoped_ptr(delegate
));
257 ASSERT_TRUE(manager_
->CloseBubble(ref
, BUBBLE_CLOSE_FORCED
));
259 ASSERT_TRUE(chain_helper
.BubbleWasTaken());
262 TEST_F(BubbleManagerTest
, AllowBubbleChainingOnCloseAll
) {
263 scoped_ptr
<BubbleDelegate
> chained_delegate
= MockBubbleDelegate::Default();
264 DelegateChainHelper
chain_helper(manager_
.get(), chained_delegate
.Pass());
266 // Manager will delete delegate.
267 MockBubbleDelegate
* delegate
= new MockBubbleDelegate
;
268 EXPECT_CALL(*delegate
, BuildBubbleUiMock())
269 .WillOnce(testing::Return(new MockBubbleUi
));
270 EXPECT_CALL(*delegate
, ShouldClose(testing::_
))
271 .WillOnce(testing::DoAll(testing::InvokeWithoutArgs(
272 &chain_helper
, &DelegateChainHelper::Chain
),
273 testing::Return(true)));
275 manager_
->ShowBubble(make_scoped_ptr(delegate
));
276 manager_
->CloseAllBubbles(BUBBLE_CLOSE_FORCED
);
278 ASSERT_TRUE(chain_helper
.BubbleWasTaken());
281 TEST_F(BubbleManagerTest
, BubblesDoNotChainOnDestroy
) {
282 // Manager will delete delegate.
283 MockBubbleDelegate
* chained_delegate
= new MockBubbleDelegate
;
284 EXPECT_CALL(*chained_delegate
, BuildBubbleUiMock()).Times(0);
285 EXPECT_CALL(*chained_delegate
, ShouldClose(testing::_
)).Times(0);
287 DelegateChainHelper
chain_helper(manager_
.get(),
288 make_scoped_ptr(chained_delegate
));
290 // Manager will delete delegate.
291 MockBubbleDelegate
* delegate
= new MockBubbleDelegate
;
292 EXPECT_CALL(*delegate
, BuildBubbleUiMock())
293 .WillOnce(testing::Return(new MockBubbleUi
));
294 EXPECT_CALL(*delegate
, ShouldClose(testing::_
))
295 .WillOnce(testing::DoAll(testing::InvokeWithoutArgs(
296 &chain_helper
, &DelegateChainHelper::Chain
),
297 testing::Return(true)));
299 manager_
->ShowBubble(make_scoped_ptr(delegate
));
302 // The manager will take the bubble, but not show it.
303 ASSERT_TRUE(chain_helper
.BubbleWasTaken());
306 TEST_F(BubbleManagerTest
, BubbleUpdatesTrue
) {
307 MockBubbleUi
* bubble_ui
= new MockBubbleUi
;
308 MockBubbleDelegate
* delegate
= new MockBubbleDelegate
;
309 EXPECT_CALL(*delegate
, BuildBubbleUiMock())
310 .WillOnce(testing::Return(bubble_ui
));
311 EXPECT_CALL(*delegate
, ShouldClose(testing::_
))
312 .WillOnce(testing::Return(true));
313 EXPECT_CALL(*delegate
, UpdateBubbleUi(bubble_ui
))
314 .WillOnce(testing::Return(true));
316 BubbleReference ref
= manager_
->ShowBubble(make_scoped_ptr(delegate
));
317 ASSERT_TRUE(ref
->UpdateBubbleUi());
320 TEST_F(BubbleManagerTest
, BubbleUpdatesFalse
) {
321 MockBubbleUi
* bubble_ui
= new MockBubbleUi
;
322 MockBubbleDelegate
* delegate
= new MockBubbleDelegate
;
323 EXPECT_CALL(*delegate
, BuildBubbleUiMock())
324 .WillOnce(testing::Return(bubble_ui
));
325 EXPECT_CALL(*delegate
, ShouldClose(testing::_
))
326 .WillOnce(testing::Return(true));
327 EXPECT_CALL(*delegate
, UpdateBubbleUi(bubble_ui
))
328 .WillOnce(testing::Return(false));
330 BubbleReference ref
= manager_
->ShowBubble(make_scoped_ptr(delegate
));
331 ASSERT_FALSE(ref
->UpdateBubbleUi());
334 TEST_F(BubbleManagerTest
, BubbleCloseReasonIsCalled
) {
335 MockBubbleManagerObserver metrics
;
336 EXPECT_CALL(metrics
, OnBubbleNeverShown(testing::_
)).Times(0);
337 EXPECT_CALL(metrics
, OnBubbleClosed(testing::_
, BUBBLE_CLOSE_ACCEPTED
));
338 manager_
->AddBubbleManagerObserver(&metrics
);
340 BubbleReference ref
= manager_
->ShowBubble(MockBubbleDelegate::Default());
341 ref
->CloseBubble(BUBBLE_CLOSE_ACCEPTED
);
343 // Destroy to verify no events are sent to |metrics| in destructor.
347 TEST_F(BubbleManagerTest
, BubbleCloseNeverShownIsCalled
) {
348 MockBubbleManagerObserver metrics
;
349 // |chained_delegate| should never be shown.
350 EXPECT_CALL(metrics
, OnBubbleNeverShown(testing::_
));
351 // |delegate| should be forced to close when the manager is destroyed.
352 EXPECT_CALL(metrics
, OnBubbleClosed(testing::_
, BUBBLE_CLOSE_FORCED
));
353 manager_
->AddBubbleManagerObserver(&metrics
);
355 // Manager will delete delegate.
356 MockBubbleDelegate
* chained_delegate
= new MockBubbleDelegate
;
357 EXPECT_CALL(*chained_delegate
, BuildBubbleUiMock()).Times(0);
358 EXPECT_CALL(*chained_delegate
, ShouldClose(testing::_
)).Times(0);
360 DelegateChainHelper
chain_helper(manager_
.get(),
361 make_scoped_ptr(chained_delegate
));
363 // Manager will delete delegate.
364 MockBubbleDelegate
* delegate
= new MockBubbleDelegate
;
365 EXPECT_CALL(*delegate
, BuildBubbleUiMock())
366 .WillOnce(testing::Return(new MockBubbleUi
));
367 EXPECT_CALL(*delegate
, ShouldClose(testing::_
))
368 .WillOnce(testing::DoAll(testing::InvokeWithoutArgs(
369 &chain_helper
, &DelegateChainHelper::Chain
),
370 testing::Return(true)));
372 manager_
->ShowBubble(make_scoped_ptr(delegate
));
375 // The manager will take the bubble, but not show it.
376 ASSERT_TRUE(chain_helper
.BubbleWasTaken());