chromium/ios/chrome/browser/ui/toolbar/toolbar_coordinator_unittest.mm

// Copyright 2024 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/ui/toolbar/toolbar_coordinator.h"

#import "base/scoped_observation.h"
#import "base/test/scoped_feature_list.h"
#import "base/test/task_environment.h"
#import "ios/chrome/browser/omnibox/model/omnibox_position_browser_agent.h"
#import "ios/chrome/browser/omnibox/model/omnibox_position_browser_agent_observer.h"
#import "ios/chrome/browser/shared/model/application_context/application_context.h"
#import "ios/chrome/browser/shared/model/browser/test/test_browser.h"
#import "ios/chrome/browser/shared/model/prefs/pref_names.h"
#import "ios/chrome/browser/shared/model/profile/test/test_profile_ios.h"
#import "ios/chrome/browser/shared/public/commands/activity_service_commands.h"
#import "ios/chrome/browser/shared/public/commands/application_commands.h"
#import "ios/chrome/browser/shared/public/commands/command_dispatcher.h"
#import "ios/chrome/browser/shared/public/commands/help_commands.h"
#import "ios/chrome/browser/shared/public/commands/lens_commands.h"
#import "ios/chrome/browser/shared/public/commands/popup_menu_commands.h"
#import "ios/chrome/browser/shared/public/commands/qr_scanner_commands.h"
#import "ios/chrome/browser/shared/public/commands/quick_delete_commands.h"
#import "ios/chrome/browser/shared/public/commands/settings_commands.h"
#import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h"
#import "ios/chrome/test/ios_chrome_scoped_testing_local_state.h"
#import "testing/platform_test.h"
#import "third_party/ocmock/OCMock/OCMock.h"

namespace {
// Sample observer for use in tests.
class TestOmniboxPositionObserver : public OmniboxPositionBrowserAgentObserver {
 public:
  void OmniboxPositionBrowserAgentHasNewBottomLayout(
      OmniboxPositionBrowserAgent* browser_agent,
      bool is_current_layout_bottom_omnibox) override {
    is_bottom_omnibox_ = is_current_layout_bottom_omnibox;
  }

  bool is_bottom_omnibox_ = false;
};
}  // namespace

// Unittests related to the ToolbarCoordinator.
class ToolbarCoordinatorTest : public PlatformTest {
 public:
  ToolbarCoordinatorTest() {
    browser_state_ = TestChromeBrowserState::Builder().Build();
    browser_ = std::make_unique<TestBrowser>(browser_state_.get());

    // Setup all necessary handlers.

    id mockHelpHandler = OCMProtocolMock(@protocol(HelpCommands));
    [browser_->GetCommandDispatcher()
        startDispatchingToTarget:mockHelpHandler
                     forProtocol:@protocol(HelpCommands)];

    id mockLensHandler = OCMProtocolMock(@protocol(LensCommands));
    [browser_->GetCommandDispatcher()
        startDispatchingToTarget:mockLensHandler
                     forProtocol:@protocol(LensCommands)];

    id mockApplicationHandler = OCMProtocolMock(@protocol(ApplicationCommands));
    [browser_->GetCommandDispatcher()
        startDispatchingToTarget:mockApplicationHandler
                     forProtocol:@protocol(ApplicationCommands)];

    id mockQRScannerHandler = OCMProtocolMock(@protocol(QRScannerCommands));
    [browser_->GetCommandDispatcher()
        startDispatchingToTarget:mockQRScannerHandler
                     forProtocol:@protocol(QRScannerCommands)];

    id mockSettingsHandler = OCMProtocolMock(@protocol(SettingsCommands));
    [browser_->GetCommandDispatcher()
        startDispatchingToTarget:mockSettingsHandler
                     forProtocol:@protocol(SettingsCommands)];

    id mockQuickDeleteHandler = OCMProtocolMock(@protocol(QuickDeleteCommands));
    [browser_->GetCommandDispatcher()
        startDispatchingToTarget:mockQuickDeleteHandler
                     forProtocol:@protocol(QuickDeleteCommands)];

    id mockPopupMenuHandler = OCMProtocolMock(@protocol(PopupMenuCommands));
    [browser_->GetCommandDispatcher()
        startDispatchingToTarget:mockPopupMenuHandler
                     forProtocol:@protocol(PopupMenuCommands)];

    id mockActivityServiceHandler =
        OCMProtocolMock(@protocol(ActivityServiceCommands));
    [browser_->GetCommandDispatcher()
        startDispatchingToTarget:mockActivityServiceHandler
                     forProtocol:@protocol(ActivityServiceCommands)];

    OmniboxPositionBrowserAgent::CreateForBrowser(browser_.get());
  }

  ~ToolbarCoordinatorTest() override {}

  void TearDown() override { [coordinator_ stop]; }

  base::test::TaskEnvironment task_environment_;
  IOSChromeScopedTestingLocalState scoped_testing_local_state_;
  std::unique_ptr<TestChromeBrowserState> browser_state_;
  std::unique_ptr<TestBrowser> browser_;
  ToolbarCoordinator* coordinator_;
};

// Test that the OmniboxPositionBrowserAgent can be observed to tell when the
// bottom omnibox position changes.
TEST_F(ToolbarCoordinatorTest, TestOmniboxPositionBrowserAgentObservation) {
  // Bottom omnibox is not supported on all devices (e.g. iPad).
  if (!IsBottomOmniboxAvailable()) {
    return;
  }
  TestOmniboxPositionObserver observer;
  base::ScopedObservation<OmniboxPositionBrowserAgent,
                          TestOmniboxPositionObserver>
      obs{&observer};

  OmniboxPositionBrowserAgent* browser_agent =
      OmniboxPositionBrowserAgent::FromBrowser(browser_.get());
  obs.Observe(browser_agent);

  coordinator_ = [[ToolbarCoordinator alloc] initWithBrowser:browser_.get()];
  [coordinator_ start];
  EXPECT_FALSE(observer.is_bottom_omnibox_);

  // Change bottom omnibox pref.
  GetApplicationContext()->GetLocalState()->SetBoolean(prefs::kBottomOmnibox,
                                                       true);

  EXPECT_TRUE(observer.is_bottom_omnibox_);
}