chromium/ash/assistant/ui/assistant_web_container_view_unittest.cc

// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/assistant/ui/assistant_web_container_view.h"

#include "ash/assistant/assistant_controller_impl.h"
#include "ash/assistant/assistant_web_ui_controller.h"
#include "ash/assistant/test/assistant_ash_test_base.h"
#include "ash/frame/non_client_frame_view_ash.h"
#include "ash/shell.h"
#include "ash/test/ash_test_views_delegate.h"
#include "base/run_loop.h"
#include "chromeos/ui/frame/default_frame_header.h"
#include "ui/views/window/frame_caption_button.h"

namespace ash {

namespace {

class TestViewsDelegate : public ash::AshTestViewsDelegate {
 public:
  TestViewsDelegate() = default;
  TestViewsDelegate(const TestViewsDelegate& other) = delete;
  TestViewsDelegate& operator=(const TestViewsDelegate& other) = delete;
  ~TestViewsDelegate() override = default;

  // views::ViewsDelegate:
  std::unique_ptr<views::NonClientFrameView> CreateDefaultNonClientFrameView(
      views::Widget* widget) override {
    return ash::Shell::Get()->CreateDefaultNonClientFrameView(widget);
  }
};

class AssistantWebContainerViewTest : public AssistantAshTestBase {
 public:
  AssistantWebContainerViewTest() = default;

  AssistantWebContainerViewTest(const AssistantWebContainerViewTest&) = delete;
  AssistantWebContainerViewTest& operator=(
      const AssistantWebContainerViewTest&) = delete;

  ~AssistantWebContainerViewTest() override = default;

 protected:
  AssistantWebContainerView* view() {
    return Shell::Get()
        ->assistant_controller()
        ->web_ui_controller()
        ->GetViewForTest();
  }

  void OpenAssistantSettings() {
    Shell::Get()->assistant_controller()->OpenAssistantSettings();
  }

  views::FrameCaptionButton* GetBackButton(views::Widget* widget) {
    views::NonClientView* non_client_view = widget->non_client_view();
    NonClientFrameViewAsh* frame_view_ash =
        static_cast<NonClientFrameViewAsh*>(non_client_view->frame_view());
    return frame_view_ash->GetHeaderView()->GetFrameHeader()->GetBackButton();
  }

 private:
  std::unique_ptr<TestViewsDelegate> views_delegate_ =
      std::make_unique<TestViewsDelegate>();
};

}  // namespace

TEST_F(AssistantWebContainerViewTest, ShowAndCloseWindow) {
  // Show Assistant Settings UI.
  OpenAssistantSettings();
  AssistantWebContainerView* container_view = view();
  ASSERT_TRUE(container_view);

  // Close Assistant Settings UI.
  container_view->GetWidget()->CloseNow();
  container_view = view();
  ASSERT_FALSE(container_view);
}

TEST_F(AssistantWebContainerViewTest, CenterWindow) {
  // Test large and small screens.
  std::vector<std::string> resolutions{"1200x1000", "800x600"};

  for (const auto& resolution : resolutions) {
    UpdateDisplay(resolution);

    // Show Assistant Settings UI and grab a reference to our view under test.
    OpenAssistantSettings();
    AssistantWebContainerView* container_view = view();

    // We expect the view to appear in the work area where new windows will
    // open.
    gfx::Rect expected_work_area =
        display::Screen::GetScreen()->GetPrimaryDisplay().work_area();

    // We expect the view to be centered in screen.
    gfx::Rect expected_bounds = gfx::Rect(expected_work_area);
    expected_bounds.ClampToCenteredSize(
        container_view->GetWidget()->GetNativeWindow()->bounds().size());
    ASSERT_EQ(expected_bounds,
              container_view->GetWidget()->GetWindowBoundsInScreen());
    container_view->GetWidget()->CloseNow();
  }
}

TEST_F(AssistantWebContainerViewTest, CloseWindowByKeyEvent) {
  // Show Assistant Settings UI.
  OpenAssistantSettings();
  ASSERT_TRUE(view());

  // Close Assistant Settings UI by key event.
  PressAndReleaseKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
  base::RunLoop().RunUntilIdle();
  ASSERT_FALSE(view());
}

TEST_F(AssistantWebContainerViewTest, ShouldHaveBackButton) {
  // Show Assistant Settings UI.
  OpenAssistantSettings();
  ASSERT_TRUE(view());

  views::FrameCaptionButton* back_button = nullptr;
  back_button = GetBackButton(view()->GetWidget());
  ASSERT_FALSE(back_button);

  view()->SetCanGoBackForTesting(/*can_go_back=*/true);
  back_button = GetBackButton(view()->GetWidget());
  ASSERT_TRUE(back_button);
  ASSERT_TRUE(back_button->GetVisible());

  view()->SetCanGoBackForTesting(/*can_go_back=*/false);
  back_button = GetBackButton(view()->GetWidget());
  ASSERT_FALSE(back_button);
}

TEST_F(AssistantWebContainerViewTest, BackButtonShouldPaintAsActive) {
  // Show Assistant Settings UI.
  OpenAssistantSettings();
  ASSERT_TRUE(view());

  view()->SetCanGoBackForTesting(/*can_go_back=*/true);
  views::FrameCaptionButton* back_button = GetBackButton(view()->GetWidget());
  ASSERT_TRUE(back_button);
  ASSERT_TRUE(back_button->GetVisible());
  ASSERT_TRUE(back_button->GetPaintAsActive());

  // Activate another window will paint the back button as inactive.
  std::unique_ptr<aura::Window> window(CreateTestWindow());
  ASSERT_TRUE(back_button->GetVisible());
  ASSERT_FALSE(back_button->GetPaintAsActive());

  // Activate Assistant web container will paint the back button as active.
  view()->GetWidget()->Activate();
  ASSERT_TRUE(back_button->GetVisible());
  ASSERT_TRUE(back_button->GetPaintAsActive());
}

TEST_F(AssistantWebContainerViewTest, ShouldRemoveBackButton) {
  // Show Assistant Settings UI.
  OpenAssistantSettings();
  ASSERT_TRUE(view());

  views::FrameCaptionButton* back_button = nullptr;
  back_button = GetBackButton(view()->GetWidget());
  ASSERT_FALSE(back_button);

  view()->OpenUrl(GURL("test1"));
  view()->DidStopLoading();
  back_button = GetBackButton(view()->GetWidget());
  ASSERT_FALSE(back_button);

  view()->SetCanGoBackForTesting(/*can_go_back=*/true);
  back_button = GetBackButton(view()->GetWidget());
  ASSERT_TRUE(back_button);
  ASSERT_TRUE(back_button->GetVisible());

  // Open another URL will remove the back button.
  view()->OpenUrl(GURL("test2"));
  view()->DidStopLoading();
  back_button = GetBackButton(view()->GetWidget());
  ASSERT_FALSE(back_button);
}

}  // namespace ash