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.
5 #include "components/web_modal/web_contents_modal_dialog_manager.h"
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"
17 class TestNativeWebContentsModalDialogManager
18 : public NativeWebContentsModalDialogManager {
28 explicit TestNativeWebContentsModalDialogManager(
29 NativeWebContentsModalDialogManagerDelegate* delegate)
30 : delegate_(delegate) {}
31 virtual void ManageDialog(NativeWebContentsModalDialog dialog) OVERRIDE {
32 dialog_state_[dialog] = NOT_SHOWN;
34 virtual void ShowDialog(NativeWebContentsModalDialog dialog) OVERRIDE {
35 dialog_state_[dialog] = SHOWN;
37 virtual void HideDialog(NativeWebContentsModalDialog dialog) OVERRIDE {
38 dialog_state_[dialog] = HIDDEN;
40 virtual void CloseDialog(NativeWebContentsModalDialog dialog) OVERRIDE {
41 delegate_->WillClose(dialog);
42 dialog_state_[dialog] = CLOSED;
44 virtual void FocusDialog(NativeWebContentsModalDialog dialog) OVERRIDE {
46 virtual void PulseDialog(NativeWebContentsModalDialog dialog) OVERRIDE {
48 virtual void HostChanged(WebContentsModalDialogHost* new_host) OVERRIDE {
51 int GetCloseCount() const {
53 for (DialogStateMap::const_iterator it = dialog_state_.begin();
54 it != dialog_state_.end(); ++it) {
55 if (it->second == CLOSED)
61 DialogState GetDialogState(NativeWebContentsModalDialog dialog) const {
62 DialogStateMap::const_iterator loc = dialog_state_.find(dialog);
63 return loc == dialog_state_.end() ? UNKNOWN : loc->second;
67 typedef std::map<NativeWebContentsModalDialog, DialogState> DialogStateMap;
69 NativeWebContentsModalDialogManagerDelegate* delegate_;
70 DialogStateMap dialog_state_;
72 DISALLOW_COPY_AND_ASSIGN(TestNativeWebContentsModalDialogManager);
75 class WebContentsModalDialogManagerTest
76 : public content::RenderViewHostTestHarness {
78 WebContentsModalDialogManagerTest()
81 native_manager(NULL) {
84 virtual void SetUp() {
85 content::RenderViewHostTestHarness::SetUp();
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);
94 // |manager| owns |native_manager| as a result.
95 test_api->ResetNativeManager(native_manager);
98 virtual void TearDown() {
100 content::RenderViewHostTestHarness::TearDown();
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++);
112 scoped_ptr<TestWebContentsModalDialogManagerDelegate> delegate;
113 WebContentsModalDialogManager* manager;
114 scoped_ptr<WebContentsModalDialogManager::TestApi> test_api;
115 TestNativeWebContentsModalDialogManager* native_manager;
117 DISALLOW_COPY_AND_ASSIGN(WebContentsModalDialogManagerTest);
120 NativeWebContentsModalDialogManager*
121 WebContentsModalDialogManager::CreateNativeManager(
122 NativeWebContentsModalDialogManagerDelegate* native_delegate) {
123 return new TestNativeWebContentsModalDialogManager(native_delegate);
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();
132 manager->ShowDialog(dialog1);
134 EXPECT_EQ(TestNativeWebContentsModalDialogManager::SHOWN,
135 native_manager->GetDialogState(dialog1));
136 EXPECT_TRUE(manager->IsDialogActive());
137 EXPECT_TRUE(delegate->web_contents_blocked());
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);
146 const NativeWebContentsModalDialog dialog1 = MakeFakeDialog();
148 manager->ShowDialog(dialog1);
150 EXPECT_EQ(TestNativeWebContentsModalDialogManager::NOT_SHOWN,
151 native_manager->GetDialogState(dialog1));
152 EXPECT_TRUE(manager->IsDialogActive());
153 EXPECT_TRUE(delegate->web_contents_blocked());
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();
162 manager->ShowDialog(dialog1);
163 manager->ShowDialog(dialog2);
164 manager->ShowDialog(dialog3);
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));
175 // Test that the dialog is shown/hidden when the WebContents is shown/hidden.
176 TEST_F(WebContentsModalDialogManagerTest, VisibilityObservation) {
177 const NativeWebContentsModalDialog dialog1 = MakeFakeDialog();
179 manager->ShowDialog(dialog1);
181 EXPECT_TRUE(manager->IsDialogActive());
182 EXPECT_TRUE(delegate->web_contents_blocked());
183 EXPECT_EQ(TestNativeWebContentsModalDialogManager::SHOWN,
184 native_manager->GetDialogState(dialog1));
186 test_api->WebContentsWasHidden();
188 EXPECT_TRUE(manager->IsDialogActive());
189 EXPECT_TRUE(delegate->web_contents_blocked());
190 EXPECT_EQ(TestNativeWebContentsModalDialogManager::HIDDEN,
191 native_manager->GetDialogState(dialog1));
193 test_api->WebContentsWasShown();
195 EXPECT_TRUE(manager->IsDialogActive());
196 EXPECT_TRUE(delegate->web_contents_blocked());
197 EXPECT_EQ(TestNativeWebContentsModalDialogManager::SHOWN,
198 native_manager->GetDialogState(dialog1));
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();
207 manager->ShowDialog(dialog1);
208 manager->ShowDialog(dialog2);
209 manager->ShowDialog(dialog3);
211 #if defined(OS_WIN) || defined(USE_AURA)
212 manager->SetCloseOnInterstitialPage(dialog2, false);
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);
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));
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();
239 manager->ShowDialog(dialog1);
240 manager->ShowDialog(dialog2);
241 manager->ShowDialog(dialog3);
242 manager->ShowDialog(dialog4);
244 native_manager->CloseDialog(dialog1);
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));
257 native_manager->CloseDialog(dialog3);
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));
268 native_manager->CloseDialog(dialog2);
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));
277 native_manager->CloseDialog(dialog4);
279 EXPECT_FALSE(manager->IsDialogActive());
280 EXPECT_FALSE(delegate->web_contents_blocked());
281 EXPECT_EQ(TestNativeWebContentsModalDialogManager::CLOSED,
282 native_manager->GetDialogState(dialog4));
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());
291 EXPECT_EQ(0, native_manager->GetCloseCount());
293 test_api->CloseAllDialogs();
294 EXPECT_FALSE(delegate->web_contents_blocked());
295 EXPECT_FALSE(manager->IsDialogActive());
296 EXPECT_EQ(kWindowCount, native_manager->GetCloseCount());
299 } // namespace web_modal