| // Copyright 2020 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <stdint.h> |
| |
| #include <algorithm> |
| #include <memory> |
| #include <string> |
| #include <utility> |
| |
| #include "base/check_op.h" |
| #include "base/containers/span.h" |
| #include "base/files/file_path.h" |
| #include "base/files/file_util.h" |
| #include "base/functional/bind.h" |
| #include "base/functional/callback.h" |
| #include "base/memory/scoped_refptr.h" |
| #include "base/path_service.h" |
| #include "base/run_loop.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/threading/thread_restrictions.h" |
| #include "base/values.h" |
| #include "build/build_config.h" |
| #include "chrome/browser/printing/print_backend_service_test_impl.h" |
| #include "chrome/common/chrome_paths.h" |
| #include "chrome/services/printing/public/mojom/print_backend_service.mojom.h" |
| #include "chrome/test/base/in_process_browser_test.h" |
| #include "content/public/test/browser_test.h" |
| #include "mojo/public/cpp/bindings/pending_receiver.h" |
| #include "mojo/public/cpp/bindings/remote.h" |
| #include "printing/backend/print_backend.h" |
| #include "printing/backend/test_print_backend.h" |
| #include "printing/buildflags/buildflags.h" |
| #include "printing/metafile.h" |
| #include "printing/mojom/print.mojom.h" |
| #include "printing/print_job_constants.h" |
| #include "printing/print_settings.h" |
| #include "printing/print_settings_conversion.h" |
| #include "printing/printing_context.h" |
| #include "printing/printing_context_factory_for_test.h" |
| #include "printing/test_printing_context.h" |
| #include "testing/gmock/include/gmock/gmock-matchers.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "third_party/abseil-cpp/absl/types/optional.h" |
| |
| #if BUILDFLAG(IS_WIN) |
| #include "printing/emf_win.h" |
| #else |
| #include "printing/metafile_skia.h" |
| #endif |
| |
| namespace printing { |
| |
| using ::testing::UnorderedElementsAreArray; |
| |
| namespace { |
| |
| constexpr char kDefaultPrinterName[] = "default-test-printer"; |
| constexpr char16_t kDefaultPrinterName16[] = u"default-test-printer"; |
| constexpr char kAnotherPrinterName[] = "another-test-printer"; |
| constexpr char kInvalidPrinterName[] = "invalid-test-printer"; |
| constexpr char16_t kInvalidPrinterName16[] = u"invalid-test-printer"; |
| constexpr char kAccessDeniedPrinterName[] = "access-denied-test-printer"; |
| |
| const PrinterBasicInfoOptions kDefaultPrintInfoOptions{{"opt1", "123"}, |
| {"opt2", "456"}}; |
| |
| const PrinterBasicInfo kDefaultPrinterInfo( |
| /*printer_name=*/kDefaultPrinterName, |
| /*display_name=*/"default test printer", |
| /*printer_description=*/"Default printer for testing.", |
| /*printer_status=*/0, |
| /*is_default=*/true, |
| kDefaultPrintInfoOptions); |
| const PrinterBasicInfo kAnotherPrinterInfo( |
| /*printer_name=*/kAnotherPrinterName, |
| /*display_name=*/"another test printer", |
| /*printer_description=*/"Another printer for testing.", |
| /*printer_status=*/5, |
| /*is_default=*/false, |
| /*options=*/{}); |
| |
| constexpr int32_t kCopiesMax = 123; |
| constexpr int kPrintSettingsCopies = 42; |
| constexpr int kPrintSettingsDefaultDpi = 300; |
| constexpr int kPrintSettingsOverrideDpi = 150; |
| |
| constexpr int32_t kTestDocumentCookie = 1; |
| |
| bool LoadMetafileDataFromFile(const std::string& file_name, |
| Metafile& metafile) { |
| base::FilePath data_file; |
| if (!base::PathService::Get(chrome::DIR_TEST_DATA, &data_file)) |
| return false; |
| |
| data_file = |
| data_file.Append(FILE_PATH_LITERAL("printing")).AppendASCII(file_name); |
| std::string data; |
| { |
| base::ScopedAllowBlockingForTesting allow_block; |
| if (!base::ReadFileToString(data_file, &data)) |
| return false; |
| } |
| return metafile.InitFromData(base::as_bytes(base::make_span(data))); |
| } |
| |
| } // namespace |
| |
| class PrintBackendBrowserTest : public InProcessBrowserTest { |
| public: |
| PrintBackendBrowserTest() = default; |
| ~PrintBackendBrowserTest() override = default; |
| |
| void SetUp() override { |
| // Do local setup before calling base class, since the base class enters |
| // the main run loop. |
| PrintBackend::SetPrintBackendForTesting(test_print_backend_.get()); |
| PrintingContext::SetPrintingContextFactoryForTest( |
| &test_printing_context_factory_); |
| InProcessBrowserTest::SetUp(); |
| } |
| |
| void TearDown() override { |
| // Call base class teardown before local teardown, to be in opposite order |
| // of `SetUp`. |
| InProcessBrowserTest::TearDown(); |
| PrintingContext::SetPrintingContextFactoryForTest(/*factory=*/nullptr); |
| PrintBackend::SetPrintBackendForTesting(/*print_backend=*/nullptr); |
| } |
| |
| // Initialize and load the backend service with some test print drivers. |
| void LaunchService() { |
| print_backend_service_ = PrintBackendServiceTestImpl::LaunchForTesting( |
| remote_, test_print_backend_, /*sandboxed=*/true); |
| } |
| |
| // Load the test backend with a default printer driver. |
| void AddDefaultPrinter() { |
| // Only explicitly specify capabilities that we pay attention to in the |
| // tests. |
| auto default_caps = std::make_unique<PrinterSemanticCapsAndDefaults>(); |
| default_caps->copies_max = kCopiesMax; |
| test_print_backend_->AddValidPrinter( |
| kDefaultPrinterName, std::move(default_caps), |
| std::make_unique<PrinterBasicInfo>(kDefaultPrinterInfo)); |
| } |
| |
| // Load the test backend with another (non-default) printer. |
| void AddAnotherPrinter() { |
| test_print_backend_->AddValidPrinter( |
| kAnotherPrinterName, std::make_unique<PrinterSemanticCapsAndDefaults>(), |
| std::make_unique<PrinterBasicInfo>(kAnotherPrinterInfo)); |
| } |
| |
| void AddAccessDeniedPrinter() { |
| test_print_backend_->AddAccessDeniedPrinter(kAccessDeniedPrinterName); |
| } |
| |
| void SetPrinterNameForSubsequentContexts(const std::string& printer_name) { |
| test_printing_context_factory_.SetPrinterNameForSubsequentContexts( |
| printer_name); |
| } |
| |
| // Common helpers to perform particular stages of printing a document. |
| mojom::ResultCode StartPrintingAndWait(const PrintSettings& print_settings) { |
| mojom::ResultCode result; |
| |
| // Safe to use base::Unretained(this) since waiting locally on the callback |
| // forces a shorter lifetime than `this`. |
| GetPrintBackendService()->StartPrinting( |
| kTestDocumentCookie, u"document name", |
| mojom::PrintTargetType::kDirectToDevice, print_settings, |
| base::BindOnce(&PrintBackendBrowserTest::CaptureResult, |
| base::Unretained(this), std::ref(result))); |
| WaitUntilCallbackReceived(); |
| return result; |
| } |
| |
| #if BUILDFLAG(IS_WIN) |
| absl::optional<mojom::ResultCode> RenderPageAndWait() { |
| // Load a sample EMF file for a single page for testing handling. |
| Emf metafile; |
| if (!LoadMetafileDataFromFile("test1.emf", metafile)) |
| return absl::nullopt; |
| |
| base::MappedReadOnlyRegion region_mapping = |
| metafile.GetDataAsSharedMemoryRegion(); |
| if (!region_mapping.IsValid()) |
| return absl::nullopt; |
| |
| // Safe to use base::Unretained(this) since waiting locally on the callback |
| // forces a shorter lifetime than `this`. |
| mojom::ResultCode result; |
| GetPrintBackendService()->RenderPrintedPage( |
| kTestDocumentCookie, |
| /*page_index=*/0, metafile.GetDataType(), |
| std::move(region_mapping.region), |
| /*page_size=*/gfx::Size(200, 200), |
| /*page_content_rect=*/gfx::Rect(0, 0, 200, 200), |
| /*shrink_factor=*/1.0f, |
| base::BindOnce(&PrintBackendBrowserTest::CaptureResult, |
| base::Unretained(this), std::ref(result))); |
| WaitUntilCallbackReceived(); |
| return result; |
| } |
| #endif // BUILDFLAG(IS_WIN) |
| |
| // TODO(crbug.com/1008222) Include Windows once XPS print pipeline is enabled. |
| #if !BUILDFLAG(IS_WIN) |
| absl::optional<mojom::ResultCode> RenderDocumentAndWait() { |
| // Load a sample PDF file for a single page for testing handling. |
| MetafileSkia metafile; |
| if (!LoadMetafileDataFromFile("embedded_images.pdf", metafile)) |
| return absl::nullopt; |
| |
| base::MappedReadOnlyRegion region_mapping = |
| metafile.GetDataAsSharedMemoryRegion(); |
| if (!region_mapping.IsValid()) |
| return absl::nullopt; |
| |
| // Safe to use base::Unretained(this) since waiting locally on the callback |
| // forces a shorter lifetime than `this`. |
| mojom::ResultCode result; |
| GetPrintBackendService()->RenderPrintedDocument( |
| kTestDocumentCookie, /*page_count=*/1u, metafile.GetDataType(), |
| std::move(region_mapping.region), |
| base::BindOnce(&PrintBackendBrowserTest::CaptureResult, |
| base::Unretained(this), std::ref(result))); |
| WaitUntilCallbackReceived(); |
| return result; |
| } |
| #endif // !BUILDFLAG(IS_WIN) |
| |
| mojom::ResultCode DocumentDoneAndWait() { |
| mojom::ResultCode result; |
| |
| // Safe to use base::Unretained(this) since waiting locally on the callback |
| // forces a shorter lifetime than `this`. |
| GetPrintBackendService()->DocumentDone( |
| kTestDocumentCookie, |
| base::BindOnce(&PrintBackendBrowserTest::CaptureResult, |
| base::Unretained(this), std::ref(result))); |
| WaitUntilCallbackReceived(); |
| return result; |
| } |
| |
| void CancelAndWait() { |
| // Safe to use base::Unretained(this) since waiting locally on the callback |
| // forces a shorter lifetime than `this`. |
| GetPrintBackendService()->Cancel( |
| kTestDocumentCookie, |
| base::BindOnce(&PrintBackendBrowserTest::CheckForQuit, |
| base::Unretained(this))); |
| WaitUntilCallbackReceived(); |
| } |
| |
| // Public callbacks used by tests. |
| void OnDidEnumeratePrinters(mojom::PrinterListResultPtr& capture_printer_list, |
| mojom::PrinterListResultPtr printer_list) { |
| capture_printer_list = std::move(printer_list); |
| CheckForQuit(); |
| } |
| |
| void OnDidGetDefaultPrinterName( |
| mojom::DefaultPrinterNameResultPtr& capture_printer_name, |
| mojom::DefaultPrinterNameResultPtr printer_name) { |
| capture_printer_name = std::move(printer_name); |
| CheckForQuit(); |
| } |
| |
| void OnDidGetPrinterSemanticCapsAndDefaults( |
| mojom::PrinterSemanticCapsAndDefaultsResultPtr& capture_printer_caps, |
| mojom::PrinterSemanticCapsAndDefaultsResultPtr printer_caps) { |
| capture_printer_caps = std::move(printer_caps); |
| CheckForQuit(); |
| } |
| |
| void OnDidFetchCapabilities( |
| mojom::PrinterCapsAndInfoResultPtr& capture_caps_and_info, |
| mojom::PrinterCapsAndInfoResultPtr caps_and_info) { |
| capture_caps_and_info = std::move(caps_and_info); |
| CheckForQuit(); |
| } |
| |
| void CapturePrintSettings( |
| mojom::PrintSettingsResultPtr& capture_print_settings, |
| mojom::PrintSettingsResultPtr print_settings) { |
| capture_print_settings = std::move(print_settings); |
| CheckForQuit(); |
| } |
| |
| void CaptureResult(mojom::ResultCode& capture_result, |
| mojom::ResultCode result) { |
| capture_result = result; |
| CheckForQuit(); |
| } |
| |
| // The following are helper functions for having a wait loop in the test and |
| // exit when expected messages are received. Expect to only have to wait for |
| // one message. |
| void WaitUntilCallbackReceived() { |
| // If callback happened before getting here, then no need to wait. |
| if (!received_message_) { |
| base::RunLoop run_loop; |
| quit_callback_ = run_loop.QuitClosure(); |
| run_loop.Run(); |
| } |
| |
| // Reset for possible subsequent test. |
| received_message_ = false; |
| } |
| |
| void CheckForQuit() { |
| received_message_ = true; |
| if (quit_callback_) |
| std::move(quit_callback_).Run(); |
| } |
| |
| // Get the print backend service being tested. |
| mojom::PrintBackendService* GetPrintBackendService() const { |
| return print_backend_service_.get(); |
| } |
| |
| private: |
| class PrintBackendPrintingContextFactoryForTest |
| : public PrintingContextFactoryForTest { |
| public: |
| std::unique_ptr<PrintingContext> CreatePrintingContext( |
| PrintingContext::Delegate* delegate, |
| bool skip_system_calls) override { |
| auto context = |
| std::make_unique<TestPrintingContext>(delegate, skip_system_calls); |
| |
| auto settings = std::make_unique<PrintSettings>(); |
| settings->set_copies(kPrintSettingsCopies); |
| settings->set_dpi(kPrintSettingsDefaultDpi); |
| settings->set_device_name(base::ASCIIToUTF16(printer_name_)); |
| context->SetDeviceSettings(printer_name_, std::move(settings)); |
| |
| return std::move(context); |
| } |
| |
| void SetPrinterNameForSubsequentContexts(const std::string& printer_name) { |
| printer_name_ = printer_name; |
| } |
| |
| private: |
| std::string printer_name_; |
| }; |
| |
| bool received_message_ = false; |
| base::OnceClosure quit_callback_; |
| |
| mojo::Remote<mojom::PrintBackendService> remote_; |
| scoped_refptr<TestPrintBackend> test_print_backend_ = |
| base::MakeRefCounted<TestPrintBackend>(); |
| TestPrintingContextDelegate test_printing_context_delegate_; |
| PrintBackendPrintingContextFactoryForTest test_printing_context_factory_; |
| std::unique_ptr<PrintBackendServiceTestImpl> print_backend_service_; |
| }; |
| |
| IN_PROC_BROWSER_TEST_F(PrintBackendBrowserTest, EnumeratePrinters) { |
| LaunchService(); |
| AddDefaultPrinter(); |
| AddAnotherPrinter(); |
| |
| const PrinterList kPrinterListExpected = {kDefaultPrinterInfo, |
| kAnotherPrinterInfo}; |
| |
| // Safe to use base::Unretained(this) since waiting locally on the callback |
| // forces a shorter lifetime than `this`. |
| mojom::PrinterListResultPtr printer_list; |
| GetPrintBackendService()->EnumeratePrinters( |
| base::BindOnce(&PrintBackendBrowserTest::OnDidEnumeratePrinters, |
| base::Unretained(this), std::ref(printer_list))); |
| WaitUntilCallbackReceived(); |
| ASSERT_TRUE(printer_list->is_printer_list()); |
| EXPECT_THAT(printer_list->get_printer_list(), |
| UnorderedElementsAreArray(kPrinterListExpected)); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(PrintBackendBrowserTest, GetDefaultPrinterName) { |
| LaunchService(); |
| AddDefaultPrinter(); |
| |
| mojom::DefaultPrinterNameResultPtr default_printer_name; |
| |
| // Safe to use base::Unretained(this) since waiting locally on the callback |
| // forces a shorter lifetime than `this`. |
| GetPrintBackendService()->GetDefaultPrinterName( |
| base::BindOnce(&PrintBackendBrowserTest::OnDidGetDefaultPrinterName, |
| base::Unretained(this), std::ref(default_printer_name))); |
| WaitUntilCallbackReceived(); |
| ASSERT_TRUE(default_printer_name->is_default_printer_name()); |
| EXPECT_EQ(default_printer_name->get_default_printer_name(), |
| kDefaultPrinterName); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(PrintBackendBrowserTest, |
| GetPrinterSemanticCapsAndDefaults) { |
| LaunchService(); |
| AddDefaultPrinter(); |
| |
| mojom::PrinterSemanticCapsAndDefaultsResultPtr printer_caps; |
| |
| // Safe to use base::Unretained(this) since waiting locally on the callback |
| // forces a shorter lifetime than `this`. |
| GetPrintBackendService()->GetPrinterSemanticCapsAndDefaults( |
| kDefaultPrinterName, |
| base::BindOnce( |
| &PrintBackendBrowserTest::OnDidGetPrinterSemanticCapsAndDefaults, |
| base::Unretained(this), std::ref(printer_caps))); |
| WaitUntilCallbackReceived(); |
| ASSERT_TRUE(printer_caps->is_printer_caps()); |
| EXPECT_EQ(printer_caps->get_printer_caps().copies_max, kCopiesMax); |
| |
| // Requesting for an invalid printer should not return capabilities. |
| GetPrintBackendService()->GetPrinterSemanticCapsAndDefaults( |
| kInvalidPrinterName, |
| base::BindOnce( |
| &PrintBackendBrowserTest::OnDidGetPrinterSemanticCapsAndDefaults, |
| base::Unretained(this), std::ref(printer_caps))); |
| WaitUntilCallbackReceived(); |
| ASSERT_TRUE(printer_caps->is_result_code()); |
| EXPECT_EQ(printer_caps->get_result_code(), mojom::ResultCode::kFailed); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(PrintBackendBrowserTest, |
| GetPrinterSemanticCapsAndDefaultsAccessDenied) { |
| LaunchService(); |
| AddAccessDeniedPrinter(); |
| |
| mojom::PrinterSemanticCapsAndDefaultsResultPtr printer_caps; |
| |
| // Requesting for a printer which requires elevated privileges should not |
| // return capabilities, and should indicate that access was denied. |
| // Safe to use base::Unretained(this) since waiting locally on the callback |
| // forces a shorter lifetime than `this`. |
| GetPrintBackendService()->GetPrinterSemanticCapsAndDefaults( |
| kAccessDeniedPrinterName, |
| base::BindOnce( |
| &PrintBackendBrowserTest::OnDidGetPrinterSemanticCapsAndDefaults, |
| base::Unretained(this), std::ref(printer_caps))); |
| WaitUntilCallbackReceived(); |
| ASSERT_TRUE(printer_caps->is_result_code()); |
| EXPECT_EQ(printer_caps->get_result_code(), mojom::ResultCode::kAccessDenied); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(PrintBackendBrowserTest, FetchCapabilities) { |
| LaunchService(); |
| AddDefaultPrinter(); |
| |
| mojom::PrinterCapsAndInfoResultPtr caps_and_info; |
| |
| // Safe to use base::Unretained(this) since waiting locally on the callback |
| // forces a shorter lifetime than `this`. |
| GetPrintBackendService()->FetchCapabilities( |
| kDefaultPrinterName, |
| base::BindOnce(&PrintBackendBrowserTest::OnDidFetchCapabilities, |
| base::Unretained(this), std::ref(caps_and_info))); |
| WaitUntilCallbackReceived(); |
| ASSERT_TRUE(caps_and_info->is_printer_caps_and_info()); |
| EXPECT_EQ(caps_and_info->get_printer_caps_and_info()->printer_caps.copies_max, |
| kCopiesMax); |
| |
| // Requesting for an invalid printer should not return capabilities. |
| GetPrintBackendService()->FetchCapabilities( |
| kInvalidPrinterName, |
| base::BindOnce(&PrintBackendBrowserTest::OnDidFetchCapabilities, |
| base::Unretained(this), std::ref(caps_and_info))); |
| WaitUntilCallbackReceived(); |
| ASSERT_TRUE(caps_and_info->is_result_code()); |
| EXPECT_EQ(caps_and_info->get_result_code(), mojom::ResultCode::kFailed); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(PrintBackendBrowserTest, FetchCapabilitiesAccessDenied) { |
| LaunchService(); |
| AddAccessDeniedPrinter(); |
| |
| mojom::PrinterCapsAndInfoResultPtr caps_and_info; |
| |
| // Safe to use base::Unretained(this) since waiting locally on the callback |
| // forces a shorter lifetime than `this`. |
| GetPrintBackendService()->FetchCapabilities( |
| kAccessDeniedPrinterName, |
| base::BindOnce(&PrintBackendBrowserTest::OnDidFetchCapabilities, |
| base::Unretained(this), std::ref(caps_and_info))); |
| WaitUntilCallbackReceived(); |
| ASSERT_TRUE(caps_and_info->is_result_code()); |
| EXPECT_EQ(caps_and_info->get_result_code(), mojom::ResultCode::kAccessDenied); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(PrintBackendBrowserTest, UseDefaultSettings) { |
| LaunchService(); |
| AddDefaultPrinter(); |
| SetPrinterNameForSubsequentContexts(kDefaultPrinterName); |
| |
| mojom::PrintSettingsResultPtr settings; |
| |
| // Safe to use base::Unretained(this) since waiting locally on the callback |
| // forces a shorter lifetime than `this`. |
| GetPrintBackendService()->UseDefaultSettings( |
| base::BindOnce(&PrintBackendBrowserTest::CapturePrintSettings, |
| base::Unretained(this), std::ref(settings))); |
| WaitUntilCallbackReceived(); |
| ASSERT_TRUE(settings->is_settings()); |
| EXPECT_EQ(settings->get_settings().copies(), kPrintSettingsCopies); |
| EXPECT_EQ(settings->get_settings().dpi(), kPrintSettingsDefaultDpi); |
| } |
| |
| #if BUILDFLAG(IS_WIN) |
| IN_PROC_BROWSER_TEST_F(PrintBackendBrowserTest, AskUserForSettings) { |
| LaunchService(); |
| AddDefaultPrinter(); |
| SetPrinterNameForSubsequentContexts(kDefaultPrinterName); |
| |
| mojom::PrintSettingsResultPtr settings; |
| |
| // Safe to use base::Unretained(this) since waiting locally on the callback |
| // forces a shorter lifetime than `this`. |
| GetPrintBackendService()->AskUserForSettings( |
| /*parent_window_id=*/8, |
| /*max_pages=*/1, /*has_selection=*/false, /*is_scripted=*/false, |
| base::BindOnce(&PrintBackendBrowserTest::CapturePrintSettings, |
| base::Unretained(this), std::ref(settings))); |
| WaitUntilCallbackReceived(); |
| ASSERT_TRUE(settings->is_settings()); |
| EXPECT_EQ(settings->get_settings().copies(), kPrintSettingsCopies); |
| EXPECT_EQ(settings->get_settings().dpi(), kPrintSettingsDefaultDpi); |
| } |
| #endif // BUILDFLAG(IS_WIN) |
| |
| IN_PROC_BROWSER_TEST_F(PrintBackendBrowserTest, UpdatePrintSettings) { |
| LaunchService(); |
| AddDefaultPrinter(); |
| SetPrinterNameForSubsequentContexts(kDefaultPrinterName); |
| |
| mojom::PrintSettingsResultPtr settings; |
| |
| PrintSettings print_settings; |
| print_settings.set_device_name(kDefaultPrinterName16); |
| print_settings.set_dpi(kPrintSettingsOverrideDpi); |
| base::Value::Dict job_settings = |
| PrintSettingsToJobSettingsDebug(print_settings); |
| job_settings.Set(kSettingPrinterType, |
| static_cast<int>(mojom::PrinterType::kLocal)); |
| |
| // Safe to use base::Unretained(this) since waiting locally on the callback |
| // forces a shorter lifetime than `this`. |
| GetPrintBackendService()->UpdatePrintSettings( |
| std::move(job_settings), |
| base::BindOnce(&PrintBackendBrowserTest::CapturePrintSettings, |
| base::Unretained(this), std::ref(settings))); |
| WaitUntilCallbackReceived(); |
| ASSERT_TRUE(settings->is_settings()); |
| EXPECT_EQ(settings->get_settings().copies(), kPrintSettingsCopies); |
| EXPECT_EQ(settings->get_settings().dpi(), kPrintSettingsOverrideDpi); |
| #if BUILDFLAG(IS_LINUX) && BUILDFLAG(USE_CUPS) |
| const PrintSettings::AdvancedSettings& advanced_settings = |
| settings->get_settings().advanced_settings(); |
| EXPECT_EQ(advanced_settings.size(), kDefaultPrintInfoOptions.size()); |
| for (const auto& advanced_setting : advanced_settings) { |
| auto option = kDefaultPrintInfoOptions.find(advanced_setting.first); |
| ASSERT_NE(option, kDefaultPrintInfoOptions.end()); |
| EXPECT_EQ(option->second, advanced_setting.second.GetString()); |
| } |
| #endif // BUILDFLAG(IS_LINUX) && BUILDFLAG(USE_CUPS) |
| |
| // Updating for an invalid printer should not return print settings. |
| print_settings.set_device_name(kInvalidPrinterName16); |
| job_settings = PrintSettingsToJobSettingsDebug(print_settings); |
| job_settings.Set(kSettingPrinterType, |
| static_cast<int>(mojom::PrinterType::kLocal)); |
| GetPrintBackendService()->UpdatePrintSettings( |
| std::move(job_settings), |
| base::BindOnce(&PrintBackendBrowserTest::CapturePrintSettings, |
| base::Unretained(this), std::ref(settings))); |
| WaitUntilCallbackReceived(); |
| ASSERT_TRUE(settings->is_result_code()); |
| EXPECT_EQ(settings->get_result_code(), mojom::ResultCode::kFailed); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(PrintBackendBrowserTest, StartPrintingValidPrinter) { |
| LaunchService(); |
| AddDefaultPrinter(); |
| SetPrinterNameForSubsequentContexts(kDefaultPrinterName); |
| |
| PrintSettings print_settings; |
| print_settings.set_device_name(kDefaultPrinterName16); |
| |
| EXPECT_EQ(StartPrintingAndWait(print_settings), mojom::ResultCode::kSuccess); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(PrintBackendBrowserTest, StartPrintingInvalidPrinter) { |
| LaunchService(); |
| AddDefaultPrinter(); |
| SetPrinterNameForSubsequentContexts(kDefaultPrinterName); |
| |
| PrintSettings print_settings; |
| print_settings.set_device_name(kInvalidPrinterName16); |
| |
| EXPECT_EQ(StartPrintingAndWait(print_settings), mojom::ResultCode::kFailed); |
| } |
| |
| #if BUILDFLAG(IS_WIN) |
| IN_PROC_BROWSER_TEST_F(PrintBackendBrowserTest, RenderPrintedPage) { |
| LaunchService(); |
| AddDefaultPrinter(); |
| SetPrinterNameForSubsequentContexts(kDefaultPrinterName); |
| |
| PrintSettings print_settings; |
| print_settings.set_device_name(kDefaultPrinterName16); |
| |
| EXPECT_EQ(StartPrintingAndWait(print_settings), mojom::ResultCode::kSuccess); |
| |
| absl::optional<mojom::ResultCode> result = RenderPageAndWait(); |
| EXPECT_EQ(result, mojom::ResultCode::kSuccess); |
| } |
| #endif // BUILDFLAG(IS_WIN) |
| |
| // TODO(crbug.com/1008222) Include Windows for this test once XPS print |
| // pipeline is enabled. |
| #if !BUILDFLAG(IS_WIN) |
| IN_PROC_BROWSER_TEST_F(PrintBackendBrowserTest, RenderPrintedDocument) { |
| LaunchService(); |
| AddDefaultPrinter(); |
| SetPrinterNameForSubsequentContexts(kDefaultPrinterName); |
| |
| PrintSettings print_settings; |
| print_settings.set_device_name(kDefaultPrinterName16); |
| |
| EXPECT_EQ(StartPrintingAndWait(print_settings), mojom::ResultCode::kSuccess); |
| |
| absl::optional<mojom::ResultCode> result = RenderDocumentAndWait(); |
| EXPECT_EQ(result, mojom::ResultCode::kSuccess); |
| } |
| #endif // !BUILDFLAG(IS_WIN) |
| |
| IN_PROC_BROWSER_TEST_F(PrintBackendBrowserTest, DocumentDone) { |
| LaunchService(); |
| AddDefaultPrinter(); |
| SetPrinterNameForSubsequentContexts(kDefaultPrinterName); |
| |
| PrintSettings print_settings; |
| print_settings.set_device_name(kDefaultPrinterName16); |
| |
| EXPECT_EQ(StartPrintingAndWait(print_settings), mojom::ResultCode::kSuccess); |
| |
| // TODO(crbug.com/1008222) Include Windows coverage for RenderDocument() |
| // path once XPS print pipeline is enabled. |
| #if BUILDFLAG(IS_WIN) |
| absl::optional<mojom::ResultCode> result = RenderPageAndWait(); |
| #else |
| absl::optional<mojom::ResultCode> result = RenderDocumentAndWait(); |
| #endif |
| EXPECT_EQ(result, mojom::ResultCode::kSuccess); |
| |
| EXPECT_EQ(DocumentDoneAndWait(), mojom::ResultCode::kSuccess); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(PrintBackendBrowserTest, Cancel) { |
| LaunchService(); |
| AddDefaultPrinter(); |
| SetPrinterNameForSubsequentContexts(kDefaultPrinterName); |
| |
| PrintSettings print_settings; |
| print_settings.set_device_name(kDefaultPrinterName16); |
| |
| EXPECT_EQ(StartPrintingAndWait(print_settings), mojom::ResultCode::kSuccess); |
| |
| CancelAndWait(); |
| } |
| |
| } // namespace printing |