1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ash/system/phonehub/task_continuation_view.h"
6
7 #include "ash/public/cpp/test/test_new_window_delegate.h"
8 #include "ash/system/phonehub/continue_browsing_chip.h"
9 #include "ash/test/ash_test_base.h"
10 #include "base/test/scoped_feature_list.h"
11 #include "chromeos/components/phonehub/fake_user_action_recorder.h"
12 #include "chromeos/components/phonehub/mutable_phone_model.h"
13 #include "chromeos/components/phonehub/phone_model_test_util.h"
14 #include "chromeos/constants/chromeos_features.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "ui/views/test/button_test_api.h"
17
18 namespace ash {
19
20 using BrowserTabsModel = chromeos::phonehub::BrowserTabsModel;
21
22 namespace {
23
24 class MockNewWindowDelegate : public testing::NiceMock<TestNewWindowDelegate> {
25 public:
26 // TestNewWindowDelegate:
27 MOCK_METHOD(void,
28 NewTabWithUrl,
29 (const GURL& url, bool from_user_interaction),
30 (override));
31 };
32
33 class DummyEvent : public ui::Event {
34 public:
DummyEvent()35 DummyEvent() : Event(ui::ET_UNKNOWN, base::TimeTicks(), 0) {}
36 };
37
38 } // namespace
39
40 class TaskContinuationViewTest : public AshTestBase {
41 public:
42 TaskContinuationViewTest() = default;
43 ~TaskContinuationViewTest() override = default;
44
45 // AshTestBase:
SetUp()46 void SetUp() override {
47 feature_list_.InitAndEnableFeature(chromeos::features::kPhoneHub);
48 AshTestBase::SetUp();
49
50 task_continuation_view_ = std::make_unique<TaskContinuationView>(
51 &phone_model_, &fake_user_action_recorder_);
52 }
53
TearDown()54 void TearDown() override {
55 task_continuation_view_.reset();
56 AshTestBase::TearDown();
57 }
58
59 protected:
task_view()60 TaskContinuationView* task_view() { return task_continuation_view_.get(); }
phone_model()61 chromeos::phonehub::MutablePhoneModel* phone_model() { return &phone_model_; }
new_window_delegate()62 MockNewWindowDelegate& new_window_delegate() { return new_window_delegate_; }
63
64 private:
65 std::unique_ptr<TaskContinuationView> task_continuation_view_;
66 chromeos::phonehub::FakeUserActionRecorder fake_user_action_recorder_;
67 chromeos::phonehub::MutablePhoneModel phone_model_;
68 base::test::ScopedFeatureList feature_list_;
69 MockNewWindowDelegate new_window_delegate_;
70 };
71
TEST_F(TaskContinuationViewTest,TaskViewVisibility)72 TEST_F(TaskContinuationViewTest, TaskViewVisibility) {
73 phone_model()->SetBrowserTabsModel(
74 BrowserTabsModel(false /* is_tab_sync_enabled */));
75 // The view should not be shown when tab sync is not enabled.
76 EXPECT_FALSE(task_view()->GetVisible());
77
78 phone_model()->SetBrowserTabsModel(
79 BrowserTabsModel(true /* is_tab_sync_enabled */));
80 // The view should not be shown when tab sync is enabled but no browser tabs
81 // open.
82 EXPECT_FALSE(task_view()->GetVisible());
83
84 BrowserTabsModel::BrowserTabMetadata metadata =
85 chromeos::phonehub::CreateFakeBrowserTabMetadata();
86
87 std::vector<BrowserTabsModel::BrowserTabMetadata> tabs = {metadata};
88
89 phone_model()->SetBrowserTabsModel(BrowserTabsModel(true, tabs));
90 // The view should be shown when there is one browser tab.
91 EXPECT_TRUE(task_view()->GetVisible());
92
93 tabs.push_back(metadata);
94 phone_model()->SetBrowserTabsModel(BrowserTabsModel(true, tabs));
95 // The view should be shown when there are two or more browser tabs.
96 EXPECT_TRUE(task_view()->GetVisible());
97 }
98
TEST_F(TaskContinuationViewTest,TaskChipsView)99 TEST_F(TaskContinuationViewTest, TaskChipsView) {
100 BrowserTabsModel::BrowserTabMetadata metadata =
101 chromeos::phonehub::CreateFakeBrowserTabMetadata();
102
103 std::vector<BrowserTabsModel::BrowserTabMetadata> tabs = {metadata};
104
105 phone_model()->SetBrowserTabsModel(BrowserTabsModel(true, tabs));
106 // The chips view should contains 1 tab.
107 size_t expected_tabs = 1;
108 EXPECT_EQ(expected_tabs, task_view()->chips_view_->children().size());
109
110 tabs.push_back(metadata);
111 phone_model()->SetBrowserTabsModel(BrowserTabsModel(true, tabs));
112 // The chips view should contains 2 tab.
113 expected_tabs = 2;
114 EXPECT_EQ(expected_tabs, task_view()->chips_view_->children().size());
115
116 for (auto* child : task_view()->chips_view_->children()) {
117 ContinueBrowsingChip* chip = static_cast<ContinueBrowsingChip*>(child);
118 // NewTabWithUrl is expected to call after button pressed simulation.
119 EXPECT_CALL(new_window_delegate(), NewTabWithUrl)
120 .WillOnce([](const GURL& url, bool from_user_interaction) {
121 EXPECT_EQ(GURL("https://www.example.com/tab1"), url);
122 EXPECT_TRUE(from_user_interaction);
123 });
124 // Simulate clicking button using dummy event.
125 views::test::ButtonTestApi(chip).NotifyClick(DummyEvent());
126 }
127 }
128
129 } // namespace ash
130