// Copyright 2023 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/browser_content/ui_bundled/browser_edit_menu_handler.h"

#import "base/test/ios/wait_util.h"
#import "base/test/scoped_feature_list.h"
#import "components/search_engines/template_url_service.h"
#import "ios/chrome/browser/browser_content/ui_bundled/browser_content_view_controller.h"
#import "ios/chrome/browser/enterprise/data_controls/model/data_controls_edit_menu_builder.h"
#import "ios/chrome/browser/enterprise/data_controls/model/data_controls_tab_helper.h"
#import "ios/chrome/browser/enterprise/data_controls/model/data_controls_test_utils.h"
#import "ios/chrome/browser/intelligence/features/features.h"
#import "ios/chrome/browser/link_to_text/ui_bundled/link_to_text_mediator.h"
#import "ios/chrome/browser/partial_translate/ui_bundled/partial_translate_mediator.h"
#import "ios/chrome/browser/search_engines/model/template_url_service_factory.h"
#import "ios/chrome/browser/search_with/ui_bundled/search_with_mediator.h"
#import "ios/chrome/browser/shared/model/profile/test/test_profile_ios.h"
#import "ios/chrome/browser/shared/public/commands/scene_commands.h"
#import "ios/chrome/browser/shared/public/features/features.h"
#import "ios/chrome/browser/web/model/chrome_web_client.h"
#import "ios/chrome/browser/web_selection/model/web_selection_tab_helper.h"
#import "ios/chrome/test/ios_chrome_scoped_testing_local_state.h"
#import "ios/chrome/test/providers/partial_translate/test_partial_translate.h"
#import "ios/chrome/test/scoped_key_window.h"
#import "ios/web/public/test/scoped_testing_web_client.h"
#import "ios/web/public/test/web_state_test_util.h"
#import "ios/web/public/test/web_task_environment.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/device_form_factor.h"

@interface SearchWithMediator (Testing)
- (NSString*)buttonTitle;
@end

namespace {

// The template for Google search engine.
const char kGoogleSearchTemplate[] = "https://www.google.com/?q={searchTerms}";

// Creates a recursive string description of `menuElement`.
// Each array element is a string "depth:type:id" with
// - depth: the depth of the node in the submenus trees
// - type: "a" for action, "c" for command, "m" for submenu, "u" for others
// - id: an id (dependant on the type).
NSArray* MenuDescription(UIMenuElement* menuElement, int indent) {
  if ([menuElement isKindOfClass:[UIAction class]]) {
    UIAction* action = (UIAction*)menuElement;
    return
        @[ [NSString stringWithFormat:@"%d:a:%@", indent, action.identifier] ];
  }
  if ([menuElement isKindOfClass:[UICommand class]]) {
    UICommand* command = (UICommand*)menuElement;
    return
        @[ [NSString stringWithFormat:@"%d:c:%@", indent,
                                      NSStringFromSelector(command.action)] ];
  }
  if ([menuElement isKindOfClass:[UIDeferredMenuElement class]]) {
    // It is not possible to have info from UIDeferredMenuElement as they
    // are only a block.
    return @[ [NSString stringWithFormat:@"%d:d", indent] ];
  }
  if ([menuElement isKindOfClass:[UIMenu class]]) {
    UIMenu* menu = (UIMenu*)menuElement;
    NSMutableArray* array = [NSMutableArray
        arrayWithObject:[NSString stringWithFormat:@"%d:m:%@", indent,
                                                   menu.identifier]];
    for (UIMenuElement* child in menu.children) {
      [array addObjectsFromArray:MenuDescription(child, indent + 1)];
    }
    return array;
  }
  return @[ [NSString
      stringWithFormat:@"%d:u:%@", indent, menuElement.description] ];
}

NSString* const kPageHTML = @"<html>"
                             "  <body>"
                             "    This is a simple HTML file."
                             "  </body>"
                             "</html>";

// Return the base menu depending on the environment.
NSMutableArray* GetExpectedMenu() {
  if (@available(iOS 27, *)) {
    return [NSMutableArray arrayWithArray:@[
      @"0:m:com.apple.menu.standard-edit",
      @"1:c:cut:",
      @"1:c:copy:",
      @"1:c:paste:",
      @"1:c:delete:",
      @"1:c:select:",
      @"1:c:selectAll:",
      @"0:m:com.apple.menu.replace",
      @"1:c:promptForReplace:",
      @"1:c:transliterateChinese:",
      @"1:c:_insertDrawing:",
      @"1:c:showWritingTools:",
      @"1:m:com.apple.menu.autofill",
      @"2:m:com.apple.menu.insert-from-external-sources",
      @"2:c:captureTextFromCamera:",
      @"0:m:com.apple.menu.open",
      @"0:m:com.apple.menu.format",
      @"1:m:com.apple.menu.text-style",
      @"2:c:toggleBoldface:",
      @"2:c:toggleItalics:",
      @"2:c:toggleUnderline:",
      @"1:m:com.apple.menu.writing-direction",
      @"2:c:makeTextWritingDirectionRightToLeft:",
      @"2:c:makeTextWritingDirectionLeftToRight:",
      @"1:c:_showTextFormattingOptions:",
      @"0:m:com.apple.menu.lookup",
      @"1:c:_define:",
      @"1:c:_translate:",
      @"1:c:findSelected:",
      @"0:m:com.apple.menu.learn",
      @"1:c:addShortcut:",
      @"0:m:com.apple.command.speech",
      @"1:c:_accessibilitySpeak:",
      @"1:c:_accessibilitySpeakLanguageSelection:",
      @"1:c:_accessibilityPauseSpeaking:",
      @"0:m:com.apple.menu.share",
      @"1:c:share:"
    ]];
  } else if (@available(iOS 18.1, *)) {
    return [NSMutableArray arrayWithArray:@[
      @"0:m:com.apple.menu.standard-edit",
      @"1:c:cut:",
      @"1:c:copy:",
      @"1:c:paste:",
      @"1:c:delete:",
      @"1:c:select:",
      @"1:c:selectAll:",
      @"0:m:com.apple.menu.replace",
      @"1:c:promptForReplace:",
      @"1:c:transliterateChinese:",
      @"1:c:_insertDrawing:",
      @"1:c:showWritingTools:",
      @"1:m:com.apple.menu.autofill",
      @"2:m:com.apple.menu.insert-from-external-sources",
      @"2:c:captureTextFromCamera:",
      @"0:m:com.apple.menu.open",
      @"0:m:com.apple.menu.format",
      @"1:m:com.apple.menu.text-style",
      @"2:c:toggleBoldface:",
      @"2:c:toggleItalics:",
      @"2:c:toggleUnderline:",
      @"1:m:com.apple.menu.writing-direction",
      @"2:c:makeTextWritingDirectionRightToLeft:",
      @"2:c:makeTextWritingDirectionLeftToRight:",
      @"1:c:_showTextFormattingOptions:",
      @"0:m:com.apple.menu.lookup",
      @"1:c:findSelected:",
      @"1:c:_define:",
      @"1:c:_translate:",
      @"0:m:com.apple.menu.learn",
      @"1:c:addShortcut:",
      @"0:m:com.apple.command.speech",
      @"1:c:_accessibilitySpeak:",
      @"1:c:_accessibilitySpeakLanguageSelection:",
      @"1:c:_accessibilityPauseSpeaking:",
      @"0:m:com.apple.menu.share",
      @"1:c:share:"
    ]];
  } else if (@available(iOS 18, *)) {
    return [NSMutableArray arrayWithArray:@[
      @"0:m:com.apple.menu.standard-edit",
      @"1:c:cut:",
      @"1:c:copy:",
      @"1:c:paste:",
      @"1:c:delete:",
      @"1:c:select:",
      @"1:c:selectAll:",
      @"0:m:com.apple.menu.replace",
      @"1:c:promptForReplace:",
      @"1:c:transliterateChinese:",
      @"1:c:_insertDrawing:",
      @"1:m:com.apple.menu.autofill",
      @"2:m:com.apple.menu.insert-from-external-sources",
      @"2:c:captureTextFromCamera:",
      @"1:c:_startWritingTools:",
      @"0:m:com.apple.menu.open",
      @"0:m:com.apple.menu.format",
      @"1:m:com.apple.menu.text-style",
      @"2:c:toggleBoldface:",
      @"2:c:toggleItalics:",
      @"2:c:toggleUnderline:",
      @"1:m:com.apple.menu.writing-direction",
      @"2:c:makeTextWritingDirectionRightToLeft:",
      @"2:c:makeTextWritingDirectionLeftToRight:",
      @"1:c:_showTextFormattingOptions:",
      @"0:m:com.apple.menu.lookup",
      @"1:c:findSelected:",
      @"1:c:_define:",
      @"1:c:_translate:",
      @"0:m:com.apple.menu.learn",
      @"1:c:addShortcut:",
      @"0:m:com.apple.command.speech",
      @"1:c:_accessibilitySpeak:",
      @"1:c:_accessibilitySpeakLanguageSelection:",
      @"1:c:_accessibilityPauseSpeaking:",
      @"0:m:com.apple.menu.share",
      @"1:c:share:"
    ]];
  } else if (@available(iOS 17.4, *)) {
    return [NSMutableArray arrayWithArray:@[
      @"0:m:com.apple.menu.standard-edit",
      @"1:c:cut:",
      @"1:c:copy:",
      @"1:c:paste:",
      @"1:c:delete:",
      @"1:c:select:",
      @"1:c:selectAll:",
      @"0:m:com.apple.menu.replace",
      @"1:c:promptForReplace:",
      @"1:c:transliterateChinese:",
      @"1:c:_insertDrawing:",
      @"1:m:com.apple.menu.autofill",
      @"2:m:com.apple.menu.insert-from-external-sources",
      @"2:c:captureTextFromCamera:",
      @"0:m:com.apple.menu.open",
      @"0:m:com.apple.menu.format",
      @"1:m:com.apple.menu.text-style",
      @"2:c:toggleBoldface:",
      @"2:c:toggleItalics:",
      @"2:c:toggleUnderline:",
      @"1:m:com.apple.menu.writing-direction",
      @"2:c:makeTextWritingDirectionRightToLeft:",
      @"2:c:makeTextWritingDirectionLeftToRight:",
      @"1:c:_showTextFormattingOptions:",
      @"0:m:com.apple.menu.lookup",
      @"1:c:findSelected:",
      @"1:c:_define:",
      @"1:c:_translate:",
      @"0:m:com.apple.menu.learn",
      @"1:c:addShortcut:",
      @"0:m:com.apple.command.speech",
      @"1:c:_accessibilitySpeak:",
      @"1:c:_accessibilitySpeakLanguageSelection:",
      @"1:c:_accessibilityPauseSpeaking:",
      @"0:m:com.apple.menu.share",
      @"1:c:share:"
    ]];
  }
  NSMutableArray* expectedMenuDescription = [NSMutableArray arrayWithArray:@[
    @"0:m:com.apple.menu.standard-edit",
    @"1:c:cut:",
    @"1:c:copy:",
    @"1:c:paste:",
    @"1:c:delete:",
    @"1:c:select:",
    @"1:c:selectAll:",
    @"0:m:com.apple.menu.replace",
    @"1:c:_promptForReplace:",
    @"1:c:_transliterateChinese:",
    @"1:c:_insertDrawing:",
    @"1:m:com.apple.menu.autofill",
    @"2:m:com.apple.menu.insert-from-external-sources",
    @"2:c:captureTextFromCamera:",
    @"0:m:com.apple.menu.open",
    @"0:m:com.apple.menu.format",
    @"1:m:com.apple.menu.text-style",
    @"2:c:toggleBoldface:",
    @"2:c:toggleItalics:",
    @"2:c:toggleUnderline:",
    @"1:m:com.apple.menu.writing-direction",
    @"2:c:makeTextWritingDirectionRightToLeft:",
    @"2:c:makeTextWritingDirectionLeftToRight:",
    @"1:c:_showTextFormattingOptions:",
    @"0:m:com.apple.menu.lookup",
    @"1:c:_findSelected:",
    @"1:c:_define:",
    @"1:c:_translate:",
    @"0:m:com.apple.menu.learn",
    @"1:c:_addShortcut:",
    @"0:m:com.apple.command.speech",
    @"1:c:_accessibilitySpeak:",
    @"1:c:_accessibilitySpeakLanguageSelection:",
    @"1:c:_accessibilityPauseSpeaking:",
    @"0:m:com.apple.menu.share",
    @"1:c:_share:"
  ]];

  return expectedMenuDescription;
}

// Add Open In New Canvas on iPad
void AddOpenInNewCanvas(NSMutableArray* menu) {
  if (ui::GetDeviceFormFactor() != ui::DEVICE_FORM_FACTOR_TABLET) {
    return;
  }
  for (unsigned int i = 0; i < menu.count; i++) {
    if ([menu[i] isEqualToString:@"0:m:com.apple.menu.format"]) {
      [menu insertObject:@"1:c:_openInNewCanvas:" atIndex:i];
      return;
    }
  }
}

// Modify the expected menu for chrome menu
void AddChromeMenu(NSMutableArray* menu) {
  for (unsigned int i = 0; i < menu.count; i++) {
    if ([menu[i] isEqualToString:@"0:m:com.apple.menu.lookup"]) {
      [menu insertObject:@"0:m:chromecommand.menu" atIndex:i];
      if (ShouldShowEditMenuItemsSynchronously()) {
        [menu insertObject:@"1:a:chromeAction.searchWith" atIndex:i + 1];
        [menu insertObject:@"1:a:chromecommand.partialTranslate" atIndex:i + 2];
      } else {
        // Deferred action.
        [menu insertObject:@"1:d" atIndex:i + 1];
        [menu insertObject:@"1:d" atIndex:i + 1];
      }
      break;
    }
  }
  // Remove the default translate.
  for (unsigned int i = 0; i < menu.count; i++) {
    if ([menu[i] isEqualToString:@"1:c:_translate:"]) {
      [menu removeObjectAtIndex:i];
      break;
    }
  }
}

// Modify the expected menu for Link to text
void AddLinkToText(NSMutableArray* menu) {
  [menu addObjectsFromArray:@[ @"0:m:chromecommand.menu.linktotext", @"1:d" ]];
}

// Modify the expected menu to remove Share items.
void RemoveShareMenu(NSMutableArray* menu) {
  for (NSInteger i = menu.count - 1; i >= 0; --i) {
    NSString* item = menu[i];
    if ([item hasPrefix:@"0:m:com.apple.menu.share"] ||
        [item hasPrefix:@"1:c:share:"] || [item hasPrefix:@"1:c:_share:"]) {
      [menu removeObjectAtIndex:i];
    }
  }
}
}  // namespace

// A test View controller that forwards the edit menu handling.
@interface TestViewController : UIViewController
@property(nonatomic, weak) BrowserEditMenuHandler* handler;

@property(nonatomic, assign) web::WebState* webState;
@end

@implementation TestViewController

- (void)buildMenuWithBuilder:(id<UIMenuBuilder>)builder {
  [super buildMenuWithBuilder:builder];
  [self.handler buildEditMenuWithBuilder:builder inWebState:self.webState];
}

@end

// A fake partial translate provider.
@interface TestPartialTranslateControllerFactory
    : NSObject <PartialTranslateControllerFactory>
@end

@implementation TestPartialTranslateControllerFactory

- (id<PartialTranslateController>)
    createTranslateControllerForSourceText:(NSString*)sourceText
                                anchorRect:(CGRect)anchor
                               inIncognito:(BOOL)inIncognito {
  return nil;
}

- (NSUInteger)maximumCharacterLimit {
  return 1100;
}

@end

// A delegate used to intercept the menu of the webView.
@interface EditMenuInteractionDelegate
    : NSObject <UIEditMenuInteractionDelegate>
@property(nonatomic, copy) NSArray* menuDescription;
@end

@implementation EditMenuInteractionDelegate

- (UIMenu*)editMenuInteraction:(UIEditMenuInteraction*)interaction
          menuForConfiguration:(UIEditMenuConfiguration*)configuration
              suggestedActions:(NSArray<UIMenuElement*>*)suggestedActions {
  NSMutableArray* descriptions = [NSMutableArray array];
  for (UIMenuElement* element in suggestedActions) {
    [descriptions addObjectsFromArray:MenuDescription(element, 0)];
  }
  self.menuDescription = descriptions;
  // Returning nil will fail the menu presentation.
  return nil;
}

@end

// Tests that the structure of the edit menu stays the same starting with iOS16.
// These are purposed to catch future changes in the menu.
class BrowserEditMenuHandlerTest : public PlatformTest {
 public:
  BrowserEditMenuHandlerTest()
      : web_client_(std::make_unique<ChromeWebClient>()) {
    TestProfileIOS::Builder test_profile_builder;
    test_profile_builder.AddTestingFactory(
        ios::TemplateURLServiceFactory::GetInstance(),
        ios::TemplateURLServiceFactory::GetDefaultFactory());
    profile_ = std::move(test_profile_builder).Build();

    web::WebState::CreateParams params(profile_.get());
    web_state_ = web::WebState::Create(params);

    WebSelectionTabHelper::CreateForWebState(web_state_.get());
    data_controls::DataControlsTabHelper::CreateForWebState(web_state_.get());
  }

  void SetUp() override {
    PlatformTest::SetUp();
    base_view_controller_ = [[TestViewController alloc] init];
    base_view_controller_.webState = web_state_.get();
    [scoped_key_window_.Get() setRootViewController:base_view_controller_];
  }

  void TearDown() override {
    base_view_controller_.webState = nullptr;
    // Reset the partial translate factory
    ios::provider::test::SetPartialTranslateControllerFactory(nil);
    PlatformTest::TearDown();
  }

  void SetupTranslateControllerFactory() {
    TestPartialTranslateControllerFactory* factory =
        [[TestPartialTranslateControllerFactory alloc] init];
    ios::provider::test::SetPartialTranslateControllerFactory(factory);
  }

  NSArray* GetMenuDescription() {
    EditMenuInteractionDelegate* delegate =
        [[EditMenuInteractionDelegate alloc] init];
    UIEditMenuInteraction* interaction =
        [[UIEditMenuInteraction alloc] initWithDelegate:delegate];
    [web_state_->GetView() addInteraction:interaction];

    UIEditMenuConfiguration* config = [UIEditMenuConfiguration
        configurationWithIdentifier:@"test.config"
                        sourcePoint:CGPointMake(10, 10)];
    [interaction presentEditMenuWithConfiguration:config];
    if (!base::test::ios::WaitUntilConditionOrTimeout(
            base::test::ios::kWaitForUIElementTimeout, ^{
              return delegate.menuDescription != nil;
            })) {
      return nil;
    };
    return delegate.menuDescription;
  }

 protected:
  IOSChromeScopedTestingLocalState scoped_testing_local_state_;
  web::WebTaskEnvironment task_environment_{
      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
  web::ScopedTestingWebClient web_client_;
  std::unique_ptr<TestProfileIOS> profile_;
  std::unique_ptr<web::WebState> web_state_;
  TestViewController* base_view_controller_;
  ScopedKeyWindow scoped_key_window_;
};

// Test the base structure of the menu.
TEST_F(BrowserEditMenuHandlerTest, CheckBaseMenuDescription) {
  NSMutableArray* expectedMenuDescription = GetExpectedMenu();
  AddOpenInNewCanvas(expectedMenuDescription);
  [base_view_controller_.view addSubview:web_state_->GetView()];
  web::test::LoadHtml(kPageHTML, web_state_.get());

  EXPECT_NSEQ(expectedMenuDescription, GetMenuDescription());
}

// Test the structure of the menu with Chrome actions.
TEST_F(BrowserEditMenuHandlerTest, CheckCustomizedMenuDescription) {
  NSMutableArray* expectedMenuDescription = GetExpectedMenu();
  AddOpenInNewCanvas(expectedMenuDescription);
  AddChromeMenu(expectedMenuDescription);
  AddLinkToText(expectedMenuDescription);
  SetupTranslateControllerFactory();
  PartialTranslateMediator* partial_translate_mediator =
      [[PartialTranslateMediator alloc]
          initWithBaseViewController:base_view_controller_
                         prefService:profile_->GetPrefs()
                fullscreenController:nullptr
                           incognito:NO];

  id scene_handler = OCMProtocolMock(@protocol(SceneCommands));
  TemplateURLService* template_url_service =
      ios::TemplateURLServiceFactory::GetForProfile(profile_.get());
  TemplateURLData template_url_data;
  template_url_data.SetURL(kGoogleSearchTemplate);
  template_url_service->ApplyDefaultSearchChangeForTesting(
      &template_url_data, DefaultSearchManager::FROM_USER);
  SearchWithMediator* search_with_mediator = [[SearchWithMediator alloc]
      initWithTemplateURLService:template_url_service
                       incognito:NO];
  search_with_mediator.sceneHandler = scene_handler;

  LinkToTextMediator* link_to_text_mediator = [[LinkToTextMediator alloc] init];
  DataControlsEditMenuBuilder* data_controls_menu_builder =
      [[DataControlsEditMenuBuilder alloc] init];
  BrowserEditMenuHandler* handler = [[BrowserEditMenuHandler alloc] init];
  handler.partialTranslateDelegate = partial_translate_mediator;
  handler.linkToTextDelegate = link_to_text_mediator;
  handler.searchWithDelegate = search_with_mediator;
  handler.dataControlsDelegate = data_controls_menu_builder;
  BrowserContentViewController* container_vc =
      [[BrowserContentViewController alloc] init];
  [container_vc willMoveToParentViewController:base_view_controller_];
  [base_view_controller_ addChildViewController:container_vc];
  [base_view_controller_.view addSubview:container_vc.view];
  [base_view_controller_ setHandler:handler];
  [container_vc didMoveToParentViewController:base_view_controller_];

  [container_vc setContentView:web_state_->GetView()];
  web::test::LoadHtml(kPageHTML, web_state_.get());
  EXPECT_NSEQ(expectedMenuDescription, GetMenuDescription());
  handler.partialTranslateDelegate = nil;
  [partial_translate_mediator shutdown];
}

// Tests that the share option is removed when sharing is blocked by Data
// Controls.
TEST_F(BrowserEditMenuHandlerTest, CheckShareRemoved) {
  // Set a policy to block sharing/copying from `kDataControlsBlockedUrl`.
  SetCopyBlockRule(profile_->GetPrefs());

  NSMutableArray* expectedMenuDescription = GetExpectedMenu();
  AddOpenInNewCanvas(expectedMenuDescription);
  RemoveShareMenu(expectedMenuDescription);

  BrowserEditMenuHandler* handler = [[BrowserEditMenuHandler alloc] init];
  DataControlsEditMenuBuilder* menu_builder =
      [[DataControlsEditMenuBuilder alloc] init];
  handler.dataControlsDelegate = menu_builder;
  [base_view_controller_ setHandler:handler];
  [base_view_controller_.view addSubview:web_state_->GetView()];
  web::test::LoadHtml(kPageHTML, GURL(kDataControlsBlockedUrl),
                      web_state_.get());

  EXPECT_NSEQ(expectedMenuDescription, GetMenuDescription());
}

// Tests that the share option is not removed when sharing is allowed by Data
// Controls.
TEST_F(BrowserEditMenuHandlerTest, CheckShareNotRemovedByPolicy) {
  NSMutableArray* expectedMenuDescription = GetExpectedMenu();
  AddOpenInNewCanvas(expectedMenuDescription);

  BrowserEditMenuHandler* handler = [[BrowserEditMenuHandler alloc] init];
  DataControlsEditMenuBuilder* menu_builder =
      [[DataControlsEditMenuBuilder alloc] init];
  handler.dataControlsDelegate = menu_builder;

  [base_view_controller_ setHandler:handler];
  [base_view_controller_.view addSubview:web_state_->GetView()];
  web::test::LoadHtml(kPageHTML, web_state_.get());

  // Sharing should be allowed because there are no data control rules set.
  EXPECT_NSEQ(expectedMenuDescription, GetMenuDescription());
}

TEST_F(BrowserEditMenuHandlerTest, SearchWithButtonTitle_Adjacent) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitWithFeaturesAndParameters(
      {{kPageActionMenu, {}},
       {kExplainGeminiEditMenu, {{"PositionForExplainGeminiEditMenu", "3"}}}},
      {});

  TemplateURLService* template_url_service =
      ios::TemplateURLServiceFactory::GetForProfile(profile_.get());
  TemplateURLData template_url_data;
  template_url_data.SetURL(kGoogleSearchTemplate);
  template_url_data.SetShortName(u"Google");
  template_url_service->ApplyDefaultSearchChangeForTesting(
      &template_url_data, DefaultSearchManager::FROM_USER);

  SearchWithMediator* search_with_mediator = [[SearchWithMediator alloc]
      initWithTemplateURLService:template_url_service
                       incognito:NO];

  EXPECT_NSEQ([search_with_mediator buttonTitle], @"Google Search");
}

TEST_F(BrowserEditMenuHandlerTest, SearchWithButtonTitle_Default) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitWithFeaturesAndParameters(
      {{kPageActionMenu, {}},
       {kExplainGeminiEditMenu, {{"PositionForExplainGeminiEditMenu", "1"}}}},
      {});

  TemplateURLService* template_url_service =
      ios::TemplateURLServiceFactory::GetForProfile(profile_.get());
  TemplateURLData template_url_data;
  template_url_data.SetURL(kGoogleSearchTemplate);
  template_url_data.SetShortName(u"Google");
  template_url_service->ApplyDefaultSearchChangeForTesting(
      &template_url_data, DefaultSearchManager::FROM_USER);

  SearchWithMediator* search_with_mediator = [[SearchWithMediator alloc]
      initWithTemplateURLService:template_url_service
                       incognito:NO];

  EXPECT_NSEQ([search_with_mediator buttonTitle], @"Search with Google");
}
