#include "ash/system/mahi/mahi_panel_view.h"
#include <memory>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
#include "ash/constants/ash_pref_names.h"
#include "ash/constants/url_constants.h"
#include "ash/public/cpp/image_util.h"
#include "ash/public/cpp/new_window_delegate.h"
#include "ash/public/cpp/test/test_new_window_delegate.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/style/icon_button.h"
#include "ash/style/system_textfield.h"
#include "ash/system/mahi/mahi_constants.h"
#include "ash/system/mahi/mahi_content_source_button.h"
#include "ash/system/mahi/mahi_question_answer_view.h"
#include "ash/system/mahi/mahi_ui_controller.h"
#include "ash/system/mahi/mahi_utils.h"
#include "ash/system/mahi/summary_outlines_elucidation_section.h"
#include "ash/system/mahi/test/mahi_test_util.h"
#include "ash/system/mahi/test/mock_mahi_manager.h"
#include "ash/test/ash_test_base.h"
#include "base/rand_util.h"
#include "base/strings/strcat.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_future.h"
#include "base/time/time.h"
#include "chromeos/components/mahi/public/cpp/mahi_manager.h"
#include "chromeos/constants/chromeos_features.h"
#include "chromeos/strings/grit/chromeos_strings.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/compositor/layer.h"
#include "ui/events/test/event_generator.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/image/image_unittest_util.h"
#include "ui/gfx/text_constants.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/scroll_view.h"
#include "ui/views/controls/scrollbar/scroll_bar.h"
#include "ui/views/controls/styled_label.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/highlight_border.h"
#include "ui/views/test/views_test_utils.h"
#include "ui/views/view_utils.h"
#include "ui/views/widget/widget.h"
#include "url/gurl.h"
namespace ash {
namespace {
using chromeos::MahiResponseStatus;
using ::testing::_;
using ::testing::Mock;
using ::testing::NiceMock;
using ::testing::Return;
class MockNewWindowDelegate : public NiceMock<TestNewWindowDelegate> {
public:
MOCK_METHOD(void,
OpenUrl,
(const GURL& url, OpenUrlFrom from, Disposition disposition),
(override));
};
std::vector<MahiResponseStatus> GetMahiErrors() {
std::vector<MahiResponseStatus> errors;
for (size_t status_value = 0;
status_value <= static_cast<size_t>(MahiResponseStatus::kMaxValue);
++status_value) {
MahiResponseStatus status = static_cast<MahiResponseStatus>(status_value);
if (status != MahiResponseStatus::kSuccess &&
status != MahiResponseStatus::kLowQuota) {
errors.push_back(status);
}
}
return errors;
}
void PressEnter() {
ui::test::EventGenerator(Shell::GetPrimaryRootWindow())
.PressKey(ui::KeyboardCode::VKEY_RETURN, ui::EF_NONE);
}
void ReturnDefaultAnswerAsyncly(
base::test::TestFuture<void>& waiter,
MahiResponseStatus status,
chromeos::MahiManager::MahiAnswerQuestionCallback callback,
base::TimeDelta delay = base::TimeDelta()) {
base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
FROM_HERE,
base::BindOnce(
[](base::OnceClosure unblock_closure, MahiResponseStatus status,
chromeos::MahiManager::MahiAnswerQuestionCallback callback) {
std::move(callback).Run(u"fake answer", status);
std::move(unblock_closure).Run();
},
waiter.GetCallback(), status, std::move(callback)),
delay);
}
void ReturnDefaultOutlinesAsyncly(
base::test::TestFuture<void>& waiter,
MahiResponseStatus status,
chromeos::MahiManager::MahiOutlinesCallback callback) {
base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
FROM_HERE,
base::BindOnce(
[](base::OnceClosure unblock_closure, MahiResponseStatus status,
chromeos::MahiManager::MahiOutlinesCallback callback) {
std::move(callback).Run(mahi_test_util::GetDefaultFakeOutlines(),
status);
std::move(unblock_closure).Run();
},
waiter.GetCallback(), status, std::move(callback)));
}
void ReturnDefaultSummaryAsyncly(
base::test::TestFuture<void>& waiter,
MahiResponseStatus status,
chromeos::MahiManager::MahiSummaryCallback callback,
base::TimeDelta delay = base::TimeDelta()) {
base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
FROM_HERE,
base::BindOnce(
[](base::OnceClosure unblock_closure, MahiResponseStatus status,
chromeos::MahiManager::MahiSummaryCallback callback) {
std::move(callback).Run(u"fake summary", status);
std::move(unblock_closure).Run();
},
waiter.GetCallback(), status, std::move(callback)),
delay);
}
void ReturnLongSummary(chromeos::MahiManager::MahiSummaryCallback callback) {
std::move(callback).Run(
base::StrCat(std::vector<std::u16string>(100, u"Long Summary\n")),
MahiResponseStatus::kSuccess);
}
std::u16string_view GetContentSourceTitle(views::View* mahi_view) {
return views::AsViewClass<MahiContentSourceButton>(
mahi_view->GetViewByID(
mahi_constants::ViewId::kContentSourceButton))
->GetText();
}
gfx::ImageSkia GetContentSourceIcon(views::View* mahi_view) {
return views::AsViewClass<MahiContentSourceButton>(
mahi_view->GetViewByID(
mahi_constants::ViewId::kContentSourceButton))
->GetImage(views::Button::STATE_NORMAL);
}
views::Label* GetSummaryLabel(views::View* mahi_view) {
return views::AsViewClass<views::Label>(
mahi_view->GetViewByID(mahi_constants::ViewId::kSummaryLabel));
}
std::u16string GetRandomString(int max_words_count) {
int string_length = base::RandInt(1, max_words_count);
std::vector<char> random_chars;
for (int string_index = 0; string_index < string_length; string_index++) {
int word_length = base::RandInt(1, 10);
for (int word_index = 0; word_index < word_length; word_index++) {
random_chars.push_back(base::RandInt('a', 'z'));
}
random_chars.push_back(0x20);
}
return std::u16string(random_chars.begin(), random_chars.end());
}
}
class MahiPanelViewTest : public AshTestBase {
public:
MahiPanelViewTest()
: AshTestBase(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
MockMahiManager& mock_mahi_manager() { return mock_mahi_manager_; }
MahiUiController* ui_controller() { return &ui_controller_; }
MockNewWindowDelegate& new_window_delegate() { return new_window_delegate_; }
MahiPanelView* panel_view() { return panel_view_; }
views::Widget* widget() { return widget_.get(); }
protected:
void SetUp() override {
scoped_feature_list_.InitWithFeatures(
{chromeos::features::kMahi,
chromeos::features::kFeatureManagementMahi},
{});
AshTestBase::SetUp();
scoped_setter_ = std::make_unique<chromeos::ScopedMahiManagerSetter>(
&mock_mahi_manager_);
CreatePanelWidget();
}
void TearDown() override {
panel_view_ = nullptr;
widget_.reset();
scoped_setter_.reset();
AshTestBase::TearDown();
}
void CreatePanelWidget() {
ResetPanelWidget();
widget_ = CreateFramelessTestWidget();
widget_->SetBounds(
gfx::Rect(0, 0,
mahi_constants::kPanelDefaultWidth,
mahi_constants::kPanelDefaultHeight));
panel_view_ = widget_->SetContentsView(
std::make_unique<MahiPanelView>(&ui_controller_));
}
void ResetPanelWidget() {
panel_view_ = nullptr;
widget_.reset();
}
void SubmitTestQuestion(const std::u16string& question = u"fake question") {
auto* const question_textfield = views::AsViewClass<views::Textfield>(
panel_view()->GetViewByID(mahi_constants::ViewId::kQuestionTextfield));
ASSERT_TRUE(question_textfield);
question_textfield->SetText(question);
auto* const send_button = panel_view()->GetViewByID(
mahi_constants::ViewId::kAskQuestionSendButton);
ASSERT_TRUE(send_button);
send_button->SetEnabled(true);
LeftClickOn(send_button);
}
private:
base::test::ScopedFeatureList scoped_feature_list_;
NiceMock<MockMahiManager> mock_mahi_manager_;
std::unique_ptr<chromeos::ScopedMahiManagerSetter> scoped_setter_;
MahiUiController ui_controller_;
raw_ptr<MahiPanelView> panel_view_ = nullptr;
std::unique_ptr<views::Widget> widget_;
MockNewWindowDelegate new_window_delegate_;
};
TEST_F(MahiPanelViewTest, SummaryTextAndIndicatorLabel) {
const std::u16string summary_text1(u"test summary text 1");
ON_CALL(mock_mahi_manager(), GetSummary)
.WillByDefault([&summary_text1](
chromeos::MahiManager::MahiSummaryCallback callback) {
std::move(callback).Run(summary_text1, MahiResponseStatus::kSuccess);
});
MahiPanelView mahi_view1(ui_controller());
const auto* const summary_label1 = views::AsViewClass<views::Label>(
mahi_view1.GetViewByID(mahi_constants::ViewId::kSummaryLabel));
const auto* const indicator_label =
views::AsViewClass<views::Label>(mahi_view1.GetViewByID(
mahi_constants::ViewId::kSummaryElucidationIndicator));
EXPECT_EQ(summary_text1, summary_label1->GetText());
EXPECT_TRUE(indicator_label->GetVisible());
EXPECT_EQ(indicator_label->GetText(),
l10n_util::GetStringUTF16(IDS_MAHI_SUMMARIZE_INDICATOR_LABEL));
const std::u16string summary_text2(u"test summary text 2");
ON_CALL(mock_mahi_manager(), GetSummary)
.WillByDefault([&summary_text2](
chromeos::MahiManager::MahiSummaryCallback callback) {
std::move(callback).Run(summary_text2, MahiResponseStatus::kSuccess);
});
MahiPanelView mahi_view2(ui_controller());
const auto* const summary_label2 = views::AsViewClass<views::Label>(
mahi_view2.GetViewByID(mahi_constants::ViewId::kSummaryLabel));
EXPECT_EQ(summary_text2, summary_label2->GetText());
EXPECT_TRUE(summary_label2->GetMultiLine());
EXPECT_EQ(summary_label2->GetHorizontalAlignment(),
gfx::HorizontalAlignment::ALIGN_LEFT);
}
TEST_F(MahiPanelViewTest, SimplifiedTextAndIndicatorLabel) {
const std::u16string simplified_text(u"test simplified text");
ON_CALL(mock_mahi_manager(), GetElucidation)
.WillByDefault(
[&simplified_text](
chromeos::MahiManager::MahiElucidationCallback callback) {
std::move(callback).Run(simplified_text,
MahiResponseStatus::kSuccess);
});
ui_controller()->set_elucidation_in_use_for_testing(true);
MahiPanelView mahi_view(ui_controller());
const auto* const result_label = views::AsViewClass<views::Label>(
mahi_view.GetViewByID(mahi_constants::ViewId::kSummaryLabel));
const auto* const indicator_label =
views::AsViewClass<views::Label>(mahi_view.GetViewByID(
mahi_constants::ViewId::kSummaryElucidationIndicator));
EXPECT_EQ(simplified_text, result_label->GetText());
EXPECT_TRUE(indicator_label->GetVisible());
EXPECT_EQ(indicator_label->GetText(),
l10n_util::GetStringUTF16(IDS_MAHI_SIMPLIFY_INDICATOR_LABEL));
}
TEST_F(MahiPanelViewTest, ThumbsUpFeedbackButton) {
base::HistogramTester histogram_tester;
EXPECT_CALL(mock_mahi_manager(), OpenFeedbackDialog).Times(0);
IconButton* thumbs_up_button = views::AsViewClass<IconButton>(
panel_view()->GetViewByID(mahi_constants::ViewId::kThumbsUpButton));
LeftClickOn(thumbs_up_button);
Mock::VerifyAndClearExpectations(&mock_mahi_manager());
EXPECT_TRUE(thumbs_up_button->toggled());
histogram_tester.ExpectBucketCount(mahi_constants::kMahiFeedbackHistogramName,
true, 1);
histogram_tester.ExpectBucketCount(mahi_constants::kMahiFeedbackHistogramName,
false, 0);
EXPECT_CALL(mock_mahi_manager(), OpenFeedbackDialog).Times(0);
LeftClickOn(thumbs_up_button);
Mock::VerifyAndClearExpectations(&mock_mahi_manager());
EXPECT_FALSE(thumbs_up_button->toggled());
histogram_tester.ExpectBucketCount(mahi_constants::kMahiFeedbackHistogramName,
true, 1);
histogram_tester.ExpectBucketCount(mahi_constants::kMahiFeedbackHistogramName,
false, 0);
EXPECT_CALL(mock_mahi_manager(), OpenFeedbackDialog).Times(0);
LeftClickOn(thumbs_up_button);
Mock::VerifyAndClearExpectations(&mock_mahi_manager());
EXPECT_TRUE(thumbs_up_button->toggled());
histogram_tester.ExpectBucketCount(mahi_constants::kMahiFeedbackHistogramName,
true, 2);
histogram_tester.ExpectBucketCount(mahi_constants::kMahiFeedbackHistogramName,
false, 0);
}
TEST_F(MahiPanelViewTest, ThumbsDownFeedbackButton) {
base::HistogramTester histogram_tester;
EXPECT_CALL(mock_mahi_manager(), OpenFeedbackDialog).Times(1);
IconButton* thumbs_down_button = views::AsViewClass<IconButton>(
panel_view()->GetViewByID(mahi_constants::ViewId::kThumbsDownButton));
LeftClickOn(thumbs_down_button);
Mock::VerifyAndClearExpectations(&mock_mahi_manager());
EXPECT_TRUE(thumbs_down_button->toggled());
histogram_tester.ExpectBucketCount(mahi_constants::kMahiFeedbackHistogramName,
true, 0);
histogram_tester.ExpectBucketCount(mahi_constants::kMahiFeedbackHistogramName,
false, 1);
EXPECT_CALL(mock_mahi_manager(), OpenFeedbackDialog).Times(0);
LeftClickOn(thumbs_down_button);
Mock::VerifyAndClearExpectations(&mock_mahi_manager());
EXPECT_FALSE(thumbs_down_button->toggled());
histogram_tester.ExpectBucketCount(mahi_constants::kMahiFeedbackHistogramName,
true, 0);
histogram_tester.ExpectBucketCount(mahi_constants::kMahiFeedbackHistogramName,
false, 1);
EXPECT_CALL(mock_mahi_manager(), OpenFeedbackDialog).Times(0);
LeftClickOn(thumbs_down_button);
Mock::VerifyAndClearExpectations(&mock_mahi_manager());
EXPECT_TRUE(thumbs_down_button->toggled());
histogram_tester.ExpectBucketCount(mahi_constants::kMahiFeedbackHistogramName,
true, 0);
histogram_tester.ExpectBucketCount(mahi_constants::kMahiFeedbackHistogramName,
false, 2);
}
TEST_F(MahiPanelViewTest, CloseButton) {
EXPECT_FALSE(widget()->IsClosed());
LeftClickOn(panel_view()->GetViewByID(mahi_constants::ViewId::kCloseButton));
EXPECT_TRUE(widget()->IsClosed());
}
TEST_F(MahiPanelViewTest, LearnMoreLink) {
auto* disclaimer_text = views::AsViewClass<views::StyledLabel>(
panel_view()->GetViewByID(mahi_constants::ViewId::kFooterLabel));
views::test::RunScheduledLayout(widget());
EXPECT_CALL(new_window_delegate(),
OpenUrl(GURL(chrome::kHelpMeReadWriteLearnMoreURL),
NewWindowDelegate::OpenUrlFrom::kUserInteraction,
NewWindowDelegate::Disposition::kNewForegroundTab));
disclaimer_text->ClickFirstLinkForTesting();
Mock::VerifyAndClearExpectations(&new_window_delegate());
}
TEST_F(MahiPanelViewTest, OutlinesHiddenByDefault) {
EXPECT_FALSE(
panel_view()
->GetViewByID(mahi_constants::ViewId::kOutlinesSectionContainer)
->GetVisible());
}
TEST_F(MahiPanelViewTest, PanelContentsViewBoundsWithShortSummary) {
ON_CALL(mock_mahi_manager(), GetContentTitle)
.WillByDefault(Return(u"fake content title"));
ON_CALL(mock_mahi_manager(), GetOutlines)
.WillByDefault(mahi_test_util::ReturnDefaultOutlines);
ON_CALL(mock_mahi_manager(), GetSummary)
.WillByDefault([](chromeos::MahiManager::MahiSummaryCallback callback) {
std::move(callback).Run(u"Short summary",
MahiResponseStatus::kSuccess);
});
MahiPanelView mahi_view(ui_controller());
mahi_view.GetViewByID(mahi_constants::ViewId::kOutlinesSectionContainer)
->SetVisible(true);
mahi_view.SetPreferredSize(gfx::Size(300, 400));
mahi_view.SizeToPreferredSize();
const int short_content_height =
mahi_view.GetViewByID(mahi_constants::kSummaryOutlinesSection)
->bounds()
.height();
const int short_contents_container_height =
mahi_view.GetViewByID(mahi_constants::kPanelContentsContainer)
->bounds()
.height();
EXPECT_GT(short_contents_container_height, short_content_height);
}
TEST_F(MahiPanelViewTest, PanelContentsViewBoundsWithLongSummary) {
ON_CALL(mock_mahi_manager(), GetContentTitle)
.WillByDefault(Return(u"fake content title"));
ON_CALL(mock_mahi_manager(), GetOutlines)
.WillByDefault(mahi_test_util::ReturnDefaultOutlines);
ON_CALL(mock_mahi_manager(), GetSummary).WillByDefault(ReturnLongSummary);
MahiPanelView mahi_view(ui_controller());
mahi_view.GetViewByID(mahi_constants::ViewId::kOutlinesSectionContainer)
->SetVisible(true);
mahi_view.SetPreferredSize(gfx::Size(300, 400));
mahi_view.SizeToPreferredSize();
const int long_content_height =
mahi_view.GetViewByID(mahi_constants::kSummaryOutlinesSection)
->bounds()
.height();
const int long_contents_container_height =
mahi_view.GetViewByID(mahi_constants::kPanelContentsContainer)
->bounds()
.height();
EXPECT_LT(long_contents_container_height, long_content_height);
}
TEST_F(MahiPanelViewTest, PanelContentsViewBoundsStayConstant) {
constexpr gfx::Size kPanelBounds(300, 400);
ON_CALL(mock_mahi_manager(), GetSummary)
.WillByDefault([](chromeos::MahiManager::MahiSummaryCallback callback) {
std::move(callback).Run(u"Short summary", MahiResponseStatus::kSuccess);
});
MahiPanelView mahi_view1(ui_controller());
mahi_view1.SetPreferredSize(kPanelBounds);
mahi_view1.SizeToPreferredSize();
ON_CALL(mock_mahi_manager(), GetSummary).WillByDefault(ReturnLongSummary);
MahiPanelView mahi_view2(ui_controller());
mahi_view2.SetPreferredSize(kPanelBounds);
mahi_view2.SizeToPreferredSize();
const int short_contents_container_height =
mahi_view1.GetViewByID(mahi_constants::kPanelContentsContainer)
->bounds()
.height();
const int long_contents_container_height =
mahi_view2.GetViewByID(mahi_constants::kPanelContentsContainer)
->bounds()
.height();
EXPECT_EQ(short_contents_container_height, long_contents_container_height);
}
TEST_F(MahiPanelViewTest, LoadingAnimations) {
ResetPanelWidget();
base::test::TestFuture<void> summary_waiter;
ON_CALL(mock_mahi_manager(), GetSummary)
.WillByDefault([&summary_waiter](
chromeos::MahiManager::MahiSummaryCallback callback) {
ReturnDefaultSummaryAsyncly(
summary_waiter, MahiResponseStatus::kSuccess, std::move(callback));
});
base::test::TestFuture<void> outlines_waiter;
ON_CALL(mock_mahi_manager(), GetOutlines)
.WillByDefault([&outlines_waiter](
chromeos::MahiManager::MahiOutlinesCallback callback) {
ReturnDefaultOutlinesAsyncly(
outlines_waiter, MahiResponseStatus::kSuccess, std::move(callback));
});
MahiPanelView mahi_view(ui_controller());
mahi_view.GetViewByID(mahi_constants::ViewId::kOutlinesSectionContainer)
->SetVisible(true);
const auto* const summary_loading_animated_image = mahi_view.GetViewByID(
mahi_constants::ViewId::kSummaryLoadingAnimatedImage);
const auto* const outlines_loading_animated_image = mahi_view.GetViewByID(
mahi_constants::ViewId::kOutlinesLoadingAnimatedImage);
const auto* const summary_label =
mahi_view.GetViewByID(mahi_constants::ViewId::kSummaryLabel);
const auto* const outlines_container =
mahi_view.GetViewByID(mahi_constants::ViewId::kOutlinesContainer);
EXPECT_TRUE(summary_loading_animated_image->GetVisible());
EXPECT_TRUE(outlines_loading_animated_image->GetVisible());
EXPECT_FALSE(summary_label->GetVisible());
EXPECT_FALSE(outlines_container->GetVisible());
ASSERT_TRUE(summary_waiter.Wait());
EXPECT_FALSE(summary_loading_animated_image->GetVisible());
EXPECT_TRUE(outlines_loading_animated_image->GetVisible());
EXPECT_TRUE(summary_label->GetVisible());
EXPECT_FALSE(outlines_container->GetVisible());
ASSERT_TRUE(outlines_waiter.Wait());
EXPECT_FALSE(summary_loading_animated_image->GetVisible());
EXPECT_FALSE(outlines_loading_animated_image->GetVisible());
EXPECT_TRUE(summary_label->GetVisible());
EXPECT_FALSE(outlines_container->GetVisible());
}
TEST_F(MahiPanelViewTest, SummaryLoadingAnimationsMetricsRecord) {
ResetPanelWidget();
base::HistogramTester histogram_tester;
auto delay_time = base::Milliseconds(100);
base::test::TestFuture<void> summary_waiter;
ON_CALL(mock_mahi_manager(), GetSummary)
.WillByDefault([&summary_waiter, delay_time](
chromeos::MahiManager::MahiSummaryCallback callback) {
ReturnDefaultSummaryAsyncly(
summary_waiter, MahiResponseStatus::kSuccess, std::move(callback),
delay_time);
});
MahiPanelView mahi_view(ui_controller());
histogram_tester.ExpectTimeBucketCount(
mahi_constants::kSummaryLoadingTimeHistogramName, delay_time, 0);
ASSERT_TRUE(summary_waiter.WaitAndClear());
histogram_tester.ExpectTimeBucketCount(
mahi_constants::kSummaryLoadingTimeHistogramName, delay_time, 1);
ui_controller()->RefreshContents();
ASSERT_TRUE(summary_waiter.Wait());
histogram_tester.ExpectTimeBucketCount(
mahi_constants::kSummaryLoadingTimeHistogramName, delay_time, 2);
}
TEST_F(MahiPanelViewTest, AnswerLoadingAnimationsMetricsRecord) {
base::HistogramTester histogram_tester;
auto delay_time = base::Milliseconds(100);
base::test::TestFuture<void> answer_waiter;
EXPECT_CALL(mock_mahi_manager(), AnswerQuestion)
.WillOnce(
[&answer_waiter, delay_time](
const std::u16string& question, bool current_panel_content,
chromeos::MahiManager::MahiAnswerQuestionCallback callback) {
ReturnDefaultAnswerAsyncly(
answer_waiter, MahiResponseStatus::kSuccess,
std::move(callback), delay_time);
});
SubmitTestQuestion();
histogram_tester.ExpectTimeBucketCount(
mahi_constants::kAnswerLoadingTimeHistogramName, delay_time, 0);
ASSERT_TRUE(answer_waiter.Wait());
histogram_tester.ExpectTimeBucketCount(
mahi_constants::kAnswerLoadingTimeHistogramName, delay_time, 1);
}
TEST_F(MahiPanelViewTest, ResizePanel) {
MahiPanelView mahi_view(ui_controller());
const gfx::Rect resized_bounds = gfx::Rect(20, 20, 150, 140);
panel_view()->SetBounds(resized_bounds.x(), resized_bounds.y(),
resized_bounds.width(), resized_bounds.height());
EXPECT_EQ(panel_view()->layer()->GetTargetClipRect(),
gfx::Rect(0, 0, resized_bounds.width(), resized_bounds.height()));
const SummaryOutlinesElucidationSection*
summary_outlines_elucidation_section =
views::AsViewClass<SummaryOutlinesElucidationSection>(
panel_view()->GetViewByID(
mahi_constants::ViewId::kSummaryOutlinesSection));
const views::Label* summary_text = views::AsViewClass<views::Label>(
summary_outlines_elucidation_section->GetViewByID(
mahi_constants::ViewId::kSummaryLabel));
EXPECT_EQ(
summary_text->GetMaximumWidth(),
resized_bounds.width() - mahi_constants::kPanelBorderAndPadding -
mahi_constants::kSummaryOutlinesElucidationSectionPadding.width());
}
TEST_F(MahiPanelViewTest, TransitionToQuestionAnswerView) {
const auto* const summary_outlines_section = panel_view()->GetViewByID(
mahi_constants::ViewId::kSummaryOutlinesSection);
ASSERT_TRUE(summary_outlines_section);
EXPECT_TRUE(summary_outlines_section->GetVisible());
const auto* const question_answer_view =
panel_view()->GetViewByID(mahi_constants::ViewId::kQuestionAnswerView);
ASSERT_TRUE(question_answer_view);
EXPECT_FALSE(question_answer_view->GetVisible());
const auto* const send_button =
panel_view()->GetViewByID(mahi_constants::ViewId::kAskQuestionSendButton);
ASSERT_TRUE(send_button);
EXPECT_TRUE(send_button->GetVisible());
const auto* const go_to_summary_outlines_button = panel_view()->GetViewByID(
mahi_constants::ViewId::kGoToSummaryOutlinesButton);
ASSERT_TRUE(go_to_summary_outlines_button);
EXPECT_FALSE(go_to_summary_outlines_button->GetVisible());
auto* const question_textfield = views::AsViewClass<views::Textfield>(
panel_view()->GetViewByID(mahi_constants::ViewId::kQuestionTextfield));
ASSERT_TRUE(question_textfield);
EXPECT_TRUE(question_textfield->GetVisible());
const auto* const go_to_question_answer_button = panel_view()->GetViewByID(
mahi_constants::ViewId::kGoToQuestionAndAnswerButton);
ASSERT_TRUE(go_to_question_answer_button);
EXPECT_FALSE(go_to_question_answer_button->GetVisible());
SubmitTestQuestion(u"input");
EXPECT_FALSE(summary_outlines_section->GetVisible());
EXPECT_TRUE(question_answer_view->GetVisible());
EXPECT_TRUE(go_to_summary_outlines_button->GetVisible());
EXPECT_TRUE(send_button->GetVisible());
views::test::RunScheduledLayout(widget());
LeftClickOn(go_to_summary_outlines_button);
EXPECT_TRUE(summary_outlines_section->GetVisible());
EXPECT_FALSE(question_answer_view->GetVisible());
EXPECT_FALSE(go_to_summary_outlines_button->GetVisible());
EXPECT_TRUE(send_button->GetVisible());
views::test::RunScheduledLayout(widget());
EXPECT_TRUE(go_to_question_answer_button->GetVisible());
LeftClickOn(go_to_question_answer_button);
EXPECT_FALSE(summary_outlines_section->GetVisible());
EXPECT_TRUE(question_answer_view->GetVisible());
ui_controller()->RefreshContents();
EXPECT_TRUE(summary_outlines_section->GetVisible());
EXPECT_FALSE(question_answer_view->GetVisible());
EXPECT_FALSE(go_to_question_answer_button->GetVisible());
}
TEST_F(MahiPanelViewTest, ScrollViewContentsDynamicSize) {
auto* const summary_outlines_section = panel_view()->GetViewByID(
mahi_constants::ViewId::kSummaryOutlinesSection);
auto* const question_answer_view =
panel_view()->GetViewByID(mahi_constants::ViewId::kQuestionAnswerView);
auto* const scroll_view_contents =
panel_view()->GetViewByID(mahi_constants::ViewId::kScrollViewContents);
summary_outlines_section->SetPreferredSize(gfx::Size(80, 300));
question_answer_view->SetPreferredSize(gfx::Size(80, 600));
views::test::RunScheduledLayout(widget());
EXPECT_TRUE(summary_outlines_section->GetVisible());
EXPECT_FALSE(question_answer_view->GetVisible());
EXPECT_EQ(summary_outlines_section->height() +
mahi_constants::kScrollContentsViewBottomPadding,
scroll_view_contents->GetPreferredSize().height());
SubmitTestQuestion(u"input");
views::test::RunScheduledLayout(widget());
EXPECT_FALSE(summary_outlines_section->GetVisible());
EXPECT_TRUE(question_answer_view->GetVisible());
EXPECT_EQ(question_answer_view->height() +
mahi_constants::kScrollContentsViewBottomPadding,
scroll_view_contents->GetPreferredSize().height());
LeftClickOn(panel_view()->GetViewByID(
mahi_constants::ViewId::kGoToSummaryOutlinesButton));
views::test::RunScheduledLayout(widget());
EXPECT_TRUE(summary_outlines_section->GetVisible());
EXPECT_FALSE(question_answer_view->GetVisible());
EXPECT_EQ(summary_outlines_section->height() +
mahi_constants::kScrollContentsViewBottomPadding,
scroll_view_contents->GetPreferredSize().height());
}
TEST_F(MahiPanelViewTest, QuestionTextfield_CreateQuestion) {
auto* const question_answer_view =
panel_view()->GetViewByID(mahi_constants::ViewId::kQuestionAnswerView);
auto* const send_button =
panel_view()->GetViewByID(mahi_constants::ViewId::kAskQuestionSendButton);
auto* const question_textfield = views::AsViewClass<views::Textfield>(
panel_view()->GetViewByID(mahi_constants::ViewId::kQuestionTextfield));
const std::u16string answer1(u"test answer1");
ON_CALL(mock_mahi_manager(), AnswerQuestion)
.WillByDefault(
[&answer1](
const std::u16string& question, bool current_panel_content,
chromeos::MahiManager::MahiAnswerQuestionCallback callback) {
std::move(callback).Run(answer1, MahiResponseStatus::kSuccess);
});
const std::u16string question1(u"question 1");
SubmitTestQuestion(question1);
ASSERT_EQ(2u, question_answer_view->children().size());
EXPECT_EQ(views::AsViewClass<views::Label>(
question_answer_view->children()[0]->GetViewByID(
mahi_constants::ViewId::kQuestionAnswerTextBubbleLabel))
->GetText(),
question1);
EXPECT_EQ(views::AsViewClass<views::Label>(
question_answer_view->children()[1]->GetViewByID(
mahi_constants::ViewId::kQuestionAnswerTextBubbleLabel))
->GetText(),
answer1);
EXPECT_TRUE(question_textfield->GetText().empty());
const std::u16string answer2(u"test answer2");
ON_CALL(mock_mahi_manager(), AnswerQuestion)
.WillByDefault(
[&answer2](
const std::u16string& question, bool current_panel_content,
chromeos::MahiManager::MahiAnswerQuestionCallback callback) {
std::move(callback).Run(answer2, MahiResponseStatus::kSuccess);
});
const std::u16string question2(u"question 2");
question_textfield->SetText(question2);
send_button->SetEnabled(true);
question_textfield->RequestFocus();
PressEnter();
ASSERT_EQ(question_answer_view->children().size(), 4u);
EXPECT_EQ(views::AsViewClass<views::Label>(
question_answer_view->children()[2]->GetViewByID(
mahi_constants::ViewId::kQuestionAnswerTextBubbleLabel))
->GetText(),
question2);
EXPECT_EQ(views::AsViewClass<views::Label>(
question_answer_view->children()[3]->GetViewByID(
mahi_constants::ViewId::kQuestionAnswerTextBubbleLabel))
->GetText(),
answer2);
EXPECT_TRUE(question_textfield->GetText().empty());
}
TEST_F(MahiPanelViewTest, QuestionTextfield_SendButtonState) {
base::test::TestFuture<void> answer_waiter;
EXPECT_CALL(mock_mahi_manager(), AnswerQuestion)
.WillOnce(
[&answer_waiter](
const std::u16string& question, bool current_panel_content,
chromeos::MahiManager::MahiAnswerQuestionCallback callback) {
ReturnDefaultAnswerAsyncly(answer_waiter,
MahiResponseStatus::kSuccess,
std::move(callback));
});
auto* const question_textfield = views::AsViewClass<views::Textfield>(
panel_view()->GetViewByID(mahi_constants::ViewId::kQuestionTextfield));
auto* const send_button =
panel_view()->GetViewByID(mahi_constants::ViewId::kAskQuestionSendButton);
ASSERT_TRUE(question_textfield);
ASSERT_TRUE(send_button);
EXPECT_TRUE(question_textfield->GetText().empty());
EXPECT_FALSE(send_button->GetEnabled());
question_textfield->RequestFocus();
ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
generator.PressKey(ui::KeyboardCode::VKEY_A, ui::EF_NONE);
EXPECT_EQ(question_textfield->GetText(), u"a");
EXPECT_TRUE(send_button->GetEnabled());
generator.PressKey(ui::KeyboardCode::VKEY_BACK, ui::EF_NONE);
EXPECT_TRUE(question_textfield->GetText().empty());
EXPECT_FALSE(send_button->GetEnabled());
generator.PressKey(ui::KeyboardCode::VKEY_A, ui::EF_NONE);
EXPECT_TRUE(send_button->GetEnabled());
LeftClickOn(send_button);
EXPECT_TRUE(question_textfield->GetText().empty());
EXPECT_FALSE(send_button->GetEnabled());
generator.PressKey(ui::KeyboardCode::VKEY_B, ui::EF_NONE);
EXPECT_EQ(question_textfield->GetText(), u"b");
EXPECT_FALSE(send_button->GetEnabled());
LeftClickOn(send_button);
question_textfield->RequestFocus();
PressEnter();
ASSERT_TRUE(answer_waiter.Wait());
EXPECT_EQ(question_textfield->GetText(), u"b");
EXPECT_TRUE(send_button->GetEnabled());
Mock::VerifyAndClearExpectations(&mock_mahi_manager());
EXPECT_CALL(mock_mahi_manager(), AnswerQuestion);
PressEnter();
EXPECT_TRUE(question_textfield->GetText().empty());
EXPECT_FALSE(send_button->GetEnabled());
Mock::VerifyAndClearExpectations(&mock_mahi_manager());
}
TEST_F(MahiPanelViewTest, QuestionTextfield_EmptyInput) {
auto* const question_textfield = views::AsViewClass<views::Textfield>(
panel_view()->GetViewByID(mahi_constants::ViewId::kQuestionTextfield));
ASSERT_TRUE(question_textfield);
EXPECT_TRUE(question_textfield->GetText().empty());
auto* const send_button =
panel_view()->GetViewByID(mahi_constants::ViewId::kAskQuestionSendButton);
ASSERT_TRUE(send_button);
EXPECT_FALSE(send_button->GetEnabled());
send_button->SetEnabled(true);
LeftClickOn(send_button);
const auto* const question_answer_view =
panel_view()->GetViewByID(mahi_constants::ViewId::kQuestionAnswerView);
ASSERT_TRUE(question_answer_view);
EXPECT_TRUE(question_answer_view->children().empty());
SubmitTestQuestion(u" ");
EXPECT_TRUE(question_answer_view->children().empty());
}
TEST_F(MahiPanelViewTest, QuestionTextfield_TrimWhitespace) {
ON_CALL(mock_mahi_manager(), AnswerQuestion)
.WillByDefault(
[](const std::u16string& question, bool current_panel_content,
chromeos::MahiManager::MahiAnswerQuestionCallback callback) {
std::move(callback).Run(u"fake answer",
MahiResponseStatus::kSuccess);
});
SubmitTestQuestion(u" leading and trailing ");
auto* const question_answer_view =
panel_view()->GetViewByID(mahi_constants::ViewId::kQuestionAnswerView);
ASSERT_TRUE(question_answer_view);
ASSERT_EQ(question_answer_view->children().size(), 2u);
EXPECT_EQ(u"leading and trailing",
views::AsViewClass<views::Label>(
question_answer_view->children()[0]->GetViewByID(
mahi_constants::ViewId::kQuestionAnswerTextBubbleLabel))
->GetText());
const std::u16string question_text(u"whitespace between");
SubmitTestQuestion(question_text);
ASSERT_EQ(question_answer_view->children().size(), 4u);
EXPECT_EQ(views::AsViewClass<views::Label>(
question_answer_view->children()[2]->GetViewByID(
mahi_constants::ViewId::kQuestionAnswerTextBubbleLabel))
->GetText(),
question_text);
}
TEST_F(MahiPanelViewTest, AnswerLoadingAnimation) {
base::test::TestFuture<void> answer_waiter;
ON_CALL(mock_mahi_manager(), AnswerQuestion)
.WillByDefault(
[&answer_waiter](
const std::u16string& question, bool current_panel_content,
chromeos::MahiManager::MahiAnswerQuestionCallback callback) {
ReturnDefaultAnswerAsyncly(answer_waiter,
MahiResponseStatus::kSuccess,
std::move(callback));
});
SubmitTestQuestion();
auto* const question_answer_view =
panel_view()->GetViewByID(mahi_constants::ViewId::kQuestionAnswerView);
ASSERT_TRUE(question_answer_view);
EXPECT_EQ(question_answer_view->children().size(), 2u);
EXPECT_TRUE(question_answer_view->children()[0]->GetViewByID(
mahi_constants::ViewId::kQuestionAnswerTextBubbleLabel));
EXPECT_TRUE(question_answer_view->children()[1]->GetViewByID(
mahi_constants::ViewId::kAnswerLoadingAnimatedImage));
ASSERT_TRUE(answer_waiter.WaitAndClear());
EXPECT_EQ(question_answer_view->children().size(), 2u);
EXPECT_TRUE(question_answer_view->children()[0]->GetViewByID(
mahi_constants::ViewId::kQuestionAnswerTextBubbleLabel));
EXPECT_TRUE(question_answer_view->children()[1]->GetViewByID(
mahi_constants::ViewId::kQuestionAnswerTextBubbleLabel));
EXPECT_FALSE(panel_view()->GetViewByID(
mahi_constants::ViewId::kAnswerLoadingAnimatedImage));
SubmitTestQuestion();
EXPECT_EQ(question_answer_view->children().size(), 4u);
EXPECT_TRUE(question_answer_view->children()[2]->GetViewByID(
mahi_constants::ViewId::kQuestionAnswerTextBubbleLabel));
EXPECT_TRUE(question_answer_view->children()[3]->GetViewByID(
mahi_constants::ViewId::kAnswerLoadingAnimatedImage));
ASSERT_TRUE(answer_waiter.WaitAndClear());
EXPECT_EQ(question_answer_view->children().size(), 4u);
EXPECT_TRUE(question_answer_view->children()[2]->GetViewByID(
mahi_constants::ViewId::kQuestionAnswerTextBubbleLabel));
EXPECT_TRUE(question_answer_view->children()[3]->GetViewByID(
mahi_constants::ViewId::kQuestionAnswerTextBubbleLabel));
EXPECT_FALSE(panel_view()->GetViewByID(
mahi_constants::ViewId::kAnswerLoadingAnimatedImage));
}
TEST_F(MahiPanelViewTest, ScrollViewScrollsAfterLayout) {
ON_CALL(mock_mahi_manager(), GetSummary).WillByDefault(ReturnLongSummary);
ON_CALL(mock_mahi_manager(), AnswerQuestion)
.WillByDefault(
[](const std::u16string& question, bool current_panel_content,
chromeos::MahiManager::MahiAnswerQuestionCallback callback) {
std::move(callback).Run(u"answer",
MahiResponseStatus::kSuccess);
});
CreatePanelWidget();
const auto* const summary_outlines_section = panel_view()->GetViewByID(
mahi_constants::ViewId::kSummaryOutlinesSection);
ASSERT_TRUE(summary_outlines_section);
EXPECT_TRUE(summary_outlines_section->GetVisible());
auto* const scroll_view = views::AsViewClass<views::ScrollView>(
panel_view()->GetViewByID(mahi_constants::ViewId::kScrollView));
ASSERT_TRUE(scroll_view);
auto* const scroll_bar = scroll_view->vertical_scroll_bar();
ASSERT_TRUE(scroll_bar);
EXPECT_TRUE(scroll_bar->GetVisible());
SubmitTestQuestion(u"question");
const auto* const question_answer_view =
panel_view()->GetViewByID(mahi_constants::ViewId::kQuestionAnswerView);
ASSERT_TRUE(question_answer_view);
ASSERT_TRUE(question_answer_view->GetVisible());
views::test::RunScheduledLayout(widget());
EXPECT_FALSE(scroll_bar->GetVisible());
while (!scroll_bar->GetVisible()) {
SubmitTestQuestion(u"question");
views::test::RunScheduledLayout(widget());
}
int previous_scroll_bar_position = scroll_bar->GetPosition();
SubmitTestQuestion(u"question");
views::test::RunScheduledLayout(widget());
EXPECT_GT(scroll_bar->GetPosition(), previous_scroll_bar_position);
previous_scroll_bar_position = scroll_bar->GetPosition();
scroll_bar->ScrollByAmount(views::ScrollBar::ScrollAmount::kEnd);
EXPECT_EQ(scroll_bar->GetPosition(), previous_scroll_bar_position);
const auto* const go_to_summary_outlines_button = panel_view()->GetViewByID(
mahi_constants::ViewId::kGoToSummaryOutlinesButton);
ASSERT_TRUE(go_to_summary_outlines_button);
LeftClickOn(go_to_summary_outlines_button);
views::test::RunScheduledLayout(widget());
EXPECT_TRUE(summary_outlines_section->GetVisible());
ASSERT_TRUE(scroll_bar->GetVisible());
EXPECT_LT(scroll_bar->GetPosition(), previous_scroll_bar_position);
previous_scroll_bar_position = scroll_bar->GetPosition();
scroll_bar->ScrollByAmount(views::ScrollBar::ScrollAmount::kStart);
EXPECT_EQ(scroll_bar->GetPosition(), previous_scroll_bar_position);
scroll_bar->ScrollByAmount(views::ScrollBar::ScrollAmount::kEnd);
EXPECT_GT(scroll_bar->GetPosition(), previous_scroll_bar_position);
previous_scroll_bar_position = scroll_bar->GetPosition();
ui_controller()->RefreshContents();
views::test::RunScheduledLayout(widget());
EXPECT_LT(scroll_bar->GetPosition(), previous_scroll_bar_position);
previous_scroll_bar_position = scroll_bar->GetPosition();
scroll_bar->ScrollByAmount(views::ScrollBar::ScrollAmount::kStart);
EXPECT_EQ(scroll_bar->GetPosition(), previous_scroll_bar_position);
}
TEST_F(MahiPanelViewTest, FailToGetAnswer) {
for (MahiResponseStatus error : GetMahiErrors()) {
base::test::TestFuture<void> answer_waiter;
EXPECT_CALL(mock_mahi_manager(), AnswerQuestion)
.WillOnce(
[&answer_waiter, error](
const std::u16string& question, bool current_panel_content,
chromeos::MahiManager::MahiAnswerQuestionCallback callback) {
ReturnDefaultAnswerAsyncly(answer_waiter, error,
std::move(callback));
});
base::HistogramTester histogram_tester;
const std::u16string question(u"A question that brings errors");
SubmitTestQuestion(question);
histogram_tester.ExpectBucketCount(
mahi_constants::kMahiQuestionSourceHistogramName,
MahiUiController::QuestionSource::kPanel, 1);
Mock::VerifyAndClearExpectations(&mock_mahi_manager());
const auto* const question_answer_view =
panel_view()->GetViewByID(mahi_constants::ViewId::kQuestionAnswerView);
CHECK(question_answer_view);
EXPECT_TRUE(question_answer_view->GetVisible());
EXPECT_TRUE(question_answer_view->GetViewByID(
mahi_constants::ViewId::kAnswerLoadingAnimatedImage));
const auto* const summary_outlines_section = panel_view()->GetViewByID(
mahi_constants::ViewId::kSummaryOutlinesSection);
CHECK(summary_outlines_section);
EXPECT_FALSE(summary_outlines_section->GetVisible());
auto* error_label_view =
views::AsViewClass<views::Label>(panel_view()->GetViewByID(
mahi_constants::ViewId::kQuestionAnswerErrorLabel));
EXPECT_EQ(nullptr, error_label_view);
auto* const question_textfield = views::AsViewClass<views::Textfield>(
panel_view()->GetViewByID(mahi_constants::ViewId::kQuestionTextfield));
auto* const send_button = panel_view()->GetViewByID(
mahi_constants::ViewId::kAskQuestionSendButton);
question_textfield->RequestFocus();
ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
generator.PressKey(ui::KeyboardCode::VKEY_A, ui::EF_NONE);
EXPECT_EQ(question_textfield->GetText(), u"a");
EXPECT_FALSE(send_button->GetEnabled());
ASSERT_TRUE(answer_waiter.WaitAndClear());
EXPECT_TRUE(question_answer_view->GetVisible());
EXPECT_FALSE(summary_outlines_section->GetVisible());
error_label_view =
views::AsViewClass<views::Label>(panel_view()->GetViewByID(
mahi_constants::ViewId::kQuestionAnswerErrorLabel));
EXPECT_TRUE(error_label_view->GetVisible());
EXPECT_EQ(
error_label_view->GetText(),
l10n_util::GetStringUTF16(mahi_utils::GetErrorStatusViewTextId(error)));
EXPECT_TRUE(send_button->GetEnabled());
EXPECT_FALSE(question_answer_view->GetViewByID(
mahi_constants::ViewId::kAnswerLoadingAnimatedImage));
EXPECT_CALL(mock_mahi_manager(), AnswerQuestion)
.WillOnce(
[&answer_waiter](
const std::u16string& question, bool current_panel_content,
chromeos::MahiManager::MahiAnswerQuestionCallback callback) {
ReturnDefaultAnswerAsyncly(answer_waiter,
MahiResponseStatus::kSuccess,
std::move(callback));
});
SubmitTestQuestion(u"A new question");
Mock::VerifyAndClearExpectations(&mock_mahi_manager());
EXPECT_TRUE(question_answer_view->GetViewByID(
mahi_constants::ViewId::kAnswerLoadingAnimatedImage));
EXPECT_TRUE(panel_view()->GetViewByID(
mahi_constants::ViewId::kQuestionAnswerErrorImage));
EXPECT_TRUE(panel_view()->GetViewByID(
mahi_constants::ViewId::kQuestionAnswerErrorLabel));
ASSERT_TRUE(answer_waiter.WaitAndClear());
EXPECT_TRUE(question_answer_view->GetVisible());
EXPECT_TRUE(panel_view()->GetViewByID(
mahi_constants::ViewId::kQuestionAnswerErrorImage));
EXPECT_TRUE(panel_view()->GetViewByID(
mahi_constants::ViewId::kQuestionAnswerErrorLabel));
EXPECT_EQ(question_answer_view->children().size(), 4u);
EXPECT_EQ(views::AsViewClass<views::Label>(
question_answer_view->children()[3]->GetViewByID(
mahi_constants::ViewId::kQuestionAnswerTextBubbleLabel))
->GetText(),
u"fake answer");
EXPECT_CALL(mock_mahi_manager(), AnswerQuestion)
.WillOnce(
[&answer_waiter, error](
const std::u16string& question, bool current_panel_content,
chromeos::MahiManager::MahiAnswerQuestionCallback callback) {
ReturnDefaultAnswerAsyncly(answer_waiter, error,
std::move(callback));
});
SubmitTestQuestion(u"A new question that brings errors");
Mock::VerifyAndClearExpectations(&mock_mahi_manager());
ASSERT_TRUE(answer_waiter.WaitAndClear());
EXPECT_EQ(question_answer_view->children().size(), 6u);
EXPECT_EQ(question_answer_view->children()[5]->children()[0]->GetID(),
mahi_constants::ViewId::kQuestionAnswerErrorImage);
EXPECT_EQ(question_answer_view->children()[5]->children()[1]->GetID(),
mahi_constants::ViewId::kQuestionAnswerErrorLabel);
EXPECT_EQ(
views::AsViewClass<views::Label>(
question_answer_view->children()[5]->GetViewByID(
mahi_constants::ViewId::kQuestionAnswerErrorLabel))
->GetText(),
l10n_util::GetStringUTF16(mahi_utils::GetErrorStatusViewTextId(error)));
CreatePanelWidget();
}
}
TEST_F(MahiPanelViewTest, GetAnswerWithLowQuotaWarning) {
base::test::TestFuture<void> answer_waiter;
EXPECT_CALL(mock_mahi_manager(), AnswerQuestion)
.WillOnce(
[&answer_waiter](
const std::u16string& question, bool current_panel_content,
chromeos::MahiManager::MahiAnswerQuestionCallback callback) {
ReturnDefaultAnswerAsyncly(answer_waiter,
MahiResponseStatus::kLowQuota,
std::move(callback));
});
SubmitTestQuestion();
Mock::VerifyAndClearExpectations(&mock_mahi_manager());
const auto* const question_answer_view =
panel_view()->GetViewByID(mahi_constants::ViewId::kQuestionAnswerView);
CHECK(question_answer_view);
EXPECT_TRUE(question_answer_view->GetVisible());
EXPECT_TRUE(question_answer_view->GetViewByID(
mahi_constants::ViewId::kAnswerLoadingAnimatedImage));
const auto* const summary_outlines_section = panel_view()->GetViewByID(
mahi_constants::ViewId::kSummaryOutlinesSection);
CHECK(summary_outlines_section);
EXPECT_FALSE(summary_outlines_section->GetVisible());
const auto* const error_status_view =
panel_view()->GetViewByID(mahi_constants::ViewId::kErrorStatusView);
CHECK(error_status_view);
EXPECT_FALSE(error_status_view->GetVisible());
ASSERT_TRUE(answer_waiter.Wait());
EXPECT_FALSE(error_status_view->GetVisible());
EXPECT_TRUE(question_answer_view->GetVisible());
EXPECT_FALSE(summary_outlines_section->GetVisible());
ASSERT_EQ(question_answer_view->children().size(), 2u);
EXPECT_EQ(views::AsViewClass<views::Label>(
question_answer_view->children()[1]->GetViewByID(
mahi_constants::ViewId::kQuestionAnswerTextBubbleLabel))
->GetText(),
u"fake answer");
}
TEST_F(MahiPanelViewTest, FailToGetOutlines) {
for (MahiResponseStatus error : GetMahiErrors()) {
base::test::TestFuture<void> outlines_waiter;
EXPECT_CALL(mock_mahi_manager(), GetOutlines)
.WillOnce([&outlines_waiter, error](
chromeos::MahiManager::MahiOutlinesCallback callback) {
ReturnDefaultOutlinesAsyncly(outlines_waiter, error,
std::move(callback));
});
CreatePanelWidget();
Mock::VerifyAndClear(&mock_mahi_manager());
const auto* const question_answer_view =
panel_view()->GetViewByID(mahi_constants::ViewId::kQuestionAnswerView);
CHECK(question_answer_view);
EXPECT_FALSE(question_answer_view->GetVisible());
const auto* const summary_outlines_section = panel_view()->GetViewByID(
mahi_constants::ViewId::kSummaryOutlinesSection);
CHECK(summary_outlines_section);
EXPECT_TRUE(summary_outlines_section->GetVisible());
const auto* const error_status_view =
panel_view()->GetViewByID(mahi_constants::ViewId::kErrorStatusView);
CHECK(error_status_view);
EXPECT_FALSE(error_status_view->GetVisible());
const auto* const error_status_label = views::AsViewClass<views::Label>(
panel_view()->GetViewByID(mahi_constants::ViewId::kErrorStatusLabel));
CHECK(error_status_label);
EXPECT_TRUE(error_status_label->GetText().empty());
ASSERT_TRUE(outlines_waiter.Wait());
EXPECT_TRUE(error_status_view->GetVisible());
EXPECT_FALSE(question_answer_view->GetVisible());
EXPECT_FALSE(summary_outlines_section->GetVisible());
EXPECT_EQ(
error_status_label->GetText(),
l10n_util::GetStringUTF16(mahi_utils::GetErrorStatusViewTextId(error)));
const auto* const retry_link =
panel_view()->GetViewByID(mahi_constants::kErrorStatusRetryLink);
ASSERT_TRUE(retry_link);
EXPECT_EQ(retry_link->GetVisible(),
mahi_utils::CalculateRetryLinkVisible(error));
if (retry_link->GetVisible()) {
views::test::RunScheduledLayout(widget());
GetEventGenerator()->MoveMouseTo(
retry_link->GetBoundsInScreen().CenterPoint());
EXPECT_CALL(mock_mahi_manager(), GetSummary);
EXPECT_CALL(mock_mahi_manager(), GetOutlines);
EXPECT_CALL(mock_mahi_manager(), AnswerQuestion).Times(0);
GetEventGenerator()->ClickLeftButton();
Mock::VerifyAndClear(&mock_mahi_manager());
}
}
}
TEST_F(MahiPanelViewTest, GetOutlinesWithLowQuotaWarning) {
base::test::TestFuture<void> outlines_waiter;
EXPECT_CALL(mock_mahi_manager(), GetOutlines)
.WillOnce([&outlines_waiter](
chromeos::MahiManager::MahiOutlinesCallback callback) {
ReturnDefaultOutlinesAsyncly(outlines_waiter,
MahiResponseStatus::kLowQuota,
std::move(callback));
});
CreatePanelWidget();
Mock::VerifyAndClear(&mock_mahi_manager());
const auto* const question_answer_view =
panel_view()->GetViewByID(mahi_constants::ViewId::kQuestionAnswerView);
CHECK(question_answer_view);
EXPECT_FALSE(question_answer_view->GetVisible());
const auto* const summary_outlines_section = panel_view()->GetViewByID(
mahi_constants::ViewId::kSummaryOutlinesSection);
CHECK(summary_outlines_section);
EXPECT_TRUE(summary_outlines_section->GetVisible());
const auto* const error_status_view =
panel_view()->GetViewByID(mahi_constants::ViewId::kErrorStatusView);
CHECK(error_status_view);
EXPECT_FALSE(error_status_view->GetVisible());
ASSERT_TRUE(outlines_waiter.Wait());
EXPECT_FALSE(error_status_view->GetVisible());
EXPECT_FALSE(question_answer_view->GetVisible());
EXPECT_TRUE(summary_outlines_section->GetVisible());
}
TEST_F(MahiPanelViewTest, FailToGetSummary) {
for (MahiResponseStatus error : GetMahiErrors()) {
base::test::TestFuture<void> summary_waiter;
EXPECT_CALL(mock_mahi_manager(), GetSummary)
.WillOnce([&summary_waiter,
error](chromeos::MahiManager::MahiSummaryCallback callback) {
ReturnDefaultSummaryAsyncly(summary_waiter, error,
std::move(callback));
});
CreatePanelWidget();
Mock::VerifyAndClear(&mock_mahi_manager());
const auto* const question_answer_view =
panel_view()->GetViewByID(mahi_constants::ViewId::kQuestionAnswerView);
CHECK(question_answer_view);
EXPECT_FALSE(question_answer_view->GetVisible());
const auto* const summary_outlines_section = panel_view()->GetViewByID(
mahi_constants::ViewId::kSummaryOutlinesSection);
CHECK(summary_outlines_section);
EXPECT_TRUE(summary_outlines_section->GetVisible());
const auto* const error_status_view =
panel_view()->GetViewByID(mahi_constants::ViewId::kErrorStatusView);
CHECK(error_status_view);
EXPECT_FALSE(error_status_view->GetVisible());
const auto* const error_status_label = views::AsViewClass<views::Label>(
panel_view()->GetViewByID(mahi_constants::ViewId::kErrorStatusLabel));
CHECK(error_status_label);
EXPECT_TRUE(error_status_label->GetText().empty());
ASSERT_TRUE(summary_waiter.Wait());
EXPECT_TRUE(error_status_view->GetVisible());
EXPECT_FALSE(question_answer_view->GetVisible());
EXPECT_FALSE(summary_outlines_section->GetVisible());
EXPECT_EQ(
error_status_label->GetText(),
l10n_util::GetStringUTF16(mahi_utils::GetErrorStatusViewTextId(error)));
const auto* const retry_link =
panel_view()->GetViewByID(mahi_constants::kErrorStatusRetryLink);
ASSERT_TRUE(retry_link);
EXPECT_EQ(retry_link->GetVisible(),
mahi_utils::CalculateRetryLinkVisible(error));
if (retry_link->GetVisible()) {
views::test::RunScheduledLayout(widget());
GetEventGenerator()->MoveMouseTo(
retry_link->GetBoundsInScreen().CenterPoint());
EXPECT_CALL(mock_mahi_manager(), GetSummary);
EXPECT_CALL(mock_mahi_manager(), GetOutlines);
EXPECT_CALL(mock_mahi_manager(), AnswerQuestion).Times(0);
GetEventGenerator()->ClickLeftButton();
Mock::VerifyAndClear(&mock_mahi_manager());
}
}
}
TEST_F(MahiPanelViewTest, GetSummaryWithLowQuotaWarning) {
base::test::TestFuture<void> summary_waiter;
EXPECT_CALL(mock_mahi_manager(), GetSummary)
.WillOnce([&summary_waiter](
chromeos::MahiManager::MahiSummaryCallback callback) {
ReturnDefaultSummaryAsyncly(
summary_waiter, MahiResponseStatus::kLowQuota, std::move(callback));
});
CreatePanelWidget();
Mock::VerifyAndClear(&mock_mahi_manager());
const auto* const question_answer_view =
panel_view()->GetViewByID(mahi_constants::ViewId::kQuestionAnswerView);
CHECK(question_answer_view);
EXPECT_FALSE(question_answer_view->GetVisible());
const auto* const summary_outlines_section = panel_view()->GetViewByID(
mahi_constants::ViewId::kSummaryOutlinesSection);
CHECK(summary_outlines_section);
EXPECT_TRUE(summary_outlines_section->GetVisible());
const auto* const error_status_view =
panel_view()->GetViewByID(mahi_constants::ViewId::kErrorStatusView);
CHECK(error_status_view);
EXPECT_FALSE(error_status_view->GetVisible());
ASSERT_TRUE(summary_waiter.Wait());
EXPECT_FALSE(error_status_view->GetVisible());
EXPECT_FALSE(question_answer_view->GetVisible());
EXPECT_TRUE(summary_outlines_section->GetVisible());
const auto* const summary_label = GetSummaryLabel(panel_view());
ASSERT_TRUE(summary_label);
EXPECT_TRUE(summary_label->GetVisible());
}
TEST_F(MahiPanelViewTest, RefreshSummaryContents) {
const std::u16string title1(u"Test content title");
const std::u16string summary1(u"Short summary");
const auto icon1(gfx::test::CreateImageSkia(128, SK_ColorBLUE));
ON_CALL(mock_mahi_manager(), GetContentTitle).WillByDefault(Return(title1));
ON_CALL(mock_mahi_manager(), GetContentIcon).WillByDefault(Return(icon1));
ON_CALL(mock_mahi_manager(), GetSummary)
.WillByDefault(
[&summary1](chromeos::MahiManager::MahiSummaryCallback callback) {
std::move(callback).Run(summary1,
chromeos::MahiResponseStatus::kSuccess);
});
MahiPanelView mahi_view(ui_controller());
EXPECT_EQ(GetContentSourceTitle(&mahi_view), title1);
EXPECT_TRUE(gfx::test::AreBitmapsEqual(
*GetContentSourceIcon(&mahi_view).bitmap(),
*image_util::ResizeAndCropImage(icon1, mahi_constants::kContentIconSize)
.bitmap()));
EXPECT_EQ(GetSummaryLabel(&mahi_view)->GetText(), summary1);
const std::u16string title2(u"Test content title 2");
const std::u16string summary2(u"Short summary 2");
const auto icon2(gfx::test::CreateImageSkia(128, SK_ColorRED));
ON_CALL(mock_mahi_manager(), GetContentTitle).WillByDefault(Return(title2));
ON_CALL(mock_mahi_manager(), GetContentIcon).WillByDefault(Return(icon2));
ON_CALL(mock_mahi_manager(), GetSummary)
.WillByDefault(
[&summary2](chromeos::MahiManager::MahiSummaryCallback callback) {
std::move(callback).Run(summary2,
chromeos::MahiResponseStatus::kSuccess);
});
ui_controller()->RefreshContents();
EXPECT_EQ(GetContentSourceTitle(&mahi_view), title2);
EXPECT_TRUE(gfx::test::AreBitmapsEqual(
*GetContentSourceIcon(&mahi_view).bitmap(),
*image_util::ResizeAndCropImage(icon2, mahi_constants::kContentIconSize)
.bitmap()));
EXPECT_EQ(GetSummaryLabel(&mahi_view)->GetText(), summary2);
}
TEST_F(MahiPanelViewTest, ContentSourceButtonUrlAfterRefresh) {
const GURL test_url1("https://www.google.com");
ON_CALL(mock_mahi_manager(), GetContentUrl).WillByDefault(Return(test_url1));
CreatePanelWidget();
EXPECT_CALL(
new_window_delegate(),
OpenUrl(test_url1, NewWindowDelegate::OpenUrlFrom::kUserInteraction,
NewWindowDelegate::Disposition::kSwitchToTab));
LeftClickOn(
panel_view()->GetViewByID(mahi_constants::ViewId::kContentSourceButton));
Mock::VerifyAndClearExpectations(&new_window_delegate());
const GURL test_url2("https://en.wikipedia.org");
ON_CALL(mock_mahi_manager(), GetContentUrl).WillByDefault(Return(test_url2));
ui_controller()->RefreshContents();
EXPECT_CALL(
new_window_delegate(),
OpenUrl(test_url2, NewWindowDelegate::OpenUrlFrom::kUserInteraction,
NewWindowDelegate::Disposition::kSwitchToTab));
LeftClickOn(
panel_view()->GetViewByID(mahi_constants::ViewId::kContentSourceButton));
Mock::VerifyAndClearExpectations(&new_window_delegate());
}
TEST_F(MahiPanelViewTest, RefreshSummaryContents_TransitionToSummaryView) {
ON_CALL(mock_mahi_manager(), AnswerQuestion)
.WillByDefault(
[](const std::u16string& question, bool current_panel_content,
chromeos::MahiManager::MahiAnswerQuestionCallback callback) {
std::move(callback).Run(u"answer",
chromeos::MahiResponseStatus::kSuccess);
});
const auto* const summary_outlines_section = panel_view()->GetViewByID(
mahi_constants::ViewId::kSummaryOutlinesSection);
const auto* const question_answer_view =
panel_view()->GetViewByID(mahi_constants::ViewId::kQuestionAnswerView);
SubmitTestQuestion();
EXPECT_FALSE(summary_outlines_section->GetVisible());
EXPECT_TRUE(question_answer_view->GetVisible());
EXPECT_EQ(question_answer_view->children().size(), 2u);
ui_controller()->RefreshContents();
EXPECT_TRUE(summary_outlines_section->GetVisible());
EXPECT_FALSE(question_answer_view->GetVisible());
EXPECT_TRUE(question_answer_view->children().empty());
}
TEST_F(MahiPanelViewTest, ClickMetrics) {
base::HistogramTester histogram;
histogram.ExpectBucketCount(mahi_constants::kMahiButtonClickHistogramName,
mahi_constants::PanelButton::kLearnMoreLink, 0);
views::test::RunScheduledLayout(widget());
views::AsViewClass<views::StyledLabel>(
panel_view()->GetViewByID(mahi_constants::ViewId::kFooterLabel))
->ClickFirstLinkForTesting();
histogram.ExpectBucketCount(mahi_constants::kMahiButtonClickHistogramName,
mahi_constants::PanelButton::kLearnMoreLink, 1);
histogram.ExpectTotalCount(mahi_constants::kMahiButtonClickHistogramName, 1);
auto* const send_button =
panel_view()->GetViewByID(mahi_constants::ViewId::kAskQuestionSendButton);
auto* const back_to_summary_outlines_button = panel_view()->GetViewByID(
mahi_constants::ViewId::kGoToSummaryOutlinesButton);
auto* const back_to_question_answer_button = panel_view()->GetViewByID(
mahi_constants::ViewId::kGoToQuestionAndAnswerButton);
views::test::RunScheduledLayout(widget());
LeftClickOn(send_button);
histogram.ExpectBucketCount(
mahi_constants::kMahiButtonClickHistogramName,
mahi_constants::PanelButton::kAskQuestionSendButton, 0);
histogram.ExpectTotalCount(mahi_constants::kMahiButtonClickHistogramName, 1);
EXPECT_FALSE(back_to_summary_outlines_button->GetVisible());
SubmitTestQuestion(u"question text");
histogram.ExpectBucketCount(
mahi_constants::kMahiButtonClickHistogramName,
mahi_constants::PanelButton::kAskQuestionSendButton, 1);
histogram.ExpectTotalCount(mahi_constants::kMahiButtonClickHistogramName, 2);
EXPECT_TRUE(back_to_summary_outlines_button->GetVisible());
views::test::RunScheduledLayout(widget());
histogram.ExpectBucketCount(
mahi_constants::kMahiButtonClickHistogramName,
mahi_constants::PanelButton::kGoToSummaryOutlinesButton, 0);
LeftClickOn(back_to_summary_outlines_button);
histogram.ExpectBucketCount(
mahi_constants::kMahiButtonClickHistogramName,
mahi_constants::PanelButton::kGoToSummaryOutlinesButton, 1);
histogram.ExpectTotalCount(mahi_constants::kMahiButtonClickHistogramName, 3);
views::test::RunScheduledLayout(widget());
EXPECT_TRUE(back_to_question_answer_button->GetVisible());
histogram.ExpectBucketCount(
mahi_constants::kMahiButtonClickHistogramName,
mahi_constants::PanelButton::kGoToQuestionAndAnswerButton, 0);
LeftClickOn(back_to_question_answer_button);
histogram.ExpectBucketCount(
mahi_constants::kMahiButtonClickHistogramName,
mahi_constants::PanelButton::kGoToQuestionAndAnswerButton, 1);
histogram.ExpectTotalCount(mahi_constants::kMahiButtonClickHistogramName, 4);
views::test::RunScheduledLayout(widget());
histogram.ExpectBucketCount(mahi_constants::kMahiButtonClickHistogramName,
mahi_constants::PanelButton::kCloseButton, 0);
LeftClickOn(panel_view()->GetViewByID(mahi_constants::ViewId::kCloseButton));
histogram.ExpectBucketCount(mahi_constants::kMahiButtonClickHistogramName,
mahi_constants::PanelButton::kCloseButton, 1);
histogram.ExpectTotalCount(mahi_constants::kMahiButtonClickHistogramName, 5);
}
TEST_F(MahiPanelViewTest, UserJourneyTimeMetrics) {
base::HistogramTester histogram;
histogram.ExpectTimeBucketCount(
mahi_constants::kMahiUserJourneyTimeHistogramName, base::Seconds(3),
0);
task_environment()->AdvanceClock(base::Seconds(3));
CreatePanelWidget();
histogram.ExpectTimeBucketCount(
mahi_constants::kMahiUserJourneyTimeHistogramName, base::Seconds(3),
1);
task_environment()->AdvanceClock(base::Minutes(3));
CreatePanelWidget();
histogram.ExpectTimeBucketCount(
mahi_constants::kMahiUserJourneyTimeHistogramName, base::Minutes(3),
1);
task_environment()->AdvanceClock(base::Minutes(10));
CreatePanelWidget();
histogram.ExpectTimeBucketCount(
mahi_constants::kMahiUserJourneyTimeHistogramName, base::Minutes(10),
1);
}
TEST_F(MahiPanelViewTest, ReportQuestionCountWhenRefresh) {
ON_CALL(mock_mahi_manager(), AnswerQuestion)
.WillByDefault(
[](const std::u16string& question, bool current_panel_content,
chromeos::MahiManager::MahiAnswerQuestionCallback callback) {
std::move(callback).Run(u"answer",
chromeos::MahiResponseStatus::kSuccess);
});
base::HistogramTester histogram_tester;
SubmitTestQuestion();
histogram_tester.ExpectBucketCount(
mahi_constants::kQuestionCountPerMahiSessionHistogramName, 1,
0);
ui_controller()->RefreshContents();
histogram_tester.ExpectBucketCount(
mahi_constants::kQuestionCountPerMahiSessionHistogramName, 1,
1);
SubmitTestQuestion();
SubmitTestQuestion();
histogram_tester.ExpectBucketCount(
mahi_constants::kQuestionCountPerMahiSessionHistogramName, 1,
1);
histogram_tester.ExpectBucketCount(
mahi_constants::kQuestionCountPerMahiSessionHistogramName, 2,
0);
ui_controller()->RefreshContents();
histogram_tester.ExpectBucketCount(
mahi_constants::kQuestionCountPerMahiSessionHistogramName, 2,
1);
}
TEST_F(MahiPanelViewTest, ReportQuestionCountWhenMahiPanelDestroyed) {
ON_CALL(mock_mahi_manager(), AnswerQuestion)
.WillByDefault(
[](const std::u16string& question, bool current_panel_content,
chromeos::MahiManager::MahiAnswerQuestionCallback callback) {
std::move(callback).Run(u"answer",
chromeos::MahiResponseStatus::kSuccess);
});
base::HistogramTester histogram_tester;
SubmitTestQuestion();
histogram_tester.ExpectBucketCount(
mahi_constants::kQuestionCountPerMahiSessionHistogramName, 1,
0);
ResetPanelWidget();
histogram_tester.ExpectBucketCount(
mahi_constants::kQuestionCountPerMahiSessionHistogramName, 1,
1);
CreatePanelWidget();
SubmitTestQuestion();
SubmitTestQuestion();
histogram_tester.ExpectBucketCount(
mahi_constants::kQuestionCountPerMahiSessionHistogramName,
1,
1);
histogram_tester.ExpectBucketCount(
mahi_constants::kQuestionCountPerMahiSessionHistogramName,
2,
0);
ResetPanelWidget();
histogram_tester.ExpectBucketCount(
mahi_constants::kQuestionCountPerMahiSessionHistogramName,
2,
1);
}
TEST_F(MahiPanelViewTest, RandomizedTextSummaryLabel) {
auto random_string = GetRandomString(500);
ON_CALL(mock_mahi_manager(), GetSummary)
.WillByDefault(
[random_string](chromeos::MahiManager::MahiSummaryCallback callback) {
std::move(callback).Run(random_string,
chromeos::MahiResponseStatus::kSuccess);
});
ui_controller()->RefreshContents();
views::test::RunScheduledLayout(widget());
auto* summary_label = views::AsViewClass<views::Label>(
panel_view()->GetViewByID(mahi_constants::ViewId::kSummaryLabel));
EXPECT_FALSE(summary_label->IsDisplayTextClipped())
<< "Summary label is clipped with the text: " << random_string;
auto* scroll_view = views::AsViewClass<views::ScrollView>(
panel_view()->GetViewByID(mahi_constants::ViewId::kScrollView));
EXPECT_LE(summary_label->width(), scroll_view->GetVisibleRect().width())
<< "Summary label width surpasses scroll view visible width: "
<< random_string;
}
TEST_F(MahiPanelViewTest, RandomizedTextQuestionAnswerLabels) {
auto random_answer = GetRandomString(100);
ON_CALL(mock_mahi_manager(), AnswerQuestion)
.WillByDefault(
[&random_answer](
const std::u16string& question, bool current_panel_content,
chromeos::MahiManager::MahiAnswerQuestionCallback callback) {
std::move(callback).Run(random_answer,
chromeos::MahiResponseStatus::kSuccess);
});
auto random_question = GetRandomString(100);
SubmitTestQuestion(random_question);
views::test::RunScheduledLayout(widget());
auto* question_answer_view =
panel_view()->GetViewByID(mahi_constants::ViewId::kQuestionAnswerView);
auto* question_label = views::AsViewClass<views::Label>(
question_answer_view->children()[0]->GetViewByID(
mahi_constants::ViewId::kQuestionAnswerTextBubbleLabel));
EXPECT_FALSE(question_label->IsDisplayTextClipped())
<< "Question label is clipped with the text: " << random_question;
auto* scroll_view = views::AsViewClass<views::ScrollView>(
panel_view()->GetViewByID(mahi_constants::ViewId::kScrollView));
EXPECT_LE(question_label->width(), scroll_view->GetVisibleRect().width())
<< "Question label width surpasses scroll view visible width: "
<< random_answer;
auto* answer_label = views::AsViewClass<views::Label>(
question_answer_view->children()[1]->GetViewByID(
mahi_constants::ViewId::kQuestionAnswerTextBubbleLabel));
EXPECT_FALSE(answer_label->IsDisplayTextClipped())
<< "Answer label is clipped with the text: " << random_answer;
EXPECT_LE(answer_label->width(), scroll_view->GetVisibleRect().width())
<< "Answer label width surpasses scroll view visible width: "
<< random_answer;
}
TEST_F(MahiPanelViewTest, OnlyOneFeedbackButtonCanKeepToggled) {
IconButton* thumbs_up_button = views::AsViewClass<IconButton>(
panel_view()->GetViewByID(mahi_constants::ViewId::kThumbsUpButton));
IconButton* thumbs_down_button = views::AsViewClass<IconButton>(
panel_view()->GetViewByID(mahi_constants::ViewId::kThumbsDownButton));
EXPECT_FALSE(thumbs_up_button->toggled());
EXPECT_FALSE(thumbs_down_button->toggled());
LeftClickOn(thumbs_up_button);
EXPECT_TRUE(thumbs_up_button->toggled());
EXPECT_FALSE(thumbs_down_button->toggled());
LeftClickOn(thumbs_down_button);
EXPECT_TRUE(thumbs_down_button->toggled());
EXPECT_FALSE(thumbs_up_button->toggled());
LeftClickOn(thumbs_up_button);
EXPECT_TRUE(thumbs_up_button->toggled());
EXPECT_FALSE(thumbs_down_button->toggled());
}
TEST_F(MahiPanelViewTest, FeedbackButtonsAllowed) {
PrefService* prefs =
Shell::Get()->session_controller()->GetActivePrefService();
prefs->SetInteger(
prefs::kHmrManagedSettings,
static_cast<int>(
mahi_utils::HmrEnterprisePolicy::kAllowedWithoutModelImprovement));
CreatePanelWidget();
EXPECT_FALSE(
panel_view()
->GetViewByID(mahi_constants::ViewId::kFeedbackButtonsContainer)
->GetVisible());
EXPECT_EQ(
l10n_util::GetStringFUTF16(
IDS_ASH_MAHI_PANEL_DISCLAIMER_FEEDBACK_DISABLED,
l10n_util::GetStringUTF16(IDS_ASH_MAHI_LEARN_MORE_LINK_LABEL_TEXT)),
static_cast<views::StyledLabel*>(
panel_view()->GetViewByID(mahi_constants::ViewId::kFooterLabel))
->GetText());
prefs->SetInteger(
prefs::kHmrManagedSettings,
static_cast<int>(
mahi_utils::HmrEnterprisePolicy::kAllowedWithModelImprovement));
CreatePanelWidget();
EXPECT_TRUE(
panel_view()
->GetViewByID(mahi_constants::ViewId::kFeedbackButtonsContainer)
->GetVisible());
EXPECT_EQ(
l10n_util::GetStringFUTF16(
IDS_ASH_MAHI_PANEL_DISCLAIMER,
l10n_util::GetStringUTF16(IDS_ASH_MAHI_LEARN_MORE_LINK_LABEL_TEXT)),
static_cast<views::StyledLabel*>(
panel_view()->GetViewByID(mahi_constants::ViewId::kFooterLabel))
->GetText());
}
TEST_F(MahiPanelViewTest, FeedbackButtonResetWhenRefresh) {
IconButton* thumbs_up_button = views::AsViewClass<IconButton>(
panel_view()->GetViewByID(mahi_constants::ViewId::kThumbsUpButton));
IconButton* thumbs_down_button = views::AsViewClass<IconButton>(
panel_view()->GetViewByID(mahi_constants::ViewId::kThumbsDownButton));
EXPECT_FALSE(thumbs_up_button->toggled());
EXPECT_FALSE(thumbs_down_button->toggled());
LeftClickOn(thumbs_up_button);
EXPECT_TRUE(thumbs_up_button->toggled());
EXPECT_FALSE(thumbs_down_button->toggled());
ui_controller()->RefreshContents();
EXPECT_FALSE(thumbs_up_button->toggled());
EXPECT_FALSE(thumbs_down_button->toggled());
LeftClickOn(thumbs_down_button);
EXPECT_FALSE(thumbs_up_button->toggled());
EXPECT_TRUE(thumbs_down_button->toggled());
ui_controller()->RefreshContents();
EXPECT_FALSE(thumbs_up_button->toggled());
EXPECT_FALSE(thumbs_down_button->toggled());
}
TEST_F(MahiPanelViewTest, FeedbackButtonsOnError) {
base::HistogramTester histogram_tester;
base::test::TestFuture<void> summary_waiter;
EXPECT_CALL(mock_mahi_manager(), GetSummary)
.WillOnce([&summary_waiter](
chromeos::MahiManager::MahiSummaryCallback callback) {
ReturnDefaultSummaryAsyncly(summary_waiter,
MahiResponseStatus::kUnknownError,
std::move(callback));
});
CreatePanelWidget();
ASSERT_TRUE(summary_waiter.Wait());
EXPECT_CALL(mock_mahi_manager(), OpenFeedbackDialog).Times(0);
IconButton* thumbs_up_button = views::AsViewClass<IconButton>(
panel_view()->GetViewByID(mahi_constants::ViewId::kThumbsUpButton));
LeftClickOn(thumbs_up_button);
Mock::VerifyAndClearExpectations(&mock_mahi_manager());
EXPECT_TRUE(thumbs_up_button->toggled());
histogram_tester.ExpectBucketCount(mahi_constants::kMahiFeedbackHistogramName,
true, 1);
histogram_tester.ExpectBucketCount(mahi_constants::kMahiFeedbackHistogramName,
false, 0);
EXPECT_CALL(mock_mahi_manager(), OpenFeedbackDialog).Times(1);
IconButton* thumbs_down_button = views::AsViewClass<IconButton>(
panel_view()->GetViewByID(mahi_constants::ViewId::kThumbsDownButton));
LeftClickOn(thumbs_down_button);
Mock::VerifyAndClearExpectations(&mock_mahi_manager());
EXPECT_TRUE(thumbs_down_button->toggled());
histogram_tester.ExpectBucketCount(mahi_constants::kMahiFeedbackHistogramName,
true, 1);
histogram_tester.ExpectBucketCount(mahi_constants::kMahiFeedbackHistogramName,
false, 1);
}
}