[go: nahoru, domu]

blob: 82b6b96f0dc82d45aaff3be5e0528dc5c8a12e31 [file] [log] [blame]
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/shared/coordinator/alert/alert_coordinator.h"
#import <UIKit/UIKit.h>
#import "base/apple/foundation_util.h"
#import "base/test/task_environment.h"
#import "ios/chrome/browser/shared/model/browser/test/test_browser.h"
#import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h"
#import "ios/chrome/test/scoped_key_window.h"
#import "testing/gtest_mac.h"
#import "testing/platform_test.h"
#import "third_party/ocmock/OCMock/OCMock.h"
#import "third_party/ocmock/gtest_support.h"
#import "ui/base/l10n/l10n_util.h"
#import "ui/strings/grit/ui_strings.h"
#pragma mark - Fixture.
// Fixture to test AlertCoordinator.
class AlertCoordinatorTest : public PlatformTest {
protected:
AlertCoordinatorTest() {
browser_state_ = TestChromeBrowserState::Builder().Build();
browser_ = std::make_unique<TestBrowser>(browser_state_.get());
view_controller_ = [[UIViewController alloc] init];
[scoped_key_window_.Get() setRootViewController:view_controller_];
}
void StartAlertCoordinator() { [alert_coordinator_ start]; }
UIViewController* GetViewController() { return view_controller_; }
AlertCoordinator* GetAlertCoordinator(UIViewController* view_controller) {
return GetAlertCoordinator(view_controller, @"Test title", nil);
}
AlertCoordinator* GetAlertCoordinator(UIViewController* view_controller,
NSString* title,
NSString* message) {
alert_coordinator_ =
[[AlertCoordinator alloc] initWithBaseViewController:view_controller
browser:browser_.get()
title:title
message:message];
return alert_coordinator_;
}
void TearDown() override {
[alert_coordinator_ stop];
PlatformTest::TearDown();
}
private:
base::test::TaskEnvironment task_environment_;
std::unique_ptr<TestChromeBrowserState> browser_state_;
std::unique_ptr<TestBrowser> browser_;
AlertCoordinator* alert_coordinator_;
ScopedKeyWindow scoped_key_window_;
UIViewController* view_controller_;
};
#pragma mark - Tests.
// Tests the alert coordinator reports as visible after presenting and at least
// on button is created.
TEST_F(AlertCoordinatorTest, ValidateIsVisible) {
// Setup.
UIViewController* view_controller = GetViewController();
AlertCoordinator* alert_coordinator = GetAlertCoordinator(view_controller);
ASSERT_FALSE(alert_coordinator.visible);
EXPECT_NSEQ(nil, view_controller.presentedViewController);
// Action.
StartAlertCoordinator();
// Test.
EXPECT_TRUE(alert_coordinator.visible);
ASSERT_TRUE([view_controller.presentedViewController
isKindOfClass:[UIAlertController class]]);
UIAlertController* alert_controller =
base::apple::ObjCCastStrict<UIAlertController>(
view_controller.presentedViewController);
EXPECT_EQ(1LU, alert_controller.actions.count);
}
// Tests the alert coordinator reports as not visible after presenting on a non
// visible view.
TEST_F(AlertCoordinatorTest, ValidateIsNotVisible) {
// Setup.
UIWindow* window =
[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UIViewController* view_controller = [[UIViewController alloc] init];
[window setRootViewController:view_controller];
AlertCoordinator* alert_coordinator = GetAlertCoordinator(view_controller);
// Action.
StartAlertCoordinator();
// Test.
EXPECT_FALSE(alert_coordinator.visible);
EXPECT_NSEQ(nil, [view_controller presentedViewController]);
}
// Tests the alert coordinator has a correct title and message.
TEST_F(AlertCoordinatorTest, TitleAndMessage) {
// Setup.
UIViewController* view_controller = GetViewController();
NSString* title = @"Foo test title!";
NSString* message = @"Foo bar message.";
GetAlertCoordinator(view_controller, title, message);
// Action.
StartAlertCoordinator();
// Test.
// Get the alert.
ASSERT_TRUE([view_controller.presentedViewController
isKindOfClass:[UIAlertController class]]);
UIAlertController* alert_controller =
base::apple::ObjCCastStrict<UIAlertController>(
view_controller.presentedViewController);
// Test the results.
EXPECT_NSEQ(title, alert_controller.title);
EXPECT_NSEQ(message, alert_controller.message);
}
// Tests the alert coordinator dismissal.
TEST_F(AlertCoordinatorTest, ValidateDismissalOnStop) {
// Setup.
UIViewController* view_controller = GetViewController();
AlertCoordinator* alert_coordinator = GetAlertCoordinator(view_controller);
StartAlertCoordinator();
ASSERT_TRUE(alert_coordinator.visible);
ASSERT_NSNE(nil, view_controller.presentedViewController);
ASSERT_TRUE([view_controller.presentedViewController
isKindOfClass:[UIAlertController class]]);
id viewControllerMock = [OCMockObject partialMockForObject:view_controller];
[[[viewControllerMock expect] andForwardToRealObject]
dismissViewControllerAnimated:NO
completion:nil];
// Action.
[alert_coordinator stop];
// Test.
EXPECT_FALSE(alert_coordinator.visible);
EXPECT_OCMOCK_VERIFY(viewControllerMock);
}
// Tests that only the expected actions are present on the alert.
TEST_F(AlertCoordinatorTest, ValidateActions) {
// Setup.
UIViewController* view_controller = GetViewController();
AlertCoordinator* alert_coordinator = GetAlertCoordinator(view_controller);
NSDictionary* actions = @{
@"foo" : @(UIAlertActionStyleDestructive),
@"foo2" : @(UIAlertActionStyleDestructive),
@"bar" : @(UIAlertActionStyleDefault),
@"bar2" : @(UIAlertActionStyleDefault),
@"testCancel" : @(UIAlertActionStyleCancel),
};
NSMutableDictionary* remainingActions = [actions mutableCopy];
// Action.
for (id key in actions) {
UIAlertActionStyle style =
static_cast<UIAlertActionStyle>([actions[key] integerValue]);
[alert_coordinator addItemWithTitle:key action:nil style:style];
}
// Test.
// Present the alert.
StartAlertCoordinator();
// Get the alert.
ASSERT_TRUE([view_controller.presentedViewController
isKindOfClass:[UIAlertController class]]);
UIAlertController* alert_controller =
base::apple::ObjCCastStrict<UIAlertController>(
view_controller.presentedViewController);
// Test the results.
for (UIAlertAction* action in alert_controller.actions) {
EXPECT_TRUE([remainingActions objectForKey:action.title]);
UIAlertActionStyle style =
static_cast<UIAlertActionStyle>([actions[action.title] integerValue]);
EXPECT_EQ(style, action.style);
[remainingActions removeObjectForKey:action.title];
}
EXPECT_EQ(0LU, [remainingActions count]);
}
// Tests that only the first cancel action is added.
TEST_F(AlertCoordinatorTest, CancelIsRegistered) {
// Setup.
UIViewController* view_controller = GetViewController();
AlertCoordinator* alert_coordinator = GetAlertCoordinator(view_controller);
NSString* firstButtonTitle = @"Cancel1";
EXPECT_FALSE(alert_coordinator.cancelButtonAdded);
// Action.
[alert_coordinator addItemWithTitle:firstButtonTitle
action:nil
style:UIAlertActionStyleCancel];
EXPECT_TRUE(alert_coordinator.cancelButtonAdded);
//  If death test becomes available, check that adding a second cancel item
// lead to a CHECK failure.
}
// Tests that the `noInteractionAction` block is called for an alert coordinator
// which is stopped before the user has interacted with it.
TEST_F(AlertCoordinatorTest, NoInteractionActionTest) {
// Setup.
UIViewController* view_controller = GetViewController();
AlertCoordinator* alert_coordinator = GetAlertCoordinator(view_controller);
__block BOOL block_called = NO;
alert_coordinator.noInteractionAction = ^{
block_called = YES;
};
StartAlertCoordinator();
// Action.
[alert_coordinator stop];
// Test.
EXPECT_TRUE(block_called);
}
// Tests that the alert coordinator is dismissed if destroyed without being
// stopped.
TEST_F(AlertCoordinatorTest, AlertDismissedOnDestroy) {
// Setup.
UIViewController* view_controller = GetViewController();
AlertCoordinator* alert_coordinator = GetAlertCoordinator(view_controller);
ASSERT_FALSE(alert_coordinator.visible);
ASSERT_EQ(nil, view_controller.presentedViewController);
__block BOOL block_called = NO;
alert_coordinator.noInteractionAction = ^{
block_called = YES;
};
StartAlertCoordinator();
alert_coordinator = nil;
EXPECT_FALSE(block_called);
}
// Tests that the preferred item sets the preferred action.
TEST_F(AlertCoordinatorTest, AlertHasPreferredAction) {
// Setup.
UIViewController* view_controller = GetViewController();
AlertCoordinator* alert_coordinator = GetAlertCoordinator(view_controller);
NSString* firstButtonTitle = @"firstButtonTitle";
NSString* secondButtonTitle = @"secondButtonTitle";
NSString* thirdButtonTitle = @"thirdButtonTitle";
// Action.
[alert_coordinator addItemWithTitle:firstButtonTitle
action:nil
style:UIAlertActionStyleDefault];
[alert_coordinator addItemWithTitle:secondButtonTitle
action:nil
style:UIAlertActionStyleDefault
preferred:YES
enabled:NO];
[alert_coordinator addItemWithTitle:thirdButtonTitle
action:nil
style:UIAlertActionStyleDefault];
// Test.
// Present the alert.
StartAlertCoordinator();
// Get the alert.
ASSERT_TRUE([view_controller.presentedViewController
isKindOfClass:[UIAlertController class]]);
UIAlertController* alert_controller =
base::apple::ObjCCastStrict<UIAlertController>(
view_controller.presentedViewController);
// Test the results.
EXPECT_EQ(3LU, alert_controller.actions.count);
UIAlertAction* preferredAction = alert_controller.preferredAction;
EXPECT_NSEQ(secondButtonTitle, preferredAction.title);
EXPECT_EQ(UIAlertActionStyleDefault, preferredAction.style);
}