OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
| 5 #include <map> |
| 6 |
| 7 #include "base/memory/scoped_ptr.h" |
5 #include "components/web_modal/native_web_contents_modal_dialog_manager.h" | 8 #include "components/web_modal/native_web_contents_modal_dialog_manager.h" |
6 #include "components/web_modal/web_contents_modal_dialog_manager.h" | 9 #include "components/web_modal/web_contents_modal_dialog_manager.h" |
| 10 #include "components/web_modal/web_contents_modal_dialog_manager_delegate.h" |
| 11 #include "content/public/browser/notification_details.h" |
| 12 #include "content/public/browser/notification_service.h" |
| 13 #include "content/public/browser/notification_source.h" |
| 14 #include "content/public/browser/notification_types.h" |
7 #include "content/public/test/test_renderer_host.h" | 15 #include "content/public/test/test_renderer_host.h" |
8 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
9 | 17 |
10 namespace web_modal { | 18 namespace web_modal { |
11 | 19 |
12 class WebContentsModalDialogManagerTest | 20 class TestNativeWebContentsModalDialogManager |
13 : public content::RenderViewHostTestHarness { | |
14 public: | |
15 virtual void SetUp() { | |
16 content::RenderViewHostTestHarness::SetUp(); | |
17 WebContentsModalDialogManager::CreateForWebContents(web_contents()); | |
18 } | |
19 }; | |
20 | |
21 class NativeWebContentsModalDialogManagerCloseTest | |
22 : public NativeWebContentsModalDialogManager { | 21 : public NativeWebContentsModalDialogManager { |
23 public: | 22 public: |
24 explicit NativeWebContentsModalDialogManagerCloseTest( | 23 enum DialogState { |
| 24 UNKNOWN, |
| 25 NOT_SHOWN, |
| 26 SHOWN, |
| 27 HIDDEN, |
| 28 CLOSED |
| 29 }; |
| 30 |
| 31 explicit TestNativeWebContentsModalDialogManager( |
25 NativeWebContentsModalDialogManagerDelegate* delegate) | 32 NativeWebContentsModalDialogManagerDelegate* delegate) |
26 : close_count_(0), delegate_(delegate) {} | 33 : delegate_(delegate) {} |
27 virtual void ManageDialog(NativeWebContentsModalDialog dialog) OVERRIDE { | 34 virtual void ManageDialog(NativeWebContentsModalDialog dialog) OVERRIDE { |
| 35 dialog_state_[dialog] = NOT_SHOWN; |
28 } | 36 } |
29 virtual void ShowDialog(NativeWebContentsModalDialog dialog) OVERRIDE { | 37 virtual void ShowDialog(NativeWebContentsModalDialog dialog) OVERRIDE { |
| 38 dialog_state_[dialog] = SHOWN; |
30 } | 39 } |
31 virtual void HideDialog(NativeWebContentsModalDialog dialog) OVERRIDE { | 40 virtual void HideDialog(NativeWebContentsModalDialog dialog) OVERRIDE { |
| 41 dialog_state_[dialog] = HIDDEN; |
32 } | 42 } |
33 virtual void CloseDialog(NativeWebContentsModalDialog dialog) OVERRIDE { | 43 virtual void CloseDialog(NativeWebContentsModalDialog dialog) OVERRIDE { |
34 delegate_->WillClose(dialog); | 44 delegate_->WillClose(dialog); |
35 ++close_count_; | 45 dialog_state_[dialog] = CLOSED; |
36 } | 46 } |
37 virtual void FocusDialog(NativeWebContentsModalDialog dialog) OVERRIDE { | 47 virtual void FocusDialog(NativeWebContentsModalDialog dialog) OVERRIDE { |
38 } | 48 } |
39 virtual void PulseDialog(NativeWebContentsModalDialog dialog) OVERRIDE { | 49 virtual void PulseDialog(NativeWebContentsModalDialog dialog) OVERRIDE { |
40 } | 50 } |
41 virtual void HostChanged(WebContentsModalDialogHost* new_host) OVERRIDE { | 51 virtual void HostChanged(WebContentsModalDialogHost* new_host) OVERRIDE { |
42 } | 52 } |
43 | 53 |
44 int close_count() const { return close_count_; } | 54 int GetCloseCount() const { |
| 55 int count = 0; |
| 56 for (DialogStateMap::const_iterator it = dialog_state_.begin(); |
| 57 it != dialog_state_.end(); ++it) { |
| 58 if (it->second == CLOSED) |
| 59 count++; |
| 60 } |
| 61 return count; |
| 62 } |
| 63 |
| 64 DialogState GetDialogState(NativeWebContentsModalDialog dialog) const { |
| 65 DialogStateMap::const_iterator loc = dialog_state_.find(dialog); |
| 66 return loc == dialog_state_.end() ? UNKNOWN : loc->second; |
| 67 } |
45 | 68 |
46 private: | 69 private: |
47 int close_count_; | 70 typedef std::map<NativeWebContentsModalDialog, DialogState> DialogStateMap; |
| 71 |
48 NativeWebContentsModalDialogManagerDelegate* delegate_; | 72 NativeWebContentsModalDialogManagerDelegate* delegate_; |
49 | 73 DialogStateMap dialog_state_; |
50 DISALLOW_COPY_AND_ASSIGN(NativeWebContentsModalDialogManagerCloseTest); | 74 |
| 75 DISALLOW_COPY_AND_ASSIGN(TestNativeWebContentsModalDialogManager); |
| 76 }; |
| 77 |
| 78 class TestWebContentsModalDialogManagerDelegate |
| 79 : public WebContentsModalDialogManagerDelegate { |
| 80 public: |
| 81 TestWebContentsModalDialogManagerDelegate() |
| 82 : web_contents_visible_(true), |
| 83 web_contents_blocked_(false) { |
| 84 } |
| 85 |
| 86 // WebContentsModalDialogManagerDelegate overrides |
| 87 virtual void SetWebContentsBlocked(content::WebContents* web_contents, |
| 88 bool blocked) OVERRIDE { |
| 89 web_contents_blocked_ = blocked; |
| 90 } |
| 91 |
| 92 virtual WebContentsModalDialogHost* GetWebContentsModalDialogHost() OVERRIDE { |
| 93 return NULL; |
| 94 } |
| 95 |
| 96 virtual bool IsWebContentsVisible( |
| 97 content::WebContents* web_contents) OVERRIDE { |
| 98 return web_contents_visible_; |
| 99 } |
| 100 |
| 101 void set_web_contents_visible(bool visible) { |
| 102 web_contents_visible_ = visible; |
| 103 } |
| 104 |
| 105 bool web_contents_blocked() const { return web_contents_blocked_; } |
| 106 |
| 107 private: |
| 108 bool web_contents_visible_; |
| 109 bool web_contents_blocked_; |
| 110 |
| 111 DISALLOW_COPY_AND_ASSIGN(TestWebContentsModalDialogManagerDelegate); |
| 112 }; |
| 113 |
| 114 class WebContentsModalDialogManagerTest |
| 115 : public content::RenderViewHostTestHarness { |
| 116 public: |
| 117 WebContentsModalDialogManagerTest() |
| 118 : next_dialog_id(1), |
| 119 manager(NULL), |
| 120 native_manager(NULL) { |
| 121 } |
| 122 |
| 123 virtual void SetUp() { |
| 124 content::RenderViewHostTestHarness::SetUp(); |
| 125 |
| 126 delegate.reset(new TestWebContentsModalDialogManagerDelegate); |
| 127 WebContentsModalDialogManager::CreateForWebContents(web_contents()); |
| 128 manager = WebContentsModalDialogManager::FromWebContents(web_contents()); |
| 129 manager->SetDelegate(delegate.get()); |
| 130 test_api.reset(new WebContentsModalDialogManager::TestApi(manager)); |
| 131 native_manager = new TestNativeWebContentsModalDialogManager(manager); |
| 132 |
| 133 // |manager| owns |native_manager| as a result. |
| 134 test_api->ResetNativeManager(native_manager); |
| 135 } |
| 136 |
| 137 virtual void TearDown() { |
| 138 test_api.reset(); |
| 139 content::RenderViewHostTestHarness::TearDown(); |
| 140 } |
| 141 |
| 142 protected: |
| 143 NativeWebContentsModalDialog MakeFakeDialog() { |
| 144 // WebContentsModalDialogManager treats the NativeWebContentsModalDialog as |
| 145 // an opaque type, so creating fake NativeWebContentsModalDialogs using |
| 146 // reinterpret_cast is valid. |
| 147 return reinterpret_cast<NativeWebContentsModalDialog>(next_dialog_id++); |
| 148 } |
| 149 |
| 150 int next_dialog_id; |
| 151 scoped_ptr<TestWebContentsModalDialogManagerDelegate> delegate; |
| 152 WebContentsModalDialogManager* manager; |
| 153 scoped_ptr<WebContentsModalDialogManager::TestApi> test_api; |
| 154 TestNativeWebContentsModalDialogManager* native_manager; |
| 155 |
| 156 DISALLOW_COPY_AND_ASSIGN(WebContentsModalDialogManagerTest); |
51 }; | 157 }; |
52 | 158 |
53 NativeWebContentsModalDialogManager* | 159 NativeWebContentsModalDialogManager* |
54 WebContentsModalDialogManager::CreateNativeManager( | 160 WebContentsModalDialogManager::CreateNativeManager( |
55 NativeWebContentsModalDialogManagerDelegate* native_delegate) { | 161 NativeWebContentsModalDialogManagerDelegate* native_delegate) { |
56 return new NativeWebContentsModalDialogManagerCloseTest(native_delegate); | 162 return new TestNativeWebContentsModalDialogManager(native_delegate); |
57 } | 163 } |
58 | 164 |
59 TEST_F(WebContentsModalDialogManagerTest, WebContentsModalDialogs) { | 165 // Test that the dialog is shown immediately when the delegate indicates the web |
60 WebContentsModalDialogManager* web_contents_modal_dialog_manager = | 166 // contents is visible. |
61 WebContentsModalDialogManager::FromWebContents(web_contents()); | 167 TEST_F(WebContentsModalDialogManagerTest, WebContentsVisible) { |
62 WebContentsModalDialogManager::TestApi test_api( | 168 // Dialog should be shown while WebContents is visible. |
63 web_contents_modal_dialog_manager); | 169 const NativeWebContentsModalDialog dialog1 = MakeFakeDialog(); |
64 | 170 |
65 NativeWebContentsModalDialogManagerCloseTest* native_manager = | 171 manager->ShowDialog(dialog1); |
66 new NativeWebContentsModalDialogManagerCloseTest( | 172 |
67 web_contents_modal_dialog_manager); | 173 EXPECT_EQ(TestNativeWebContentsModalDialogManager::SHOWN, |
68 | 174 native_manager->GetDialogState(dialog1)); |
69 // |web_contents_modal_dialog_manager| owns |native_manager| as a result. | 175 EXPECT_TRUE(manager->IsShowingDialog()); |
70 test_api.ResetNativeManager(native_manager); | 176 EXPECT_TRUE(delegate->web_contents_blocked()); |
71 | 177 } |
| 178 |
| 179 // Test that the dialog is not shown immediately when the delegate indicates the |
| 180 // web contents is not visible. |
| 181 TEST_F(WebContentsModalDialogManagerTest, WebContentsNotVisible) { |
| 182 // Dialog should not be shown while WebContents is not visible. |
| 183 delegate->set_web_contents_visible(false); |
| 184 |
| 185 const NativeWebContentsModalDialog dialog1 = MakeFakeDialog(); |
| 186 |
| 187 manager->ShowDialog(dialog1); |
| 188 |
| 189 EXPECT_EQ(TestNativeWebContentsModalDialogManager::NOT_SHOWN, |
| 190 native_manager->GetDialogState(dialog1)); |
| 191 EXPECT_TRUE(manager->IsShowingDialog()); |
| 192 EXPECT_TRUE(delegate->web_contents_blocked()); |
| 193 } |
| 194 |
| 195 // Test that only the first of multiple dialogs is shown. |
| 196 TEST_F(WebContentsModalDialogManagerTest, ShowDialogs) { |
| 197 const NativeWebContentsModalDialog dialog1 = MakeFakeDialog(); |
| 198 const NativeWebContentsModalDialog dialog2 = MakeFakeDialog(); |
| 199 const NativeWebContentsModalDialog dialog3 = MakeFakeDialog(); |
| 200 |
| 201 manager->ShowDialog(dialog1); |
| 202 manager->ShowDialog(dialog2); |
| 203 manager->ShowDialog(dialog3); |
| 204 |
| 205 EXPECT_TRUE(delegate->web_contents_blocked()); |
| 206 EXPECT_EQ(TestNativeWebContentsModalDialogManager::SHOWN, |
| 207 native_manager->GetDialogState(dialog1)); |
| 208 EXPECT_EQ(TestNativeWebContentsModalDialogManager::NOT_SHOWN, |
| 209 native_manager->GetDialogState(dialog2)); |
| 210 EXPECT_EQ(TestNativeWebContentsModalDialogManager::NOT_SHOWN, |
| 211 native_manager->GetDialogState(dialog3)); |
| 212 } |
| 213 |
| 214 // Test that the dialog is shown/hidden on |
| 215 // NOTIFICATION_WEB_CONTENTS_VISIBILITY_CHANGED. |
| 216 TEST_F(WebContentsModalDialogManagerTest, VisibilityObservation) { |
| 217 const NativeWebContentsModalDialog dialog1 = MakeFakeDialog(); |
| 218 bool web_contents_visible = true; |
| 219 |
| 220 manager->ShowDialog(dialog1); |
| 221 |
| 222 EXPECT_TRUE(manager->IsShowingDialog()); |
| 223 EXPECT_TRUE(delegate->web_contents_blocked()); |
| 224 EXPECT_EQ(TestNativeWebContentsModalDialogManager::SHOWN, |
| 225 native_manager->GetDialogState(dialog1)); |
| 226 |
| 227 web_contents_visible = false; |
| 228 manager->Observe(content::NOTIFICATION_WEB_CONTENTS_VISIBILITY_CHANGED, |
| 229 content::NotificationService::AllSources(), |
| 230 content::Details<bool>(&web_contents_visible)); |
| 231 |
| 232 EXPECT_TRUE(manager->IsShowingDialog()); |
| 233 EXPECT_TRUE(delegate->web_contents_blocked()); |
| 234 EXPECT_EQ(TestNativeWebContentsModalDialogManager::HIDDEN, |
| 235 native_manager->GetDialogState(dialog1)); |
| 236 |
| 237 web_contents_visible = true; |
| 238 manager->Observe(content::NOTIFICATION_WEB_CONTENTS_VISIBILITY_CHANGED, |
| 239 content::NotificationService::AllSources(), |
| 240 content::Details<bool>(&web_contents_visible)); |
| 241 |
| 242 EXPECT_TRUE(manager->IsShowingDialog()); |
| 243 EXPECT_TRUE(delegate->web_contents_blocked()); |
| 244 EXPECT_EQ(TestNativeWebContentsModalDialogManager::SHOWN, |
| 245 native_manager->GetDialogState(dialog1)); |
| 246 } |
| 247 |
| 248 // Test that the first dialog is always shown, regardless of the order in which |
| 249 // dialogs are closed. |
| 250 TEST_F(WebContentsModalDialogManagerTest, CloseDialogs) { |
| 251 // The front dialog is always shown regardless of dialog close order. |
| 252 const NativeWebContentsModalDialog dialog1 = MakeFakeDialog(); |
| 253 const NativeWebContentsModalDialog dialog2 = MakeFakeDialog(); |
| 254 const NativeWebContentsModalDialog dialog3 = MakeFakeDialog(); |
| 255 const NativeWebContentsModalDialog dialog4 = MakeFakeDialog(); |
| 256 |
| 257 manager->ShowDialog(dialog1); |
| 258 manager->ShowDialog(dialog2); |
| 259 manager->ShowDialog(dialog3); |
| 260 manager->ShowDialog(dialog4); |
| 261 |
| 262 native_manager->CloseDialog(dialog1); |
| 263 |
| 264 EXPECT_TRUE(manager->IsShowingDialog()); |
| 265 EXPECT_TRUE(delegate->web_contents_blocked()); |
| 266 EXPECT_EQ(TestNativeWebContentsModalDialogManager::CLOSED, |
| 267 native_manager->GetDialogState(dialog1)); |
| 268 EXPECT_EQ(TestNativeWebContentsModalDialogManager::SHOWN, |
| 269 native_manager->GetDialogState(dialog2)); |
| 270 EXPECT_EQ(TestNativeWebContentsModalDialogManager::NOT_SHOWN, |
| 271 native_manager->GetDialogState(dialog3)); |
| 272 EXPECT_EQ(TestNativeWebContentsModalDialogManager::NOT_SHOWN, |
| 273 native_manager->GetDialogState(dialog4)); |
| 274 |
| 275 native_manager->CloseDialog(dialog3); |
| 276 |
| 277 EXPECT_TRUE(manager->IsShowingDialog()); |
| 278 EXPECT_TRUE(delegate->web_contents_blocked()); |
| 279 EXPECT_EQ(TestNativeWebContentsModalDialogManager::SHOWN, |
| 280 native_manager->GetDialogState(dialog2)); |
| 281 EXPECT_EQ(TestNativeWebContentsModalDialogManager::CLOSED, |
| 282 native_manager->GetDialogState(dialog3)); |
| 283 EXPECT_EQ(TestNativeWebContentsModalDialogManager::NOT_SHOWN, |
| 284 native_manager->GetDialogState(dialog4)); |
| 285 |
| 286 native_manager->CloseDialog(dialog2); |
| 287 |
| 288 EXPECT_TRUE(manager->IsShowingDialog()); |
| 289 EXPECT_TRUE(delegate->web_contents_blocked()); |
| 290 EXPECT_EQ(TestNativeWebContentsModalDialogManager::CLOSED, |
| 291 native_manager->GetDialogState(dialog2)); |
| 292 EXPECT_EQ(TestNativeWebContentsModalDialogManager::SHOWN, |
| 293 native_manager->GetDialogState(dialog4)); |
| 294 |
| 295 native_manager->CloseDialog(dialog4); |
| 296 |
| 297 EXPECT_FALSE(manager->IsShowingDialog()); |
| 298 EXPECT_FALSE(delegate->web_contents_blocked()); |
| 299 EXPECT_EQ(TestNativeWebContentsModalDialogManager::CLOSED, |
| 300 native_manager->GetDialogState(dialog4)); |
| 301 } |
| 302 |
| 303 // Test that CloseAllDialogs does what it says. |
| 304 TEST_F(WebContentsModalDialogManagerTest, CloseAllDialogs) { |
72 const int kWindowCount = 4; | 305 const int kWindowCount = 4; |
73 for (int i = 0; i < kWindowCount; i++) { | 306 for (int i = 0; i < kWindowCount; i++) |
74 // WebContentsModalDialogManager treats the NativeWebContentsModalDialog as | 307 manager->ShowDialog(MakeFakeDialog()); |
75 // an opaque type, so creating fake NativeWebContentsModalDialogs using | 308 |
76 // reinterpret_cast is valid. | 309 EXPECT_EQ(0, native_manager->GetCloseCount()); |
77 web_contents_modal_dialog_manager->ShowDialog( | 310 |
78 reinterpret_cast<NativeWebContentsModalDialog>(i)); | 311 test_api->CloseAllDialogs(); |
79 } | 312 EXPECT_FALSE(delegate->web_contents_blocked()); |
80 EXPECT_EQ(0, native_manager->close_count()); | 313 EXPECT_FALSE(manager->IsShowingDialog()); |
81 | 314 EXPECT_EQ(kWindowCount, native_manager->GetCloseCount()); |
82 test_api.CloseAllDialogs(); | |
83 EXPECT_EQ(kWindowCount, native_manager->close_count()); | |
84 } | 315 } |
85 | 316 |
86 } // namespace web_modal | 317 } // namespace web_modal |
OLD | NEW |