- add sources.
[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/native_web_contents_modal_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 class TestNativeWebContentsModalDialogManager
18     : public NativeWebContentsModalDialogManager {
19  public:
20   enum DialogState {
21     UNKNOWN,
22     NOT_SHOWN,
23     SHOWN,
24     HIDDEN,
25     CLOSED
26   };
27
28   explicit TestNativeWebContentsModalDialogManager(
29       NativeWebContentsModalDialogManagerDelegate* delegate)
30       : delegate_(delegate) {}
31   virtual void ManageDialog(NativeWebContentsModalDialog dialog) OVERRIDE {
32     dialog_state_[dialog] = NOT_SHOWN;
33   }
34   virtual void ShowDialog(NativeWebContentsModalDialog dialog) OVERRIDE {
35     dialog_state_[dialog] = SHOWN;
36   }
37   virtual void HideDialog(NativeWebContentsModalDialog dialog) OVERRIDE {
38     dialog_state_[dialog] = HIDDEN;
39   }
40   virtual void CloseDialog(NativeWebContentsModalDialog dialog) OVERRIDE {
41     delegate_->WillClose(dialog);
42     dialog_state_[dialog] = CLOSED;
43   }
44   virtual void FocusDialog(NativeWebContentsModalDialog dialog) OVERRIDE {
45   }
46   virtual void PulseDialog(NativeWebContentsModalDialog dialog) OVERRIDE {
47   }
48   virtual void HostChanged(WebContentsModalDialogHost* new_host) OVERRIDE {
49   }
50
51   int GetCloseCount() const {
52     int count = 0;
53     for (DialogStateMap::const_iterator it = dialog_state_.begin();
54          it != dialog_state_.end(); ++it) {
55       if (it->second == CLOSED)
56         count++;
57     }
58     return count;
59   }
60
61   DialogState GetDialogState(NativeWebContentsModalDialog dialog) const {
62     DialogStateMap::const_iterator loc = dialog_state_.find(dialog);
63     return loc == dialog_state_.end() ? UNKNOWN : loc->second;
64   }
65
66  private:
67   typedef std::map<NativeWebContentsModalDialog, DialogState> DialogStateMap;
68
69   NativeWebContentsModalDialogManagerDelegate* delegate_;
70   DialogStateMap dialog_state_;
71
72   DISALLOW_COPY_AND_ASSIGN(TestNativeWebContentsModalDialogManager);
73 };
74
75 class WebContentsModalDialogManagerTest
76     : public content::RenderViewHostTestHarness {
77  public:
78   WebContentsModalDialogManagerTest()
79       : next_dialog_id(1),
80         manager(NULL),
81         native_manager(NULL) {
82   }
83
84   virtual void SetUp() {
85     content::RenderViewHostTestHarness::SetUp();
86
87     delegate.reset(new TestWebContentsModalDialogManagerDelegate);
88     WebContentsModalDialogManager::CreateForWebContents(web_contents());
89     manager = WebContentsModalDialogManager::FromWebContents(web_contents());
90     manager->SetDelegate(delegate.get());
91     test_api.reset(new WebContentsModalDialogManager::TestApi(manager));
92     native_manager = new TestNativeWebContentsModalDialogManager(manager);
93
94     // |manager| owns |native_manager| as a result.
95     test_api->ResetNativeManager(native_manager);
96   }
97
98   virtual void TearDown() {
99     test_api.reset();
100     content::RenderViewHostTestHarness::TearDown();
101   }
102
103  protected:
104   NativeWebContentsModalDialog MakeFakeDialog() {
105     // WebContentsModalDialogManager treats the NativeWebContentsModalDialog as
106     // an opaque type, so creating fake NativeWebContentsModalDialogs using
107     // reinterpret_cast is valid.
108     return reinterpret_cast<NativeWebContentsModalDialog>(next_dialog_id++);
109   }
110
111   int next_dialog_id;
112   scoped_ptr<TestWebContentsModalDialogManagerDelegate> delegate;
113   WebContentsModalDialogManager* manager;
114   scoped_ptr<WebContentsModalDialogManager::TestApi> test_api;
115   TestNativeWebContentsModalDialogManager* native_manager;
116
117   DISALLOW_COPY_AND_ASSIGN(WebContentsModalDialogManagerTest);
118 };
119
120 NativeWebContentsModalDialogManager*
121 WebContentsModalDialogManager::CreateNativeManager(
122     NativeWebContentsModalDialogManagerDelegate* native_delegate) {
123   return new TestNativeWebContentsModalDialogManager(native_delegate);
124 }
125
126 // Test that the dialog is shown immediately when the delegate indicates the web
127 // contents is visible.
128 TEST_F(WebContentsModalDialogManagerTest, WebContentsVisible) {
129   // Dialog should be shown while WebContents is visible.
130   const NativeWebContentsModalDialog dialog1 = MakeFakeDialog();
131
132   manager->ShowDialog(dialog1);
133
134   EXPECT_EQ(TestNativeWebContentsModalDialogManager::SHOWN,
135             native_manager->GetDialogState(dialog1));
136   EXPECT_TRUE(manager->IsDialogActive());
137   EXPECT_TRUE(delegate->web_contents_blocked());
138 }
139
140 // Test that the dialog is not shown immediately when the delegate indicates the
141 // web contents is not visible.
142 TEST_F(WebContentsModalDialogManagerTest, WebContentsNotVisible) {
143   // Dialog should not be shown while WebContents is not visible.
144   delegate->set_web_contents_visible(false);
145
146   const NativeWebContentsModalDialog dialog1 = MakeFakeDialog();
147
148   manager->ShowDialog(dialog1);
149
150   EXPECT_EQ(TestNativeWebContentsModalDialogManager::NOT_SHOWN,
151             native_manager->GetDialogState(dialog1));
152   EXPECT_TRUE(manager->IsDialogActive());
153   EXPECT_TRUE(delegate->web_contents_blocked());
154 }
155
156 // Test that only the first of multiple dialogs is shown.
157 TEST_F(WebContentsModalDialogManagerTest, ShowDialogs) {
158   const NativeWebContentsModalDialog dialog1 = MakeFakeDialog();
159   const NativeWebContentsModalDialog dialog2 = MakeFakeDialog();
160   const NativeWebContentsModalDialog dialog3 = MakeFakeDialog();
161
162   manager->ShowDialog(dialog1);
163   manager->ShowDialog(dialog2);
164   manager->ShowDialog(dialog3);
165
166   EXPECT_TRUE(delegate->web_contents_blocked());
167   EXPECT_EQ(TestNativeWebContentsModalDialogManager::SHOWN,
168             native_manager->GetDialogState(dialog1));
169   EXPECT_EQ(TestNativeWebContentsModalDialogManager::NOT_SHOWN,
170             native_manager->GetDialogState(dialog2));
171   EXPECT_EQ(TestNativeWebContentsModalDialogManager::NOT_SHOWN,
172             native_manager->GetDialogState(dialog3));
173 }
174
175 // Test that the dialog is shown/hidden when the WebContents is shown/hidden.
176 TEST_F(WebContentsModalDialogManagerTest, VisibilityObservation) {
177   const NativeWebContentsModalDialog dialog1 = MakeFakeDialog();
178
179   manager->ShowDialog(dialog1);
180
181   EXPECT_TRUE(manager->IsDialogActive());
182   EXPECT_TRUE(delegate->web_contents_blocked());
183   EXPECT_EQ(TestNativeWebContentsModalDialogManager::SHOWN,
184             native_manager->GetDialogState(dialog1));
185
186   test_api->WebContentsWasHidden();
187
188   EXPECT_TRUE(manager->IsDialogActive());
189   EXPECT_TRUE(delegate->web_contents_blocked());
190   EXPECT_EQ(TestNativeWebContentsModalDialogManager::HIDDEN,
191             native_manager->GetDialogState(dialog1));
192
193   test_api->WebContentsWasShown();
194
195   EXPECT_TRUE(manager->IsDialogActive());
196   EXPECT_TRUE(delegate->web_contents_blocked());
197   EXPECT_EQ(TestNativeWebContentsModalDialogManager::SHOWN,
198             native_manager->GetDialogState(dialog1));
199 }
200
201 // Test that attaching an interstitial page closes dialogs configured to close.
202 TEST_F(WebContentsModalDialogManagerTest, InterstitialPage) {
203   const NativeWebContentsModalDialog dialog1 = MakeFakeDialog();
204   const NativeWebContentsModalDialog dialog2 = MakeFakeDialog();
205   const NativeWebContentsModalDialog dialog3 = MakeFakeDialog();
206
207   manager->ShowDialog(dialog1);
208   manager->ShowDialog(dialog2);
209   manager->ShowDialog(dialog3);
210
211 #if defined(OS_WIN) || defined(USE_AURA)
212   manager->SetCloseOnInterstitialPage(dialog2, false);
213 #else
214   // TODO(wittman): Remove this section once Mac is changed to close on
215   // interstitial pages by default.
216   manager->SetCloseOnInterstitialPage(dialog1, true);
217   manager->SetCloseOnInterstitialPage(dialog3, true);
218 #endif
219
220   test_api->DidAttachInterstitialPage();
221   EXPECT_EQ(TestNativeWebContentsModalDialogManager::CLOSED,
222             native_manager->GetDialogState(dialog1));
223   EXPECT_EQ(TestNativeWebContentsModalDialogManager::SHOWN,
224             native_manager->GetDialogState(dialog2));
225   EXPECT_EQ(TestNativeWebContentsModalDialogManager::CLOSED,
226             native_manager->GetDialogState(dialog3));
227 }
228
229
230 // Test that the first dialog is always shown, regardless of the order in which
231 // dialogs are closed.
232 TEST_F(WebContentsModalDialogManagerTest, CloseDialogs) {
233   // The front dialog is always shown regardless of dialog close order.
234   const NativeWebContentsModalDialog dialog1 = MakeFakeDialog();
235   const NativeWebContentsModalDialog dialog2 = MakeFakeDialog();
236   const NativeWebContentsModalDialog dialog3 = MakeFakeDialog();
237   const NativeWebContentsModalDialog dialog4 = MakeFakeDialog();
238
239   manager->ShowDialog(dialog1);
240   manager->ShowDialog(dialog2);
241   manager->ShowDialog(dialog3);
242   manager->ShowDialog(dialog4);
243
244   native_manager->CloseDialog(dialog1);
245
246   EXPECT_TRUE(manager->IsDialogActive());
247   EXPECT_TRUE(delegate->web_contents_blocked());
248   EXPECT_EQ(TestNativeWebContentsModalDialogManager::CLOSED,
249             native_manager->GetDialogState(dialog1));
250   EXPECT_EQ(TestNativeWebContentsModalDialogManager::SHOWN,
251             native_manager->GetDialogState(dialog2));
252   EXPECT_EQ(TestNativeWebContentsModalDialogManager::NOT_SHOWN,
253             native_manager->GetDialogState(dialog3));
254   EXPECT_EQ(TestNativeWebContentsModalDialogManager::NOT_SHOWN,
255             native_manager->GetDialogState(dialog4));
256
257   native_manager->CloseDialog(dialog3);
258
259   EXPECT_TRUE(manager->IsDialogActive());
260   EXPECT_TRUE(delegate->web_contents_blocked());
261   EXPECT_EQ(TestNativeWebContentsModalDialogManager::SHOWN,
262             native_manager->GetDialogState(dialog2));
263   EXPECT_EQ(TestNativeWebContentsModalDialogManager::CLOSED,
264             native_manager->GetDialogState(dialog3));
265   EXPECT_EQ(TestNativeWebContentsModalDialogManager::NOT_SHOWN,
266             native_manager->GetDialogState(dialog4));
267
268   native_manager->CloseDialog(dialog2);
269
270   EXPECT_TRUE(manager->IsDialogActive());
271   EXPECT_TRUE(delegate->web_contents_blocked());
272   EXPECT_EQ(TestNativeWebContentsModalDialogManager::CLOSED,
273             native_manager->GetDialogState(dialog2));
274   EXPECT_EQ(TestNativeWebContentsModalDialogManager::SHOWN,
275             native_manager->GetDialogState(dialog4));
276
277   native_manager->CloseDialog(dialog4);
278
279   EXPECT_FALSE(manager->IsDialogActive());
280   EXPECT_FALSE(delegate->web_contents_blocked());
281   EXPECT_EQ(TestNativeWebContentsModalDialogManager::CLOSED,
282             native_manager->GetDialogState(dialog4));
283 }
284
285 // Test that CloseAllDialogs does what it says.
286 TEST_F(WebContentsModalDialogManagerTest, CloseAllDialogs) {
287   const int kWindowCount = 4;
288   for (int i = 0; i < kWindowCount; i++)
289     manager->ShowDialog(MakeFakeDialog());
290
291   EXPECT_EQ(0, native_manager->GetCloseCount());
292
293   test_api->CloseAllDialogs();
294   EXPECT_FALSE(delegate->web_contents_blocked());
295   EXPECT_FALSE(manager->IsDialogActive());
296   EXPECT_EQ(kWindowCount, native_manager->GetCloseCount());
297 }
298
299 }  // namespace web_modal