blob: 64cf25f7c34cf329444748f23ada0ba6723e87c0 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/printing/browser/printer_capabilities.h"
#include <memory>
#include "base/bind.h"
#include "base/memory/ref_counted.h"
#include "base/stl_util.h"
#include "base/values.h"
#include "content/public/test/browser_task_environment.h"
#include "printing/backend/test_print_backend.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/size.h"
namespace printing {
using base::Value;
namespace {
const char kDpi[] = "dpi";
} // namespace
class PrinterCapabilitiesTest : public testing::Test {
public:
PrinterCapabilitiesTest() {}
~PrinterCapabilitiesTest() override {}
protected:
void SetUp() override {
test_backend_ = base::MakeRefCounted<TestPrintBackend>();
PrintBackend::SetPrintBackendForTesting(test_backend_.get());
}
void TearDown() override { test_backend_ = nullptr; }
TestPrintBackend* print_backend() { return test_backend_.get(); }
private:
content::BrowserTaskEnvironment task_environment_;
scoped_refptr<TestPrintBackend> test_backend_;
};
// Verify that we don't crash for a missing printer and a nullptr is never
// returned.
TEST_F(PrinterCapabilitiesTest, NonNullForMissingPrinter) {
std::string printer_name = "missing_printer";
PrinterBasicInfo basic_info;
PrinterSemanticCapsAndDefaults::Papers no_additional_papers;
base::Value settings_dictionary =
GetSettingsOnBlockingPool(printer_name, basic_info, no_additional_papers,
/* has_secure_protocol */ false, nullptr);
ASSERT_FALSE(settings_dictionary.DictEmpty());
}
TEST_F(PrinterCapabilitiesTest, ProvidedCapabilitiesUsed) {
std::string printer_name = "test_printer";
PrinterBasicInfo basic_info;
PrinterSemanticCapsAndDefaults::Papers no_additional_papers;
// Set a capability and add a valid printer.
auto caps = std::make_unique<PrinterSemanticCapsAndDefaults>();
caps->dpis = {{600, 600}};
print_backend()->AddValidPrinter(printer_name, std::move(caps));
base::Value settings_dictionary = GetSettingsOnBlockingPool(
printer_name, basic_info, no_additional_papers,
/* has_secure_protocol */ false, print_backend());
// Verify settings were created.
ASSERT_FALSE(settings_dictionary.DictEmpty());
// Verify capabilities dict exists and has 2 entries. (printer and version)
base::Value* cdd = settings_dictionary.FindKeyOfType(
kSettingCapabilities, base::Value::Type::DICTIONARY);
ASSERT_TRUE(cdd);
EXPECT_EQ(2U, cdd->DictSize());
// Read the CDD for the "dpi" attribute.
base::Value* caps_dict =
cdd->FindKeyOfType(kPrinter, base::Value::Type::DICTIONARY);
ASSERT_TRUE(caps_dict);
EXPECT_TRUE(caps_dict->FindKey(kDpi));
}
// Ensure that the capabilities dictionary is present but empty if the backend
// doesn't return capabilities.
TEST_F(PrinterCapabilitiesTest, NullCapabilitiesExcluded) {
std::string printer_name = "test_printer";
PrinterBasicInfo basic_info;
PrinterSemanticCapsAndDefaults::Papers no_additional_papers;
// Return false when attempting to retrieve capabilities.
print_backend()->AddValidPrinter(printer_name, nullptr);
base::Value settings_dictionary = GetSettingsOnBlockingPool(
printer_name, basic_info, no_additional_papers,
/* has_secure_protocol */ false, print_backend());
// Verify settings were created.
ASSERT_FALSE(settings_dictionary.DictEmpty());
// Verify that capabilities is an empty dictionary.
base::Value* caps_dict = settings_dictionary.FindKeyOfType(
kSettingCapabilities, base::Value::Type::DICTIONARY);
ASSERT_TRUE(caps_dict);
EXPECT_TRUE(caps_dict->DictEmpty());
}
TEST_F(PrinterCapabilitiesTest, AdditionalPapers) {
std::string printer_name = "test_printer";
PrinterBasicInfo basic_info;
// Set a capability and add a valid printer.
auto caps = std::make_unique<PrinterSemanticCapsAndDefaults>();
caps->dpis = {{600, 600}};
print_backend()->AddValidPrinter(printer_name, std::move(caps));
// Add some more paper sizes.
PrinterSemanticCapsAndDefaults::Papers additional_papers;
additional_papers.push_back({"foo", "vendor", {200, 300}});
additional_papers.push_back({"bar", "vendor", {600, 600}});
base::Value settings_dictionary = GetSettingsOnBlockingPool(
printer_name, basic_info, additional_papers,
/* has_secure_protocol */ false, print_backend());
// Verify settings were created.
ASSERT_FALSE(settings_dictionary.DictEmpty());
// Verify there is a CDD with a printer entry.
const Value* cdd = settings_dictionary.FindKeyOfType(kSettingCapabilities,
Value::Type::DICTIONARY);
ASSERT_TRUE(cdd);
const Value* printer = cdd->FindKeyOfType(kPrinter, Value::Type::DICTIONARY);
ASSERT_TRUE(printer);
// Verify there are 2 paper sizes.
const Value* media_size =
printer->FindKeyOfType("media_size", Value::Type::DICTIONARY);
ASSERT_TRUE(media_size);
const Value* media_option =
media_size->FindKeyOfType("option", Value::Type::LIST);
ASSERT_TRUE(media_option);
const auto& list = media_option->GetList();
ASSERT_EQ(2U, list.size());
ASSERT_TRUE(list[0].is_dict());
ASSERT_TRUE(list[1].is_dict());
// Verify the 2 paper sizes are the ones in |additional_papers|.
const Value* name;
const Value* vendor;
const Value* width;
const Value* height;
name = list[0].FindKeyOfType("custom_display_name", Value::Type::STRING);
ASSERT_TRUE(name);
EXPECT_EQ("foo", name->GetString());
vendor = list[0].FindKeyOfType("vendor_id", Value::Type::STRING);
ASSERT_TRUE(vendor);
EXPECT_EQ("vendor", vendor->GetString());
width = list[0].FindKeyOfType("width_microns", Value::Type::INTEGER);
ASSERT_TRUE(width);
EXPECT_EQ(200, width->GetInt());
height = list[0].FindKeyOfType("height_microns", Value::Type::INTEGER);
ASSERT_TRUE(height);
EXPECT_EQ(300, height->GetInt());
name = list[1].FindKeyOfType("custom_display_name", Value::Type::STRING);
ASSERT_TRUE(name);
EXPECT_EQ("bar", name->GetString());
vendor = list[1].FindKeyOfType("vendor_id", Value::Type::STRING);
ASSERT_TRUE(vendor);
EXPECT_EQ("vendor", vendor->GetString());
width = list[1].FindKeyOfType("width_microns", Value::Type::INTEGER);
ASSERT_TRUE(width);
EXPECT_EQ(600, width->GetInt());
height = list[1].FindKeyOfType("height_microns", Value::Type::INTEGER);
ASSERT_TRUE(height);
EXPECT_EQ(600, height->GetInt());
}
#if defined(OS_CHROMEOS)
TEST_F(PrinterCapabilitiesTest, HasNotSecureProtocol) {
std::string printer_name = "test_printer";
PrinterBasicInfo basic_info;
PrinterSemanticCapsAndDefaults::Papers no_additional_papers;
bool has_secure_protocol = false;
// Set a capability and add a valid printer.
auto caps = std::make_unique<PrinterSemanticCapsAndDefaults>();
caps->pin_supported = true;
print_backend()->AddValidPrinter(printer_name, std::move(caps));
base::Value settings_dictionary =
GetSettingsOnBlockingPool(printer_name, basic_info, no_additional_papers,
has_secure_protocol, print_backend());
// Verify settings were created.
ASSERT_FALSE(settings_dictionary.DictEmpty());
// Verify there is a CDD with a printer entry.
const Value* cdd = settings_dictionary.FindKeyOfType(kSettingCapabilities,
Value::Type::DICTIONARY);
ASSERT_TRUE(cdd);
const Value* printer = cdd->FindKeyOfType(kPrinter, Value::Type::DICTIONARY);
ASSERT_TRUE(printer);
// Verify that pin is not supported.
const Value* pin = printer->FindKeyOfType("pin", Value::Type::DICTIONARY);
ASSERT_TRUE(pin);
base::Optional<bool> pin_supported = pin->FindBoolKey("supported");
ASSERT_TRUE(pin_supported.has_value());
ASSERT_FALSE(pin_supported.value());
}
#endif // defined(OS_CHROMEOS)
} // namespace printing