OLD | NEW |
(Empty) | |
| 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. |
| 4 |
| 5 #import "ios/chrome/browser/ui/dialogs/dialog_presenter.h" |
| 6 |
| 7 #import "base/mac/scoped_nsobject.h" |
| 8 #include "base/time/time.h" |
| 9 #import "ios/chrome/browser/ui/alert_coordinator/alert_coordinator.h" |
| 10 #include "ios/web/public/test/test_web_state.h" |
| 11 #include "ios/web/public/web_state/web_state_observer.h" |
| 12 #include "testing/gtest/include/gtest/gtest.h" |
| 13 #include "testing/gtest_mac.h" |
| 14 #include "testing/platform_test.h" |
| 15 #include "url/gurl.h" |
| 16 |
| 17 namespace { |
| 18 // TestWebState subclass that supports the WebStateDestroyed() callback for a |
| 19 // single observer. |
| 20 class DialogPresenterTestWebState : public web::TestWebState { |
| 21 public: |
| 22 DialogPresenterTestWebState() : web::TestWebState(), observer_(nullptr) {} |
| 23 ~DialogPresenterTestWebState() override { |
| 24 if (observer_) |
| 25 observer_->WebStateDestroyed(); |
| 26 } |
| 27 |
| 28 protected: |
| 29 // WebState overrides. |
| 30 void AddObserver(web::WebStateObserver* observer) override { |
| 31 // Currently, only one observer is supported. |
| 32 ASSERT_EQ(observer_, nullptr); |
| 33 observer_ = observer; |
| 34 } |
| 35 |
| 36 private: |
| 37 web::WebStateObserver* observer_; |
| 38 }; |
| 39 } // namespace |
| 40 |
| 41 @interface TestDialogPresenterDelegate : NSObject<DialogPresenterDelegate> { |
| 42 std::vector<web::WebState*> _presentedWebStates; |
| 43 } |
| 44 // The web states for the dialogs that have been presented. |
| 45 @property(nonatomic, readonly) std::vector<web::WebState*> presentedWebStates; |
| 46 @end |
| 47 |
| 48 @implementation TestDialogPresenterDelegate |
| 49 @synthesize presenting = _presenting; |
| 50 |
| 51 - (std::vector<web::WebState*>)presentedWebStates { |
| 52 return _presentedWebStates; |
| 53 } |
| 54 |
| 55 - (void)dialogPresenter:(DialogPresenter*)presenter |
| 56 willShowDialogForWebState:(web::WebState*)webState { |
| 57 _presentedWebStates.push_back(webState); |
| 58 } |
| 59 |
| 60 @end |
| 61 |
| 62 class DialogPresenterTest : public PlatformTest { |
| 63 protected: |
| 64 DialogPresenterTest() |
| 65 : delegate_([[TestDialogPresenterDelegate alloc] init]), |
| 66 viewController_([[UIViewController alloc] init]), |
| 67 presenter_([[DialogPresenter alloc] initWithDelegate:delegate_ |
| 68 presentingViewController:viewController_]) { |
| 69 [presenter_ setActive:YES]; |
| 70 } |
| 71 ~DialogPresenterTest() override { |
| 72 [[presenter_ presentedDialogCoordinator] stop]; |
| 73 } |
| 74 |
| 75 TestDialogPresenterDelegate* delegate() { return delegate_; } |
| 76 UIViewController* viewController() { return viewController_; } |
| 77 DialogPresenter* presenter() { return presenter_; } |
| 78 |
| 79 private: |
| 80 base::scoped_nsobject<TestDialogPresenterDelegate> delegate_; |
| 81 base::scoped_nsobject<UIViewController> viewController_; |
| 82 base::scoped_nsobject<DialogPresenter> presenter_; |
| 83 }; |
| 84 |
| 85 // Tests that a dialog was successfully shown and that the delegate was notified |
| 86 // with the correct context. |
| 87 TEST_F(DialogPresenterTest, SimpleTest) { |
| 88 DialogPresenterTestWebState webState; |
| 89 [presenter() runJavaScriptAlertPanelWithMessage:@"" |
| 90 requestURL:GURL() |
| 91 webState:&webState |
| 92 completionHandler:nil]; |
| 93 EXPECT_EQ(1U, delegate().presentedWebStates.size()); |
| 94 EXPECT_EQ(&webState, delegate().presentedWebStates.front()); |
| 95 } |
| 96 |
| 97 // Tests that multiple JavaScript dialogs are queued |
| 98 TEST_F(DialogPresenterTest, QueueTest) { |
| 99 // Tests that the dialog for |webState1| has been shown. |
| 100 DialogPresenterTestWebState webState1; |
| 101 [presenter() runJavaScriptAlertPanelWithMessage:@"" |
| 102 requestURL:GURL() |
| 103 webState:&webState1 |
| 104 completionHandler:nil]; |
| 105 EXPECT_EQ(1U, delegate().presentedWebStates.size()); |
| 106 EXPECT_EQ(&webState1, delegate().presentedWebStates.front()); |
| 107 // Attempt to present another dialog for |webState2|, and verify that only |
| 108 // |webState2| has been shown. |
| 109 DialogPresenterTestWebState webState2; |
| 110 [presenter() runJavaScriptAlertPanelWithMessage:@"" |
| 111 requestURL:GURL() |
| 112 webState:&webState2 |
| 113 completionHandler:nil]; |
| 114 EXPECT_EQ(1U, delegate().presentedWebStates.size()); |
| 115 EXPECT_EQ(&webState1, delegate().presentedWebStates.front()); |
| 116 // Dismiss the dialog for |webState1| and call the confirm handler to trigger |
| 117 // showing the dialog for |webState2|. |
| 118 [presenter().presentedDialogCoordinator stop]; |
| 119 [presenter() |
| 120 buttonWasTappedForCoordinator:presenter().presentedDialogCoordinator]; |
| 121 EXPECT_EQ(2U, delegate().presentedWebStates.size()); |
| 122 EXPECT_EQ(&webState1, delegate().presentedWebStates.front()); |
| 123 EXPECT_EQ(&webState2, delegate().presentedWebStates.back()); |
| 124 } |
| 125 |
| 126 // Tests that cancelling a queued JavaScript dialog will call its completion |
| 127 // handler. |
| 128 TEST_F(DialogPresenterTest, CancelTest) { |
| 129 // Show a dialog for |webState1| and enqueue a dialog for |webState2|. |
| 130 DialogPresenterTestWebState webState1; |
| 131 [presenter() runJavaScriptAlertPanelWithMessage:@"" |
| 132 requestURL:GURL() |
| 133 webState:&webState1 |
| 134 completionHandler:nil]; |
| 135 DialogPresenterTestWebState webState2; |
| 136 __block BOOL completion_called = NO; |
| 137 [presenter() runJavaScriptAlertPanelWithMessage:@"" |
| 138 requestURL:GURL() |
| 139 webState:&webState2 |
| 140 completionHandler:^() { |
| 141 completion_called = YES; |
| 142 }]; |
| 143 EXPECT_EQ(1U, delegate().presentedWebStates.size()); |
| 144 EXPECT_EQ(&webState1, delegate().presentedWebStates.front()); |
| 145 // Cancel the dialog for |webState2| and verify that |completion_called| was |
| 146 // reset. |
| 147 [presenter() cancelDialogForWebState:&webState2]; |
| 148 EXPECT_TRUE(completion_called); |
| 149 } |
| 150 |
| 151 // Tests that if the delegate is presenting, the alert is showed only when |
| 152 // notified. |
| 153 TEST_F(DialogPresenterTest, DelegatePresenting) { |
| 154 // Tests that the dialog is not shown if the delegate is presenting. |
| 155 DialogPresenterTestWebState webState1; |
| 156 delegate().presenting = YES; |
| 157 [presenter() runJavaScriptAlertPanelWithMessage:@"" |
| 158 requestURL:GURL() |
| 159 webState:&webState1 |
| 160 completionHandler:nil]; |
| 161 EXPECT_EQ(0U, delegate().presentedWebStates.size()); |
| 162 [presenter() tryToPresent]; |
| 163 EXPECT_EQ(0U, delegate().presentedWebStates.size()); |
| 164 |
| 165 // The delegate is not presenting anymore, the dialog is not shown yet. |
| 166 delegate().presenting = NO; |
| 167 EXPECT_EQ(0U, delegate().presentedWebStates.size()); |
| 168 |
| 169 // Notify the presenter that it can present. |
| 170 [presenter() tryToPresent]; |
| 171 EXPECT_EQ(1U, delegate().presentedWebStates.size()); |
| 172 EXPECT_EQ(&webState1, delegate().presentedWebStates.front()); |
| 173 } |
| 174 |
| 175 // Tests that cancelling all queued JavaScript dialogs will call all completion |
| 176 // handlers. |
| 177 TEST_F(DialogPresenterTest, CancelAllTest) { |
| 178 // Show a dialog for |context1| and enqueue a dialog for |context2| and |
| 179 // |context3|. |
| 180 DialogPresenterTestWebState webState1; |
| 181 __block BOOL completion1_called = NO; |
| 182 [presenter() runJavaScriptAlertPanelWithMessage:@"1" |
| 183 requestURL:GURL() |
| 184 webState:&webState1 |
| 185 completionHandler:^() { |
| 186 completion1_called = YES; |
| 187 }]; |
| 188 DialogPresenterTestWebState webState2; |
| 189 __block BOOL completion2_called = NO; |
| 190 [presenter() runJavaScriptAlertPanelWithMessage:@"2" |
| 191 requestURL:GURL() |
| 192 webState:&webState2 |
| 193 completionHandler:^() { |
| 194 completion2_called = YES; |
| 195 }]; |
| 196 DialogPresenterTestWebState webState3; |
| 197 __block BOOL completion3_called = NO; |
| 198 [presenter() runJavaScriptAlertPanelWithMessage:@"3" |
| 199 requestURL:GURL() |
| 200 webState:&webState3 |
| 201 completionHandler:^() { |
| 202 completion3_called = YES; |
| 203 }]; |
| 204 EXPECT_EQ(1U, delegate().presentedWebStates.size()); |
| 205 EXPECT_EQ(&webState1, delegate().presentedWebStates.front()); |
| 206 // Cancel all dialogs and verify that all |completion_called| were called. |
| 207 [presenter() cancelAllDialogs]; |
| 208 EXPECT_TRUE(completion1_called); |
| 209 EXPECT_TRUE(completion2_called); |
| 210 EXPECT_TRUE(completion3_called); |
| 211 } |
OLD | NEW |