Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / components / web_modal / web_contents_modal_dialog_manager_unittest.cc
1 // Copyright (c) 2012 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.
4
5 #include "components/web_modal/web_contents_modal_dialog_manager.h"
6
7 #include <map>
8
9 #include "base/memory/scoped_ptr.h"
10 #include "components/web_modal/single_web_contents_dialog_manager.h"
11 #include "components/web_modal/test_web_contents_modal_dialog_manager_delegate.h"
12 #include "content/public/test/test_renderer_host.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 namespace web_modal {
16
17 // Tracks persistent state changes of the native WC-modal dialog manager.
18 class NativeManagerTracker {
19  public:
20   enum DialogState {
21     UNKNOWN,
22     NOT_SHOWN,
23     SHOWN,
24     HIDDEN,
25     CLOSED
26   };
27
28   NativeManagerTracker() : state_(UNKNOWN), was_shown_(false) {}
29
30   void SetState(DialogState state) {
31     state_ = state;
32     if (state_ == SHOWN)
33       was_shown_ = true;
34   }
35
36   DialogState state_;
37   bool was_shown_;
38 };
39
40 NativeManagerTracker unused_tracker;
41
42 class TestNativeWebContentsModalDialogManager
43     : public SingleWebContentsDialogManager {
44  public:
45   TestNativeWebContentsModalDialogManager(
46       NativeWebContentsModalDialog dialog,
47       SingleWebContentsDialogManagerDelegate* delegate,
48       NativeManagerTracker* tracker)
49       : delegate_(delegate),
50         dialog_(dialog),
51         tracker_(tracker) {
52     if (tracker_)
53       tracker_->SetState(NativeManagerTracker::NOT_SHOWN);
54   }
55
56   void Show() override {
57     if (tracker_)
58       tracker_->SetState(NativeManagerTracker::SHOWN);
59   }
60   void Hide() override {
61     if (tracker_)
62       tracker_->SetState(NativeManagerTracker::HIDDEN);
63   }
64   void Close() override {
65     if (tracker_)
66       tracker_->SetState(NativeManagerTracker::CLOSED);
67     delegate_->WillClose(dialog_);
68   }
69   void Focus() override {}
70   void Pulse() override {}
71   void HostChanged(WebContentsModalDialogHost* new_host) override {}
72   NativeWebContentsModalDialog dialog() override { return dialog_; }
73
74   void StopTracking() {
75     tracker_ = NULL;
76   }
77
78  private:
79   SingleWebContentsDialogManagerDelegate* delegate_;
80   NativeWebContentsModalDialog dialog_;
81   NativeManagerTracker* tracker_;
82
83   DISALLOW_COPY_AND_ASSIGN(TestNativeWebContentsModalDialogManager);
84 };
85
86 class WebContentsModalDialogManagerTest
87     : public content::RenderViewHostTestHarness {
88  public:
89   WebContentsModalDialogManagerTest()
90       : next_dialog_id(1),
91         manager(NULL) {
92   }
93
94   void SetUp() override {
95     content::RenderViewHostTestHarness::SetUp();
96
97     delegate.reset(new TestWebContentsModalDialogManagerDelegate);
98     WebContentsModalDialogManager::CreateForWebContents(web_contents());
99     manager = WebContentsModalDialogManager::FromWebContents(web_contents());
100     manager->SetDelegate(delegate.get());
101     test_api.reset(new WebContentsModalDialogManager::TestApi(manager));
102   }
103
104   void TearDown() override {
105     test_api.reset();
106     content::RenderViewHostTestHarness::TearDown();
107   }
108
109  protected:
110   NativeWebContentsModalDialog MakeFakeDialog() {
111     // WebContentsModalDialogManager treats the NativeWebContentsModalDialog as
112     // an opaque type, so creating fake NativeWebContentsModalDialogs using
113     // reinterpret_cast is valid.
114     return reinterpret_cast<NativeWebContentsModalDialog>(next_dialog_id++);
115   }
116
117   int next_dialog_id;
118   scoped_ptr<TestWebContentsModalDialogManagerDelegate> delegate;
119   WebContentsModalDialogManager* manager;
120   scoped_ptr<WebContentsModalDialogManager::TestApi> test_api;
121
122   DISALLOW_COPY_AND_ASSIGN(WebContentsModalDialogManagerTest);
123 };
124
125 SingleWebContentsDialogManager*
126 WebContentsModalDialogManager::CreateNativeWebModalManager(
127     NativeWebContentsModalDialog dialog,
128     SingleWebContentsDialogManagerDelegate* native_delegate) {
129   NOTREACHED();
130   return new TestNativeWebContentsModalDialogManager(
131       dialog,
132       native_delegate,
133       &unused_tracker);
134 }
135
136 // Test that the dialog is shown immediately when the delegate indicates the web
137 // contents is visible.
138 TEST_F(WebContentsModalDialogManagerTest, WebContentsVisible) {
139   // Dialog should be shown while WebContents is visible.
140   const NativeWebContentsModalDialog dialog = MakeFakeDialog();
141
142   NativeManagerTracker tracker;
143   TestNativeWebContentsModalDialogManager* native_manager =
144       new TestNativeWebContentsModalDialogManager(dialog, manager, &tracker);
145   manager->ShowDialogWithManager(dialog,
146       scoped_ptr<SingleWebContentsDialogManager>(native_manager).Pass());
147
148   EXPECT_EQ(NativeManagerTracker::SHOWN, tracker.state_);
149   EXPECT_TRUE(manager->IsDialogActive());
150   EXPECT_TRUE(delegate->web_contents_blocked());
151   EXPECT_TRUE(tracker.was_shown_);
152
153   native_manager->StopTracking();
154 }
155
156 // Test that the dialog is not shown immediately when the delegate indicates the
157 // web contents is not visible.
158 TEST_F(WebContentsModalDialogManagerTest, WebContentsNotVisible) {
159   // Dialog should not be shown while WebContents is not visible.
160   delegate->set_web_contents_visible(false);
161
162   const NativeWebContentsModalDialog dialog = MakeFakeDialog();
163
164   NativeManagerTracker tracker;
165   TestNativeWebContentsModalDialogManager* native_manager =
166       new TestNativeWebContentsModalDialogManager(dialog, manager, &tracker);
167   manager->ShowDialogWithManager(dialog,
168       scoped_ptr<SingleWebContentsDialogManager>(native_manager).Pass());
169
170   EXPECT_EQ(NativeManagerTracker::NOT_SHOWN, tracker.state_);
171   EXPECT_TRUE(manager->IsDialogActive());
172   EXPECT_TRUE(delegate->web_contents_blocked());
173   EXPECT_FALSE(tracker.was_shown_);
174
175   native_manager->StopTracking();
176 }
177
178 // Test that only the first of multiple dialogs is shown.
179 TEST_F(WebContentsModalDialogManagerTest, ShowDialogs) {
180   const NativeWebContentsModalDialog dialog1 = MakeFakeDialog();
181   const NativeWebContentsModalDialog dialog2 = MakeFakeDialog();
182   const NativeWebContentsModalDialog dialog3 = MakeFakeDialog();
183
184   NativeManagerTracker tracker1;
185   NativeManagerTracker tracker2;
186   NativeManagerTracker tracker3;
187   TestNativeWebContentsModalDialogManager* native_manager1 =
188       new TestNativeWebContentsModalDialogManager(dialog1, manager, &tracker1);
189   TestNativeWebContentsModalDialogManager* native_manager2 =
190       new TestNativeWebContentsModalDialogManager(dialog2, manager, &tracker2);
191   TestNativeWebContentsModalDialogManager* native_manager3 =
192       new TestNativeWebContentsModalDialogManager(dialog3, manager, &tracker3);
193   manager->ShowDialogWithManager(dialog1,
194       scoped_ptr<SingleWebContentsDialogManager>(native_manager1).Pass());
195   manager->ShowDialogWithManager(dialog2,
196       scoped_ptr<SingleWebContentsDialogManager>(native_manager2).Pass());
197   manager->ShowDialogWithManager(dialog3,
198       scoped_ptr<SingleWebContentsDialogManager>(native_manager3).Pass());
199
200   EXPECT_TRUE(delegate->web_contents_blocked());
201   EXPECT_EQ(NativeManagerTracker::SHOWN, tracker1.state_);
202   EXPECT_EQ(NativeManagerTracker::NOT_SHOWN, tracker2.state_);
203   EXPECT_EQ(NativeManagerTracker::NOT_SHOWN, tracker3.state_);
204
205   native_manager1->StopTracking();
206   native_manager2->StopTracking();
207   native_manager3->StopTracking();
208 }
209
210 // Test that the dialog is shown/hidden when the WebContents is shown/hidden.
211 TEST_F(WebContentsModalDialogManagerTest, VisibilityObservation) {
212   const NativeWebContentsModalDialog dialog = MakeFakeDialog();
213
214   NativeManagerTracker tracker;
215   TestNativeWebContentsModalDialogManager* native_manager =
216       new TestNativeWebContentsModalDialogManager(dialog, manager, &tracker);
217   manager->ShowDialogWithManager(dialog,
218       scoped_ptr<SingleWebContentsDialogManager>(native_manager).Pass());
219
220   EXPECT_TRUE(manager->IsDialogActive());
221   EXPECT_TRUE(delegate->web_contents_blocked());
222   EXPECT_EQ(NativeManagerTracker::SHOWN, tracker.state_);
223
224   test_api->WebContentsWasHidden();
225
226   EXPECT_TRUE(manager->IsDialogActive());
227   EXPECT_TRUE(delegate->web_contents_blocked());
228   EXPECT_EQ(NativeManagerTracker::HIDDEN, tracker.state_);
229
230   test_api->WebContentsWasShown();
231
232   EXPECT_TRUE(manager->IsDialogActive());
233   EXPECT_TRUE(delegate->web_contents_blocked());
234   EXPECT_EQ(NativeManagerTracker::SHOWN, tracker.state_);
235
236   native_manager->StopTracking();
237 }
238
239 // Test that attaching an interstitial page closes all dialogs.
240 TEST_F(WebContentsModalDialogManagerTest, InterstitialPage) {
241   const NativeWebContentsModalDialog dialog1 = MakeFakeDialog();
242   const NativeWebContentsModalDialog dialog2 = MakeFakeDialog();
243
244   NativeManagerTracker tracker1;
245   NativeManagerTracker tracker2;
246   TestNativeWebContentsModalDialogManager* native_manager1 =
247       new TestNativeWebContentsModalDialogManager(dialog1, manager, &tracker1);
248   TestNativeWebContentsModalDialogManager* native_manager2 =
249       new TestNativeWebContentsModalDialogManager(dialog2, manager, &tracker2);
250   manager->ShowDialogWithManager(dialog1,
251       scoped_ptr<SingleWebContentsDialogManager>(native_manager1).Pass());
252   manager->ShowDialogWithManager(dialog2,
253       scoped_ptr<SingleWebContentsDialogManager>(native_manager2).Pass());
254
255   test_api->DidAttachInterstitialPage();
256
257 #if defined(USE_AURA)
258   EXPECT_EQ(NativeManagerTracker::CLOSED, tracker1.state_);
259   EXPECT_EQ(NativeManagerTracker::CLOSED, tracker2.state_);
260 #else
261   EXPECT_EQ(NativeManagerTracker::SHOWN, tracker1.state_);
262   EXPECT_EQ(NativeManagerTracker::NOT_SHOWN, tracker2.state_);
263 #endif
264
265   EXPECT_TRUE(tracker1.was_shown_);
266   EXPECT_FALSE(tracker2.was_shown_);
267
268 #if !defined(USE_AURA)
269   native_manager1->StopTracking();
270   native_manager2->StopTracking();
271 #endif
272 }
273
274
275 // Test that the first dialog is always shown, regardless of the order in which
276 // dialogs are closed.
277 TEST_F(WebContentsModalDialogManagerTest, CloseDialogs) {
278   // The front dialog is always shown regardless of dialog close order.
279   const NativeWebContentsModalDialog dialog1 = MakeFakeDialog();
280   const NativeWebContentsModalDialog dialog2 = MakeFakeDialog();
281   const NativeWebContentsModalDialog dialog3 = MakeFakeDialog();
282   const NativeWebContentsModalDialog dialog4 = MakeFakeDialog();
283
284   NativeManagerTracker tracker1;
285   NativeManagerTracker tracker2;
286   NativeManagerTracker tracker3;
287   NativeManagerTracker tracker4;
288   TestNativeWebContentsModalDialogManager* native_manager1 =
289       new TestNativeWebContentsModalDialogManager(dialog1, manager, &tracker1);
290   TestNativeWebContentsModalDialogManager* native_manager2 =
291       new TestNativeWebContentsModalDialogManager(dialog2, manager, &tracker2);
292   TestNativeWebContentsModalDialogManager* native_manager3 =
293       new TestNativeWebContentsModalDialogManager(dialog3, manager, &tracker3);
294   TestNativeWebContentsModalDialogManager* native_manager4 =
295       new TestNativeWebContentsModalDialogManager(dialog4, manager, &tracker4);
296   manager->ShowDialogWithManager(dialog1,
297       scoped_ptr<SingleWebContentsDialogManager>(native_manager1).Pass());
298   manager->ShowDialogWithManager(dialog2,
299       scoped_ptr<SingleWebContentsDialogManager>(native_manager2).Pass());
300   manager->ShowDialogWithManager(dialog3,
301       scoped_ptr<SingleWebContentsDialogManager>(native_manager3).Pass());
302   manager->ShowDialogWithManager(dialog4,
303       scoped_ptr<SingleWebContentsDialogManager>(native_manager4).Pass());
304
305   native_manager1->Close();
306
307   EXPECT_TRUE(manager->IsDialogActive());
308   EXPECT_TRUE(delegate->web_contents_blocked());
309   EXPECT_EQ(NativeManagerTracker::CLOSED, tracker1.state_);
310   EXPECT_EQ(NativeManagerTracker::SHOWN, tracker2.state_);
311   EXPECT_EQ(NativeManagerTracker::NOT_SHOWN, tracker3.state_);
312   EXPECT_EQ(NativeManagerTracker::NOT_SHOWN, tracker4.state_);
313
314   native_manager3->Close();
315
316   EXPECT_TRUE(manager->IsDialogActive());
317   EXPECT_TRUE(delegate->web_contents_blocked());
318   EXPECT_EQ(NativeManagerTracker::CLOSED, tracker1.state_);
319   EXPECT_EQ(NativeManagerTracker::SHOWN, tracker2.state_);
320   EXPECT_EQ(NativeManagerTracker::CLOSED, tracker3.state_);
321   EXPECT_EQ(NativeManagerTracker::NOT_SHOWN, tracker4.state_);
322   EXPECT_FALSE(tracker3.was_shown_);
323
324   native_manager2->Close();
325
326   EXPECT_TRUE(manager->IsDialogActive());
327   EXPECT_TRUE(delegate->web_contents_blocked());
328   EXPECT_EQ(NativeManagerTracker::CLOSED, tracker1.state_);
329   EXPECT_EQ(NativeManagerTracker::CLOSED, tracker2.state_);
330   EXPECT_EQ(NativeManagerTracker::CLOSED, tracker3.state_);
331   EXPECT_EQ(NativeManagerTracker::SHOWN, tracker4.state_);
332   EXPECT_FALSE(tracker3.was_shown_);
333
334   native_manager4->Close();
335
336   EXPECT_FALSE(manager->IsDialogActive());
337   EXPECT_FALSE(delegate->web_contents_blocked());
338   EXPECT_EQ(NativeManagerTracker::CLOSED, tracker1.state_);
339   EXPECT_EQ(NativeManagerTracker::CLOSED, tracker2.state_);
340   EXPECT_EQ(NativeManagerTracker::CLOSED, tracker3.state_);
341   EXPECT_EQ(NativeManagerTracker::CLOSED, tracker4.state_);
342   EXPECT_TRUE(tracker1.was_shown_);
343   EXPECT_TRUE(tracker2.was_shown_);
344   EXPECT_FALSE(tracker3.was_shown_);
345   EXPECT_TRUE(tracker4.was_shown_);
346 }
347
348 // Test that CloseAllDialogs does what it says.
349 TEST_F(WebContentsModalDialogManagerTest, CloseAllDialogs) {
350   const int kWindowCount = 4;
351   NativeManagerTracker trackers[kWindowCount];
352   TestNativeWebContentsModalDialogManager* native_managers[kWindowCount];
353   for (int i = 0; i < kWindowCount; i++) {
354     const NativeWebContentsModalDialog dialog = MakeFakeDialog();
355     native_managers[i] =
356         new TestNativeWebContentsModalDialogManager(
357             dialog, manager, &(trackers[i]));
358     manager->ShowDialogWithManager(dialog,
359     scoped_ptr<SingleWebContentsDialogManager>(
360         native_managers[i]).Pass());
361   }
362
363   for (int i = 0; i < kWindowCount; i++)
364     EXPECT_NE(NativeManagerTracker::CLOSED, trackers[i].state_);
365
366   test_api->CloseAllDialogs();
367
368   EXPECT_FALSE(delegate->web_contents_blocked());
369   EXPECT_FALSE(manager->IsDialogActive());
370   for (int i = 0; i < kWindowCount; i++)
371     EXPECT_EQ(NativeManagerTracker::CLOSED, trackers[i].state_);
372 }
373
374 }  // namespace web_modal