blob: a8e67931b33ab64d1d12e101c1281d70d8447b43 [file] [log] [blame]
// Copyright 2020 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/menu/action_factory.h"
#import "base/test/metrics/histogram_tester.h"
#import "base/test/task_environment.h"
#import "ios/chrome/browser/main/test_browser.h"
#import "ios/chrome/browser/sessions/test_session_service.h"
#import "ios/chrome/browser/ui/commands/application_commands.h"
#import "ios/chrome/browser/ui/commands/command_dispatcher.h"
#import "ios/chrome/browser/ui/menu/menu_action_type.h"
#import "ios/chrome/browser/ui/menu/menu_histograms.h"
#import "ios/chrome/grit/ios_strings.h"
#import "testing/gmock/include/gmock/gmock.h"
#import "testing/gtest/include/gtest/gtest.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_mac.h"
#import "ui/base/test/ios/ui_image_test_utils.h"
#import "url/gurl.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
MenuScenario kTestMenuScenario = MenuScenario::kHistoryEntry;
} // namespace
// Test fixture for the ActionFactory.
class ActionFactoryTest : public PlatformTest {
protected:
ActionFactoryTest()
: test_title_(@"SomeTitle"),
test_browser_(std::make_unique<TestBrowser>()) {}
void SetUp() override {
mock_application_commands_handler_ =
OCMStrictProtocolMock(@protocol(ApplicationCommands));
[test_browser_->GetCommandDispatcher()
startDispatchingToTarget:mock_application_commands_handler_
forProtocol:@protocol(ApplicationCommands)];
mock_application_settings_commands_handler_ =
OCMStrictProtocolMock(@protocol(ApplicationSettingsCommands));
[test_browser_->GetCommandDispatcher()
startDispatchingToTarget:mock_application_settings_commands_handler_
forProtocol:@protocol(ApplicationSettingsCommands)];
}
// Creates a blue square.
UIImage* CreateMockImage() {
return ui::test::uiimage_utils::UIImageWithSizeAndSolidColor(
CGSizeMake(10, 10), [UIColor blueColor]);
}
base::test::TaskEnvironment task_environment_;
base::HistogramTester histogram_tester_;
NSString* test_title_;
std::unique_ptr<TestBrowser> test_browser_;
id mock_application_commands_handler_;
id mock_application_settings_commands_handler_;
};
// Tests the creation of an action using the parameterized method, and verifies
// that the action has the right title and image.
TEST_F(ActionFactoryTest, CreateActionWithParameters) {
if (@available(iOS 13.0, *)) {
ActionFactory* factory =
[[ActionFactory alloc] initWithBrowser:test_browser_.get()
scenario:kTestMenuScenario];
UIImage* mockImage = CreateMockImage();
UIAction* action = [factory actionWithTitle:test_title_
image:mockImage
type:MenuActionType::Copy
block:^{
}];
EXPECT_TRUE([test_title_ isEqualToString:action.title]);
EXPECT_EQ(mockImage, action.image);
}
}
// Tests that the copy action has the right title and image.
TEST_F(ActionFactoryTest, CopyAction) {
if (@available(iOS 13.0, *)) {
ActionFactory* factory =
[[ActionFactory alloc] initWithBrowser:test_browser_.get()
scenario:kTestMenuScenario];
UIImage* expectedImage = [UIImage imageNamed:@"copy_link_url"];
NSString* expectedTitle =
l10n_util::GetNSString(IDS_IOS_COPY_LINK_ACTION_TITLE);
GURL testURL = GURL("https://example.com");
UIAction* action = [factory actionToCopyURL:testURL];
EXPECT_TRUE([expectedTitle isEqualToString:action.title]);
EXPECT_EQ(expectedImage, action.image);
}
}
// Tests that the share action has the right title and image.
TEST_F(ActionFactoryTest, ShareAction) {
if (@available(iOS 13.0, *)) {
ActionFactory* factory =
[[ActionFactory alloc] initWithBrowser:test_browser_.get()
scenario:kTestMenuScenario];
UIImage* expectedImage = [UIImage imageNamed:@"share"];
NSString* expectedTitle =
l10n_util::GetNSString(IDS_IOS_SHARE_BUTTON_LABEL);
UIAction* action = [factory actionToShareWithBlock:^{
}];
EXPECT_TRUE([expectedTitle isEqualToString:action.title]);
EXPECT_EQ(expectedImage, action.image);
}
}
// Tests that the delete action has the right title and image.
TEST_F(ActionFactoryTest, DeleteAction) {
if (@available(iOS 13.0, *)) {
ActionFactory* factory =
[[ActionFactory alloc] initWithBrowser:test_browser_.get()
scenario:kTestMenuScenario];
UIImage* expectedImage = [UIImage imageNamed:@"delete"];
NSString* expectedTitle =
l10n_util::GetNSString(IDS_IOS_DELETE_ACTION_TITLE);
UIAction* action = [factory actionToDeleteWithBlock:^{
}];
EXPECT_TRUE([expectedTitle isEqualToString:action.title]);
EXPECT_EQ(expectedImage, action.image);
EXPECT_EQ(UIMenuElementAttributesDestructive, action.attributes);
}
}
// Tests that the Open in New Tab actions have the right titles and images.
TEST_F(ActionFactoryTest, OpenInNewTabAction_URL) {
if (@available(iOS 13.0, *)) {
ActionFactory* factory =
[[ActionFactory alloc] initWithBrowser:test_browser_.get()
scenario:kTestMenuScenario];
GURL testURL = GURL("https://example.com");
UIImage* expectedImage = [UIImage imageNamed:@"open_in_new_tab"];
NSString* expectedTitle =
l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWTAB);
UIAction* actionWithURL = [factory actionToOpenInNewTabWithURL:testURL
completion:nil];
EXPECT_TRUE([expectedTitle isEqualToString:actionWithURL.title]);
EXPECT_EQ(expectedImage, actionWithURL.image);
UIAction* actionWithBlock = [factory actionToOpenInNewTabWithBlock:nil];
EXPECT_TRUE([expectedTitle isEqualToString:actionWithBlock.title]);
EXPECT_EQ(expectedImage, actionWithBlock.image);
}
}
// Tests that the Open in New Incognito Tab actions have the right titles
// and images.
TEST_F(ActionFactoryTest, OpenInNewIncognitoTabAction_URL) {
if (@available(iOS 13.0, *)) {
ActionFactory* factory =
[[ActionFactory alloc] initWithBrowser:test_browser_.get()
scenario:kTestMenuScenario];
GURL testURL = GURL("https://example.com");
UIImage* expectedImage = [UIImage imageNamed:@"open_in_incognito"];
NSString* expectedTitle =
l10n_util::GetNSString(IDS_IOS_OPEN_IN_INCOGNITO_ACTION_TITLE);
UIAction* actionWithURL =
[factory actionToOpenInNewIncognitoTabWithURL:testURL completion:nil];
EXPECT_TRUE([expectedTitle isEqualToString:actionWithURL.title]);
EXPECT_EQ(expectedImage, actionWithURL.image);
UIAction* actionWithBlock =
[factory actionToOpenInNewIncognitoTabWithBlock:nil];
EXPECT_TRUE([expectedTitle isEqualToString:actionWithBlock.title]);
EXPECT_EQ(expectedImage, actionWithBlock.image);
}
}
// Tests that the Open in New Window action has the right title and image.
TEST_F(ActionFactoryTest, OpenInNewWindowAction) {
if (@available(iOS 13.0, *)) {
ActionFactory* factory =
[[ActionFactory alloc] initWithBrowser:test_browser_.get()
scenario:kTestMenuScenario];
GURL testURL = GURL("https://example.com");
UIImage* expectedImage = [UIImage imageNamed:@"open_new_window"];
NSString* expectedTitle =
l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_OPENINNEWWINDOW);
UIAction* action =
[factory actionToOpenInNewWindowWithURL:testURL
activityOrigin:WindowActivityToolsOrigin];
EXPECT_TRUE([expectedTitle isEqualToString:action.title]);
EXPECT_EQ(expectedImage, action.image);
}
}
// Tests that the remove action has the right title and image.
TEST_F(ActionFactoryTest, RemoveAction) {
if (@available(iOS 13.0, *)) {
ActionFactory* factory =
[[ActionFactory alloc] initWithBrowser:test_browser_.get()
scenario:kTestMenuScenario];
UIImage* expectedImage = [UIImage imageNamed:@"remove"];
NSString* expectedTitle =
l10n_util::GetNSString(IDS_IOS_REMOVE_ACTION_TITLE);
UIAction* action = [factory actionToRemoveWithBlock:^{
}];
EXPECT_TRUE([expectedTitle isEqualToString:action.title]);
EXPECT_EQ(expectedImage, action.image);
}
}
// Tests that the edit action has the right title and image.
TEST_F(ActionFactoryTest, EditAction) {
if (@available(iOS 13.0, *)) {
ActionFactory* factory =
[[ActionFactory alloc] initWithBrowser:test_browser_.get()
scenario:kTestMenuScenario];
UIImage* expectedImage = [UIImage imageNamed:@"edit"];
NSString* expectedTitle = l10n_util::GetNSString(IDS_IOS_EDIT_ACTION_TITLE);
UIAction* action = [factory actionToEditWithBlock:^{
}];
EXPECT_TRUE([expectedTitle isEqualToString:action.title]);
EXPECT_EQ(expectedImage, action.image);
}
}
// Tests that the Open All Tabs action has the right title and image.
TEST_F(ActionFactoryTest, openAllTabsAction) {
if (@available(iOS 13.0, *)) {
ActionFactory* factory =
[[ActionFactory alloc] initWithBrowser:test_browser_.get()
scenario:kTestMenuScenario];
UIImage* expectedImage = [UIImage systemImageNamed:@"plus"];
NSString* expectedTitle =
l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_OPEN_ALL_LINKS);
UIAction* action = [factory actionToOpenAllTabsWithBlock:^{
}];
EXPECT_TRUE([expectedTitle isEqualToString:action.title]);
EXPECT_EQ(expectedImage, action.image);
}
}
// Tests that the hide action has the right title and image.
TEST_F(ActionFactoryTest, hideAction) {
if (@available(iOS 13.0, *)) {
ActionFactory* factory =
[[ActionFactory alloc] initWithBrowser:test_browser_.get()
scenario:kTestMenuScenario];
UIImage* expectedImage = [UIImage imageNamed:@"remove"];
NSString* expectedTitle =
l10n_util::GetNSString(IDS_IOS_RECENT_TABS_HIDE_MENU_OPTION);
UIAction* action = [factory actionToHideWithBlock:^{
}];
EXPECT_TRUE([expectedTitle isEqualToString:action.title]);
EXPECT_EQ(expectedImage, action.image);
}
}
// Tests that the Move Folder action has the right title and image.
TEST_F(ActionFactoryTest, MoveFolderAction) {
if (@available(iOS 13.0, *)) {
ActionFactory* factory =
[[ActionFactory alloc] initWithBrowser:test_browser_.get()
scenario:kTestMenuScenario];
UIImage* expectedImage = [UIImage imageNamed:@"move_folder"];
NSString* expectedTitle =
l10n_util::GetNSString(IDS_IOS_BOOKMARK_CONTEXT_MENU_MOVE);
UIAction* action = [factory actionToMoveFolderWithBlock:^{
}];
EXPECT_TRUE([expectedTitle isEqualToString:action.title]);
EXPECT_EQ(expectedImage, action.image);
}
}
// Tests that the Mark As Read action has the right title and image.
TEST_F(ActionFactoryTest, markAsReadAction) {
if (@available(iOS 13.0, *)) {
ActionFactory* factory =
[[ActionFactory alloc] initWithBrowser:test_browser_.get()
scenario:kTestMenuScenario];
UIImage* expectedImage = [UIImage imageNamed:@"mark_read"];
NSString* expectedTitle =
l10n_util::GetNSString(IDS_IOS_READING_LIST_MARK_AS_READ_ACTION);
UIAction* action = [factory actionToMarkAsReadWithBlock:^{
}];
EXPECT_TRUE([expectedTitle isEqualToString:action.title]);
EXPECT_EQ(expectedImage, action.image);
}
}
// Tests that the Mark As Unread action has the right title and image.
TEST_F(ActionFactoryTest, markAsUnreadAction) {
if (@available(iOS 13.0, *)) {
ActionFactory* factory =
[[ActionFactory alloc] initWithBrowser:test_browser_.get()
scenario:kTestMenuScenario];
UIImage* expectedImage = [UIImage imageNamed:@"remove"];
NSString* expectedTitle =
l10n_util::GetNSString(IDS_IOS_READING_LIST_MARK_AS_UNREAD_ACTION);
UIAction* action = [factory actionToMarkAsUnreadWithBlock:^{
}];
EXPECT_TRUE([expectedTitle isEqualToString:action.title]);
EXPECT_EQ(expectedImage, action.image);
}
}
// Tests that the View Offline Version in New Tab action has the right title and
// image.
TEST_F(ActionFactoryTest, viewOfflineVersion) {
if (@available(iOS 13.0, *)) {
ActionFactory* factory =
[[ActionFactory alloc] initWithBrowser:test_browser_.get()
scenario:kTestMenuScenario];
UIImage* expectedImage = [UIImage imageNamed:@"offline"];
NSString* expectedTitle =
l10n_util::GetNSString(IDS_IOS_READING_LIST_OPEN_OFFLINE_BUTTON);
UIAction* action = [factory actionToOpenOfflineVersionInNewTabWithBlock:^{
}];
EXPECT_TRUE([expectedTitle isEqualToString:action.title]);
EXPECT_EQ(expectedImage, action.image);
}
}
// Tests that the Open with JavaScript evaluation has have the right titles and
// image.
TEST_F(ActionFactoryTest, OpenWithJavaScript) {
if (@available(iOS 13.0, *)) {
ActionFactory* factory =
[[ActionFactory alloc] initWithBrowser:test_browser_.get()
scenario:kTestMenuScenario];
UIImage* expectedImage = [UIImage imageNamed:@"open"];
NSString* expectedTitle =
l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_OPEN);
UIAction* actionWithBlock = [factory actionToOpenJavascriptWithBlock:^{
}];
EXPECT_TRUE([expectedTitle isEqualToString:actionWithBlock.title]);
EXPECT_EQ(expectedImage, actionWithBlock.image);
}
}