| Index: ios/chrome/browser/ui/dialogs/dialog_presenter_unittest.mm
|
| diff --git a/ios/chrome/browser/ui/dialogs/dialog_presenter_unittest.mm b/ios/chrome/browser/ui/dialogs/dialog_presenter_unittest.mm
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..8bebde7863078f195870d89695698f8f6e7d39c0
|
| --- /dev/null
|
| +++ b/ios/chrome/browser/ui/dialogs/dialog_presenter_unittest.mm
|
| @@ -0,0 +1,211 @@
|
| +// Copyright 2015 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#import "ios/chrome/browser/ui/dialogs/dialog_presenter.h"
|
| +
|
| +#import "base/mac/scoped_nsobject.h"
|
| +#include "base/time/time.h"
|
| +#import "ios/chrome/browser/ui/alert_coordinator/alert_coordinator.h"
|
| +#include "ios/web/public/test/test_web_state.h"
|
| +#include "ios/web/public/web_state/web_state_observer.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +#include "testing/gtest_mac.h"
|
| +#include "testing/platform_test.h"
|
| +#include "url/gurl.h"
|
| +
|
| +namespace {
|
| +// TestWebState subclass that supports the WebStateDestroyed() callback for a
|
| +// single observer.
|
| +class DialogPresenterTestWebState : public web::TestWebState {
|
| + public:
|
| + DialogPresenterTestWebState() : web::TestWebState(), observer_(nullptr) {}
|
| + ~DialogPresenterTestWebState() override {
|
| + if (observer_)
|
| + observer_->WebStateDestroyed();
|
| + }
|
| +
|
| + protected:
|
| + // WebState overrides.
|
| + void AddObserver(web::WebStateObserver* observer) override {
|
| + // Currently, only one observer is supported.
|
| + ASSERT_EQ(observer_, nullptr);
|
| + observer_ = observer;
|
| + }
|
| +
|
| + private:
|
| + web::WebStateObserver* observer_;
|
| +};
|
| +} // namespace
|
| +
|
| +@interface TestDialogPresenterDelegate : NSObject<DialogPresenterDelegate> {
|
| + std::vector<web::WebState*> _presentedWebStates;
|
| +}
|
| +// The web states for the dialogs that have been presented.
|
| +@property(nonatomic, readonly) std::vector<web::WebState*> presentedWebStates;
|
| +@end
|
| +
|
| +@implementation TestDialogPresenterDelegate
|
| +@synthesize presenting = _presenting;
|
| +
|
| +- (std::vector<web::WebState*>)presentedWebStates {
|
| + return _presentedWebStates;
|
| +}
|
| +
|
| +- (void)dialogPresenter:(DialogPresenter*)presenter
|
| + willShowDialogForWebState:(web::WebState*)webState {
|
| + _presentedWebStates.push_back(webState);
|
| +}
|
| +
|
| +@end
|
| +
|
| +class DialogPresenterTest : public PlatformTest {
|
| + protected:
|
| + DialogPresenterTest()
|
| + : delegate_([[TestDialogPresenterDelegate alloc] init]),
|
| + viewController_([[UIViewController alloc] init]),
|
| + presenter_([[DialogPresenter alloc] initWithDelegate:delegate_
|
| + presentingViewController:viewController_]) {
|
| + [presenter_ setActive:YES];
|
| + }
|
| + ~DialogPresenterTest() override {
|
| + [[presenter_ presentedDialogCoordinator] stop];
|
| + }
|
| +
|
| + TestDialogPresenterDelegate* delegate() { return delegate_; }
|
| + UIViewController* viewController() { return viewController_; }
|
| + DialogPresenter* presenter() { return presenter_; }
|
| +
|
| + private:
|
| + base::scoped_nsobject<TestDialogPresenterDelegate> delegate_;
|
| + base::scoped_nsobject<UIViewController> viewController_;
|
| + base::scoped_nsobject<DialogPresenter> presenter_;
|
| +};
|
| +
|
| +// Tests that a dialog was successfully shown and that the delegate was notified
|
| +// with the correct context.
|
| +TEST_F(DialogPresenterTest, SimpleTest) {
|
| + DialogPresenterTestWebState webState;
|
| + [presenter() runJavaScriptAlertPanelWithMessage:@""
|
| + requestURL:GURL()
|
| + webState:&webState
|
| + completionHandler:nil];
|
| + EXPECT_EQ(1U, delegate().presentedWebStates.size());
|
| + EXPECT_EQ(&webState, delegate().presentedWebStates.front());
|
| +}
|
| +
|
| +// Tests that multiple JavaScript dialogs are queued
|
| +TEST_F(DialogPresenterTest, QueueTest) {
|
| + // Tests that the dialog for |webState1| has been shown.
|
| + DialogPresenterTestWebState webState1;
|
| + [presenter() runJavaScriptAlertPanelWithMessage:@""
|
| + requestURL:GURL()
|
| + webState:&webState1
|
| + completionHandler:nil];
|
| + EXPECT_EQ(1U, delegate().presentedWebStates.size());
|
| + EXPECT_EQ(&webState1, delegate().presentedWebStates.front());
|
| + // Attempt to present another dialog for |webState2|, and verify that only
|
| + // |webState2| has been shown.
|
| + DialogPresenterTestWebState webState2;
|
| + [presenter() runJavaScriptAlertPanelWithMessage:@""
|
| + requestURL:GURL()
|
| + webState:&webState2
|
| + completionHandler:nil];
|
| + EXPECT_EQ(1U, delegate().presentedWebStates.size());
|
| + EXPECT_EQ(&webState1, delegate().presentedWebStates.front());
|
| + // Dismiss the dialog for |webState1| and call the confirm handler to trigger
|
| + // showing the dialog for |webState2|.
|
| + [presenter().presentedDialogCoordinator stop];
|
| + [presenter()
|
| + buttonWasTappedForCoordinator:presenter().presentedDialogCoordinator];
|
| + EXPECT_EQ(2U, delegate().presentedWebStates.size());
|
| + EXPECT_EQ(&webState1, delegate().presentedWebStates.front());
|
| + EXPECT_EQ(&webState2, delegate().presentedWebStates.back());
|
| +}
|
| +
|
| +// Tests that cancelling a queued JavaScript dialog will call its completion
|
| +// handler.
|
| +TEST_F(DialogPresenterTest, CancelTest) {
|
| + // Show a dialog for |webState1| and enqueue a dialog for |webState2|.
|
| + DialogPresenterTestWebState webState1;
|
| + [presenter() runJavaScriptAlertPanelWithMessage:@""
|
| + requestURL:GURL()
|
| + webState:&webState1
|
| + completionHandler:nil];
|
| + DialogPresenterTestWebState webState2;
|
| + __block BOOL completion_called = NO;
|
| + [presenter() runJavaScriptAlertPanelWithMessage:@""
|
| + requestURL:GURL()
|
| + webState:&webState2
|
| + completionHandler:^() {
|
| + completion_called = YES;
|
| + }];
|
| + EXPECT_EQ(1U, delegate().presentedWebStates.size());
|
| + EXPECT_EQ(&webState1, delegate().presentedWebStates.front());
|
| + // Cancel the dialog for |webState2| and verify that |completion_called| was
|
| + // reset.
|
| + [presenter() cancelDialogForWebState:&webState2];
|
| + EXPECT_TRUE(completion_called);
|
| +}
|
| +
|
| +// Tests that if the delegate is presenting, the alert is showed only when
|
| +// notified.
|
| +TEST_F(DialogPresenterTest, DelegatePresenting) {
|
| + // Tests that the dialog is not shown if the delegate is presenting.
|
| + DialogPresenterTestWebState webState1;
|
| + delegate().presenting = YES;
|
| + [presenter() runJavaScriptAlertPanelWithMessage:@""
|
| + requestURL:GURL()
|
| + webState:&webState1
|
| + completionHandler:nil];
|
| + EXPECT_EQ(0U, delegate().presentedWebStates.size());
|
| + [presenter() tryToPresent];
|
| + EXPECT_EQ(0U, delegate().presentedWebStates.size());
|
| +
|
| + // The delegate is not presenting anymore, the dialog is not shown yet.
|
| + delegate().presenting = NO;
|
| + EXPECT_EQ(0U, delegate().presentedWebStates.size());
|
| +
|
| + // Notify the presenter that it can present.
|
| + [presenter() tryToPresent];
|
| + EXPECT_EQ(1U, delegate().presentedWebStates.size());
|
| + EXPECT_EQ(&webState1, delegate().presentedWebStates.front());
|
| +}
|
| +
|
| +// Tests that cancelling all queued JavaScript dialogs will call all completion
|
| +// handlers.
|
| +TEST_F(DialogPresenterTest, CancelAllTest) {
|
| + // Show a dialog for |context1| and enqueue a dialog for |context2| and
|
| + // |context3|.
|
| + DialogPresenterTestWebState webState1;
|
| + __block BOOL completion1_called = NO;
|
| + [presenter() runJavaScriptAlertPanelWithMessage:@"1"
|
| + requestURL:GURL()
|
| + webState:&webState1
|
| + completionHandler:^() {
|
| + completion1_called = YES;
|
| + }];
|
| + DialogPresenterTestWebState webState2;
|
| + __block BOOL completion2_called = NO;
|
| + [presenter() runJavaScriptAlertPanelWithMessage:@"2"
|
| + requestURL:GURL()
|
| + webState:&webState2
|
| + completionHandler:^() {
|
| + completion2_called = YES;
|
| + }];
|
| + DialogPresenterTestWebState webState3;
|
| + __block BOOL completion3_called = NO;
|
| + [presenter() runJavaScriptAlertPanelWithMessage:@"3"
|
| + requestURL:GURL()
|
| + webState:&webState3
|
| + completionHandler:^() {
|
| + completion3_called = YES;
|
| + }];
|
| + EXPECT_EQ(1U, delegate().presentedWebStates.size());
|
| + EXPECT_EQ(&webState1, delegate().presentedWebStates.front());
|
| + // Cancel all dialogs and verify that all |completion_called| were called.
|
| + [presenter() cancelAllDialogs];
|
| + EXPECT_TRUE(completion1_called);
|
| + EXPECT_TRUE(completion2_called);
|
| + EXPECT_TRUE(completion3_called);
|
| +}
|
|
|