| // 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. |
| |
| #include "chrome/browser/ash/printing/cups_print_job_notification_manager.h" |
| |
| #include "base/check_deref.h" |
| #include "chrome/browser/apps/app_service/app_service_proxy.h" |
| #include "chrome/browser/apps/app_service/app_service_test.h" |
| #include "chrome/browser/ash/printing/cups_print_job.h" |
| #include "chrome/browser/ash/printing/cups_print_job_notification.h" |
| #include "chrome/browser/ash/printing/fake_cups_print_job_manager.h" |
| #include "chrome/grit/branded_strings.h" |
| #include "chrome/grit/generated_resources.h" |
| #include "chrome/test/base/testing_profile.h" |
| #include "components/services/app_service/public/cpp/app_types.h" |
| #include "content/public/test/browser_task_environment.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/message_center/public/cpp/notification.h" |
| |
| namespace ash { |
| |
| namespace { |
| |
| using testing::AllOf; |
| using testing::Eq; |
| using testing::Property; |
| |
| constexpr char kAppId[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; |
| |
| constexpr char kAppName[] = "app_name"; |
| constexpr char16_t kAppName16[] = u"app_name"; |
| |
| constexpr char kPrinterName[] = "printer"; |
| constexpr char16_t kPrinterName16[] = u"printer"; |
| |
| } // namespace |
| |
| class CupsPrintJobNotificationTest : public testing::Test, |
| public testing::WithParamInterface<bool> { |
| protected: |
| CupsPrintJobNotificationTest() |
| : print_job_manager_(&profile_), |
| notification_manager_(&profile_, &print_job_manager_) {} |
| |
| void SetUp() override { |
| testing::Test::SetUp(); |
| |
| // Wait for AppServiceProxy to be ready. |
| app_service_test_.SetUp(&profile_); |
| if (IsWebPrintingTest()) { |
| AddIWA(kAppId, kAppName); |
| } |
| } |
| |
| CupsPrintJob CreateCupsPrintJob(const std::string& printer_name, |
| uint32_t total_page_number) { |
| chromeos::Printer printer; |
| printer.set_display_name(printer_name); |
| |
| if (IsWebPrintingTest()) { |
| return CupsPrintJob( |
| printer, /*job_id=*/0, /*document_title=*/std::string(), |
| total_page_number, crosapi::mojom::PrintJob::Source::kIsolatedWebApp, |
| /*source_id=*/kAppId, printing::proto::PrintSettings()); |
| } else { |
| return CupsPrintJob( |
| printer, /*job_id=*/0, /*document_title=*/std::string(), |
| total_page_number, crosapi::mojom::PrintJob::Source::kUnknown, |
| /*source_id=*/std::string(), printing::proto::PrintSettings()); |
| } |
| } |
| |
| std::unique_ptr<CupsPrintJobNotification> CreateNotificationForJob( |
| base::WeakPtr<CupsPrintJob> job) { |
| return std::make_unique<CupsPrintJobNotification>(¬ification_manager_, |
| job, &profile_); |
| } |
| |
| std::u16string GetExpectedNotificationAppName() const { |
| return IsWebPrintingTest() |
| ? kAppName16 |
| : l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME); |
| } |
| |
| private: |
| bool IsWebPrintingTest() const { return GetParam(); } |
| |
| void AddIWA(const std::string& app_id, const std::string& short_name) { |
| std::vector<apps::AppPtr> apps; |
| apps::AppPtr app = std::make_unique<apps::App>(apps::AppType::kWeb, app_id); |
| app->app_id = app_id; |
| app->readiness = apps::Readiness::kReady; |
| app->short_name = short_name; |
| apps.push_back(std::move(app)); |
| app_service_test_.proxy()->OnApps(std::move(apps), apps::AppType::kWeb, |
| /*should_notify_initialized=*/false); |
| } |
| |
| content::BrowserTaskEnvironment task_environment_; |
| TestingProfile profile_; |
| FakeCupsPrintJobManager print_job_manager_; |
| CupsPrintJobNotificationManager notification_manager_; |
| |
| apps::AppServiceTest app_service_test_; |
| }; |
| |
| // Validates notification for the CLIENT_UNAUTHORIZED error. |
| TEST_P(CupsPrintJobNotificationTest, ClientUnauthorized) { |
| CupsPrintJob job = CreateCupsPrintJob(kPrinterName, /*total_page_number=*/1); |
| |
| // Create notification. |
| auto cups_notification = CreateNotificationForJob(job.GetWeakPtr()); |
| |
| // Dispatch an update to move it to the FAILED state. |
| job.set_error_code(chromeos::PrinterErrorCode::CLIENT_UNAUTHORIZED); |
| job.set_state(CupsPrintJob::State::STATE_FAILED); |
| cups_notification->OnPrintJobStatusUpdated(); |
| |
| const auto& notification = |
| CHECK_DEREF(cups_notification->GetNotificationDataForTesting()); |
| EXPECT_THAT( |
| notification, |
| AllOf( |
| Property(&message_center::Notification::title, |
| Eq(l10n_util::GetStringUTF16( |
| IDS_PRINT_JOB_AUTHORIZATION_ERROR_NOTIFICATION_TITLE))), |
| Property( |
| &message_center::Notification::message, |
| Eq(l10n_util::GetStringFUTF16( |
| IDS_PRINT_JOB_NOTIFICATION_IDENTIFICATION_REQUIRED_MESSAGE, |
| kPrinterName16))))); |
| } |
| |
| // Validates notification for a running job. |
| TEST_P(CupsPrintJobNotificationTest, RunningJob) { |
| CupsPrintJob job = CreateCupsPrintJob(kPrinterName, /*total_page_number=*/10); |
| |
| // Create notification. |
| auto cups_notification = CreateNotificationForJob(job.GetWeakPtr()); |
| |
| // Dispatch an update to move it to the STARTED state. |
| job.set_state(CupsPrintJob::State::STATE_STARTED); |
| cups_notification->OnPrintJobStatusUpdated(); |
| |
| const auto& notification = |
| CHECK_DEREF(cups_notification->GetNotificationDataForTesting()); |
| EXPECT_THAT( |
| notification, |
| AllOf(Property(&message_center::Notification::title, |
| Eq(l10n_util::GetStringUTF16( |
| IDS_PRINT_JOB_PRINTING_NOTIFICATION_TITLE))), |
| Property(&message_center::Notification::message, |
| Eq(l10n_util::GetStringFUTF16( |
| IDS_PRINT_JOB_NOTIFICATION_APP_PRINTING_IN_PROGRESS, |
| GetExpectedNotificationAppName(), u"10", |
| kPrinterName16))))); |
| } |
| |
| // Validates notification for a running job with a single page. |
| TEST_P(CupsPrintJobNotificationTest, RunningJobSinglePage) { |
| CupsPrintJob job = CreateCupsPrintJob(kPrinterName, /*total_page_number=*/1); |
| |
| // Create notification. |
| auto cups_notification = CreateNotificationForJob(job.GetWeakPtr()); |
| |
| // Dispatch an update to move it to the STARTED state. |
| job.set_state(CupsPrintJob::State::STATE_STARTED); |
| cups_notification->OnPrintJobStatusUpdated(); |
| |
| const auto& notification = |
| CHECK_DEREF(cups_notification->GetNotificationDataForTesting()); |
| EXPECT_THAT( |
| notification, |
| AllOf( |
| Property(&message_center::Notification::title, |
| Eq(l10n_util::GetStringUTF16( |
| IDS_PRINT_JOB_PRINTING_NOTIFICATION_TITLE))), |
| Property( |
| &message_center::Notification::message, |
| Eq(l10n_util::GetStringFUTF16( |
| IDS_PRINT_JOB_NOTIFICATION_APP_PRINTING_IN_PROGRESS_SINGLE_PAGE, |
| GetExpectedNotificationAppName(), kPrinterName16))))); |
| } |
| |
| // Validates notification for a completed job. |
| TEST_P(CupsPrintJobNotificationTest, JobDone) { |
| CupsPrintJob job = CreateCupsPrintJob(kPrinterName, /*total_page_number=*/1); |
| |
| // Create notification. |
| auto cups_notification = CreateNotificationForJob(job.GetWeakPtr()); |
| |
| // Dispatch an update to move it to the DOCUMENT_DONE state. |
| job.set_state(CupsPrintJob::State::STATE_DOCUMENT_DONE); |
| cups_notification->OnPrintJobStatusUpdated(); |
| |
| const auto& notification = |
| CHECK_DEREF(cups_notification->GetNotificationDataForTesting()); |
| EXPECT_THAT( |
| notification, |
| AllOf(Property(&message_center::Notification::title, |
| Eq(l10n_util::GetStringUTF16( |
| IDS_PRINT_JOB_DONE_NOTIFICATION_TITLE))), |
| Property(&message_center::Notification::message, |
| Eq(l10n_util::GetStringFUTF16( |
| IDS_PRINT_JOB_NOTIFICATION_APP_PRINTING_DONE, |
| GetExpectedNotificationAppName(), kPrinterName16))))); |
| } |
| |
| // The boolean controls whether the test is instantiated for Web Printing API |
| // job notifications or regular job notifications. |
| INSTANTIATE_TEST_SUITE_P(/**/, CupsPrintJobNotificationTest, testing::Bool()); |
| |
| } // namespace ash |