#include "chrome/browser/ui/webui/print_preview/local_printer_handler_default.h"
#include <functional>
#include <memory>
#include <string_view>
#include <utility>
#include "base/json/json_string_value_serializer.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_refptr.h"
#include "base/task/single_thread_task_runner.h"
#include "base/values.h"
#include "chrome/common/printing/printer_capabilities.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_task_environment.h"
#include "printing/backend/print_backend.h"
#include "printing/backend/test_print_backend.h"
#include "printing/buildflags/buildflags.h"
#include "printing/print_job_constants.h"
#include "printing/printing_features.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#if BUILDFLAG(ENABLE_OOP_PRINTING)
#include "chrome/browser/printing/print_backend_service_manager.h"
#include "chrome/browser/printing/print_backend_service_test_impl.h"
#else
#include "base/notreached.h"
#endif
#if BUILDFLAG(IS_WIN) && BUILDFLAG(ENABLE_OOP_PRINTING)
#include <vector>
#include "base/task/thread_pool.h"
#include "base/test/bind.h"
#include "base/test/values_test_util.h"
#include "chrome/browser/printing/printer_xml_parser_impl.h"
#include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h"
#endif
namespace printing {
namespace {
#if BUILDFLAG(IS_WIN) && BUILDFLAG(ENABLE_OOP_PRINTING)
constexpr char kVendorCapabilities[] = "vendor_capability";
constexpr char kXmlTestFeature[] =
R"(<?xml version="1.0" encoding="UTF-8"?>
<psf:PrintCapabilities>
<psf:Feature name="TestFeature">
<psf:Property name="psf:SelectionType">
<psf:Value xsi:type="xsd:QName">psk:PickOne</psf:Value>
</psf:Property>
<psf:Option constrained="psk:None">
<psf:ScoredProperty name="TestTimeStamp">
<psf:Value xsi:type="xsd:integer">0</psf:Value>
</psf:ScoredProperty>
</psf:Option>
</psf:Feature>
</psf:PrintCapabilities>)";
constexpr char kXmlPageOutputQuality[] =
R"(<?xml version="1.0" encoding="UTF-8"?>
<psf:PrintCapabilities>
<psf:Feature name="psk:PageOutputQuality">
<psf:Property name="psf:SelectionType">
<psf:Value xsi:type="xsd:QName">psk:PickOne</psf:Value>
</psf:Property>
<psf:Property name="psk:DisplayName">
<psf:Value xsi:type="xsd:string">Quality</psf:Value>
</psf:Property>
<psf:Option name="ns0000:Draft" constrained="psk:None">
<psf:Property name="psk:DisplayName">
<psf:Value xsi:type="xsd:string">Draft</psf:Value>
</psf:Property>
</psf:Option>
<psf:Option name="ns0000:Standard" constrained="psk:None">
<psf:Property name="psk:DisplayName">
<psf:Value xsi:type="xsd:string">Standard</psf:Value>
</psf:Property>
</psf:Option>
</psf:Feature>
</psf:PrintCapabilities>)";
constexpr char kJsonPageOutputQuality[] = R"({
"display_name": "Page output quality",
"id": "page_output_quality",
"select_cap": {
"option": [ {
"display_name": "Draft",
"value": "ns0000:Draft"
}, {
"display_name": "Standard",
"value": "ns0000:Standard"
} ]
},
"type": "SELECT"
})";
#endif
void RecordGetDefaultPrinter(std::string& default_printer_out,
const std::string& default_printer) { … }
void RecordPrinterList(size_t& call_count,
base::Value::List& printers_out,
base::Value::List printers) { … }
void RecordPrintersDone(bool& is_done_out) { … }
void RecordGetCapability(base::Value::Dict& capabilities_out,
base::Value::Dict capability) { … }
base::Value GetJSONAsValue(std::string_view json, std::string& error) { … }
}
class LocalPrinterHandlerDefaultTestBase : public testing::Test { … };
class LocalPrinterHandlerDefaultTest
: public LocalPrinterHandlerDefaultTestBase,
public testing::WithParamInterface<bool> { … };
#if BUILDFLAG(ENABLE_OOP_PRINTING)
class LocalPrinterHandlerDefaultWithServiceTest
: public LocalPrinterHandlerDefaultTestBase { … };
#if BUILDFLAG(IS_WIN)
class LocalPrinterHandlerDefaultWithServiceEnableXpsTest
: public LocalPrinterHandlerDefaultWithServiceTest {
public:
bool EnableXpsCapabilities() override { return true; }
};
#endif
INSTANTIATE_TEST_SUITE_P(…);
#else
INSTANTIATE_TEST_SUITE_P(,
LocalPrinterHandlerDefaultTest,
testing::Values(false));
#endif
TEST_P(LocalPrinterHandlerDefaultTest, GetDefaultPrinter) { … }
TEST_P(LocalPrinterHandlerDefaultTest, GetDefaultPrinterNoneInstalled) { … }
#if BUILDFLAG(ENABLE_OOP_PRINTING)
TEST_F(LocalPrinterHandlerDefaultWithServiceTest,
GetDefaultPrinterTerminatedService) { … }
#endif
TEST_P(LocalPrinterHandlerDefaultTest, GetPrinters) { … }
TEST_P(LocalPrinterHandlerDefaultTest, GetPrintersNoneRegistered) { … }
#if BUILDFLAG(ENABLE_OOP_PRINTING)
TEST_F(LocalPrinterHandlerDefaultWithServiceTest,
GetPrintersInvalidPrinterDataFails) { … }
TEST_F(LocalPrinterHandlerDefaultWithServiceTest,
GetPrintersTerminatedService) { … }
#endif
TEST_P(LocalPrinterHandlerDefaultTest, StartGetCapabilityValidPrinter) { … }
TEST_P(LocalPrinterHandlerDefaultTest, StartGetCapabilityInvalidPrinter) { … }
#if BUILDFLAG(ENABLE_OOP_PRINTING)
TEST_P(LocalPrinterHandlerDefaultTest, StartGetCapabilityAccessDenied) { … }
TEST_F(LocalPrinterHandlerDefaultWithServiceTest,
StartGetCapabilityElevatedPermissionsSucceeds) { … }
TEST_F(LocalPrinterHandlerDefaultWithServiceTest,
StartGetCapabilityInvalidPrinterDataFails) { … }
TEST_F(LocalPrinterHandlerDefaultWithServiceTest,
StartGetCapabilityTerminatedService) { … }
#if BUILDFLAG(IS_WIN)
TEST_F(LocalPrinterHandlerDefaultWithServiceEnableXpsTest,
FetchXpsPrinterCapabilitiesValidXps) {
AddPrinter("printer1", "default1", "description1", true,
false);
SetPrinterXml("printer1", kXmlTestFeature);
base::Value::Dict fetched_caps;
local_printer_handler()->StartGetCapability(
"printer1",
base::BindOnce(&RecordGetCapability, std::ref(fetched_caps)));
RunUntilIdle();
const base::Value::Dict* capabilities =
fetched_caps.FindDict(kSettingCapabilities);
ASSERT_TRUE(capabilities);
EXPECT_TRUE(fetched_caps.FindDict(kPrinter));
const base::Value::Dict* printer = capabilities->FindDict(kPrinter);
ASSERT_TRUE(printer);
ASSERT_FALSE(printer->FindList(kVendorCapabilities));
}
TEST_F(LocalPrinterHandlerDefaultWithServiceEnableXpsTest,
FetchXpsPrinterCapabilitiesValidXpsCapabilityWithInterest) {
AddPrinter("printer1", "default1", "description1", true,
false);
SetPrinterXml("printer1", kXmlPageOutputQuality);
base::Value::Dict fetched_caps;
local_printer_handler()->StartGetCapability(
"printer1",
base::BindOnce(&RecordGetCapability, std::ref(fetched_caps)));
RunUntilIdle();
const base::Value::Dict* capabilities =
fetched_caps.FindDict(kSettingCapabilities);
ASSERT_TRUE(capabilities);
EXPECT_TRUE(fetched_caps.FindDict(kPrinter));
const base::Value::Dict* printer = capabilities->FindDict(kPrinter);
ASSERT_TRUE(printer);
const base::Value::List* vendor_capabilities =
printer->FindList(kVendorCapabilities);
ASSERT_TRUE(vendor_capabilities);
ASSERT_EQ(vendor_capabilities->size(), 1u);
EXPECT_EQ(vendor_capabilities->front(),
base::test::ParseJson(kJsonPageOutputQuality));
}
TEST_F(LocalPrinterHandlerDefaultWithServiceEnableXpsTest,
FetchXpsPrinterCapabilitiesInvalidXps) {
AddPrinter("printer1", "default1", "description1", true,
false);
SetPrinterXml("printer1", "");
base::Value::Dict fetched_caps;
local_printer_handler()->StartGetCapability(
"printer1",
base::BindOnce(&RecordGetCapability, std::ref(fetched_caps)));
RunUntilIdle();
const base::Value::Dict* capabilities =
fetched_caps.FindDict(kSettingCapabilities);
ASSERT_FALSE(capabilities);
}
#endif
#endif
}