| // 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. |
| |
| #include "ash/glanceables/classroom/glanceables_classroom_item_view.h" |
| |
| #include <optional> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include "ash/glanceables/classroom/glanceables_classroom_types.h" |
| #include "ash/glanceables/common/glanceables_view_id.h" |
| #include "ash/shell.h" |
| #include "ash/system/model/system_tray_model.h" |
| #include "ash/system/time/calendar_unittest_utils.h" |
| #include "ash/test/ash_test_base.h" |
| #include "base/functional/callback_helpers.h" |
| #include "base/time/time.h" |
| #include "base/time/time_override.h" |
| #include "chromeos/ash/components/settings/scoped_timezone_settings.h" |
| #include "ui/views/accessibility/view_accessibility.h" |
| #include "ui/views/controls/image_view.h" |
| #include "ui/views/controls/label.h" |
| #include "ui/views/view_utils.h" |
| #include "url/gurl.h" |
| |
| namespace ash { |
| |
| class GlanceablesClassroomItemViewTest : public AshTestBase { |
| public: |
| const views::ImageView* GetIconView( |
| const GlanceablesClassroomItemView& view) const { |
| return views::AsViewClass<views::ImageView>(view.GetViewByID( |
| std::to_underlying(GlanceablesViewId::kClassroomItemIcon))); |
| } |
| |
| const views::Label* GetCourseWorkTitleLabel( |
| const GlanceablesClassroomItemView& view) const { |
| return views::AsViewClass<views::Label>(view.GetViewByID(std::to_underlying( |
| GlanceablesViewId::kClassroomItemCourseWorkTitleLabel))); |
| } |
| |
| const views::Label* GetCourseTitleLabel( |
| const GlanceablesClassroomItemView& view) const { |
| return views::AsViewClass<views::Label>(view.GetViewByID( |
| std::to_underlying(GlanceablesViewId::kClassroomItemCourseTitleLabel))); |
| } |
| |
| const views::Label* GetDueDateLabel( |
| const GlanceablesClassroomItemView& view) const { |
| return views::AsViewClass<views::Label>(view.GetViewByID( |
| std::to_underlying(GlanceablesViewId::kClassroomItemDueDateLabel))); |
| } |
| |
| const views::Label* GetDueTimeLabel( |
| const GlanceablesClassroomItemView& view) const { |
| return views::AsViewClass<views::Label>(view.GetViewByID( |
| std::to_underlying(GlanceablesViewId::kClassroomItemDueTimeLabel))); |
| } |
| }; |
| |
| TEST_F(GlanceablesClassroomItemViewTest, RendersWithoutDueDateTime) { |
| const auto assignment = GlanceablesClassroomAssignment( |
| "Algebra", "Solve equation", |
| GURL("https://classroom.google.com/test-link-1"), std::nullopt, |
| base::Time(), std::nullopt); |
| const auto view = |
| GlanceablesClassroomItemView(&assignment, base::DoNothing()); |
| |
| const auto* const icon_view = GetIconView(view); |
| const auto* const course_work_title_label = GetCourseWorkTitleLabel(view); |
| const auto* const course_title_label = GetCourseTitleLabel(view); |
| const auto* const due_date_label = GetDueDateLabel(view); |
| const auto* const due_time_label = GetDueTimeLabel(view); |
| |
| ASSERT_TRUE(icon_view); |
| ASSERT_TRUE(course_work_title_label); |
| ASSERT_TRUE(course_title_label); |
| EXPECT_FALSE(due_date_label); |
| EXPECT_FALSE(due_time_label); |
| |
| EXPECT_EQ(course_work_title_label->GetText(), u"Solve equation"); |
| EXPECT_EQ(course_title_label->GetText(), u"Algebra"); |
| } |
| |
| TEST_F(GlanceablesClassroomItemViewTest, RendersWithDueDateTime) { |
| // "Now" equals to Sunday, 4/9/2023 5:15pm in the overridden timezone. |
| base::subtle::ScopedTimeClockOverrides time_override( |
| []() { |
| base::Time now; |
| EXPECT_TRUE(base::Time::FromString("10 Apr 2023 00:15 GMT", &now)); |
| return now; |
| }, |
| nullptr, nullptr); |
| ash::system::ScopedTimezoneSettings tz(u"America/Los_Angeles"); |
| |
| const std::vector<std::u16string> expected_due_date_labels{ |
| u"Apr 8", u"Today", u"Mon", u"Tue", u"Wed", |
| u"Thu", u"Fri", u"Sat", u"Apr 16"}; |
| |
| // For 9 subsequent assignments starting from "yesterday", check their due |
| // date and time labels. |
| base::Time due = base::Time::Now() - base::Days(1); |
| for (size_t i = 0; i < 9; ++i) { |
| const auto assignment = GlanceablesClassroomAssignment( |
| "Algebra", "Solve equation", |
| GURL("https://classroom.google.com/test-link-1"), due, base::Time(), |
| std::nullopt); |
| const auto view = |
| GlanceablesClassroomItemView(&assignment, base::DoNothing()); |
| |
| const auto* const due_date_label = GetDueDateLabel(view); |
| const auto* const due_time_label = GetDueTimeLabel(view); |
| |
| EXPECT_EQ(due_date_label->GetText(), expected_due_date_labels.at(i)); |
| EXPECT_EQ(due_time_label->GetText(), u"5:15\x202FPM"); |
| |
| due += base::Days(1); |
| } |
| } |
| |
| TEST_F(GlanceablesClassroomItemViewTest, RendersDueTimeIn24HrFormat) { |
| ash::system::ScopedTimezoneSettings tz(u"America/Los_Angeles"); |
| Shell::Get()->system_tray_model()->SetUse24HourClock(true); |
| |
| base::Time due; |
| ASSERT_TRUE(base::Time::FromString("10 Apr 2023 00:15 GMT", &due)); |
| |
| const auto assignment = GlanceablesClassroomAssignment( |
| "Algebra", "Solve equation", |
| GURL("https://classroom.google.com/test-link-1"), due, base::Time(), |
| std::nullopt); |
| const auto view = |
| GlanceablesClassroomItemView(&assignment, base::DoNothing()); |
| const auto* const due_time_label = GetDueTimeLabel(view); |
| |
| ASSERT_TRUE(due_time_label); |
| EXPECT_EQ(due_time_label->GetText(), u"17:15"); |
| } |
| |
| TEST_F(GlanceablesClassroomItemViewTest, DoesNotRenderDueTimeFor2359) { |
| // 1 - for ICU formatters; 2 - for `base::Time::LocalExplode`. |
| ash::system::ScopedTimezoneSettings tz(u"America/Los_Angeles"); |
| calendar_test_utils::ScopedLibcTimeZone libc_tz("America/Los_Angeles"); |
| |
| base::Time due; |
| ASSERT_TRUE(base::Time::FromString("10 Apr 2023 06:59 GMT", &due)); |
| |
| const auto assignment = GlanceablesClassroomAssignment( |
| "Algebra", "Solve equation", |
| GURL("https://classroom.google.com/test-link-1"), due, base::Time(), |
| std::nullopt); |
| const auto view = |
| GlanceablesClassroomItemView(&assignment, base::DoNothing()); |
| const auto* const due_time_label = GetDueTimeLabel(view); |
| |
| ASSERT_TRUE(due_time_label); |
| EXPECT_TRUE(due_time_label->GetText().empty()); |
| } |
| |
| TEST_F(GlanceablesClassroomItemViewTest, AccessibleProperties) { |
| const auto assignment = GlanceablesClassroomAssignment( |
| "Algebra", "Solve equation", |
| GURL("https://classroom.google.com/test-link-1"), std::nullopt, |
| base::Time(), std::nullopt); |
| auto view = GlanceablesClassroomItemView(&assignment, base::DoNothing()); |
| ui::AXNodeData data; |
| |
| view.GetViewAccessibility().GetAccessibleNodeData(&data); |
| EXPECT_EQ(data.role, ax::mojom::Role::kListItem); |
| EXPECT_EQ(data.GetDefaultActionVerb(), ax::mojom::DefaultActionVerb::kClick); |
| |
| view.SetEnabled(false); |
| data = ui::AXNodeData(); |
| view.GetViewAccessibility().GetAccessibleNodeData(&data); |
| EXPECT_EQ(data.GetDefaultActionVerb(), ax::mojom::DefaultActionVerb::kClick); |
| } |
| |
| } // namespace ash |