| // Copyright 2016 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 <cups/cups.h> |
| |
| #include <map> |
| #include <memory> |
| |
| #include "base/logging.h" |
| #include "printing/backend/cups_ipp_util.h" |
| #include "printing/backend/cups_printer.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace printing { |
| |
| class MockCupsOptionProvider : public CupsOptionProvider { |
| public: |
| ~MockCupsOptionProvider() override {} |
| |
| ipp_attribute_t* GetSupportedOptionValues( |
| const char* option_name) const override { |
| const auto attr = supported_attributes_.find(option_name); |
| return attr != supported_attributes_.end() ? attr->second : nullptr; |
| } |
| |
| std::vector<base::StringPiece> GetSupportedOptionValueStrings( |
| const char* option_name) const override { |
| ipp_attribute_t* attr = GetSupportedOptionValues(option_name); |
| if (!attr) |
| return std::vector<base::StringPiece>(); |
| |
| std::vector<base::StringPiece> strings; |
| int size = ippGetCount(attr); |
| for (int i = 0; i < size; ++i) { |
| strings.emplace_back(ippGetString(attr, i, nullptr)); |
| } |
| |
| return strings; |
| } |
| |
| ipp_attribute_t* GetDefaultOptionValue( |
| const char* option_name) const override { |
| const auto attr = default_attributes_.find(option_name); |
| return attr != default_attributes_.end() ? attr->second : nullptr; |
| } |
| |
| bool CheckOptionSupported(const char* name, |
| const char* value) const override { |
| NOTREACHED(); |
| return false; |
| } |
| |
| void SetSupportedOptions(base::StringPiece name, ipp_attribute_t* attribute) { |
| supported_attributes_[name] = attribute; |
| } |
| |
| void SetOptionDefault(base::StringPiece name, ipp_attribute_t* attribute) { |
| default_attributes_[name] = attribute; |
| } |
| |
| private: |
| std::map<base::StringPiece, ipp_attribute_t*> supported_attributes_; |
| std::map<base::StringPiece, ipp_attribute_t*> default_attributes_; |
| }; |
| |
| class PrintBackendCupsIppUtilTest : public ::testing::Test { |
| protected: |
| void SetUp() override { |
| ipp_ = ippNew(); |
| printer_ = std::make_unique<MockCupsOptionProvider>(); |
| } |
| |
| void TearDown() override { |
| ippDelete(ipp_); |
| printer_.reset(); |
| } |
| |
| ipp_t* ipp_; |
| std::unique_ptr<MockCupsOptionProvider> printer_; |
| }; |
| |
| ipp_attribute_t* MakeRange(ipp_t* ipp, int lower_bound, int upper_bound) { |
| return ippAddRange(ipp, IPP_TAG_PRINTER, "TEST_DATA", lower_bound, |
| upper_bound); |
| } |
| |
| ipp_attribute_t* MakeString(ipp_t* ipp, const char* value) { |
| return ippAddString(ipp, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "TEST_DATA", |
| nullptr, value); |
| } |
| |
| ipp_attribute_t* MakeStringCollection(ipp_t* ipp, |
| const std::vector<const char*>& strings) { |
| return ippAddStrings(ipp, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "TEST_DATA", |
| strings.size(), nullptr, strings.data()); |
| } |
| |
| TEST_F(PrintBackendCupsIppUtilTest, CopiesCapable) { |
| printer_->SetSupportedOptions("copies", MakeRange(ipp_, 1, 2)); |
| |
| PrinterSemanticCapsAndDefaults caps; |
| CapsAndDefaultsFromPrinter(*printer_, &caps); |
| |
| EXPECT_TRUE(caps.copies_capable); |
| } |
| |
| TEST_F(PrintBackendCupsIppUtilTest, CopiesNotCapable) { |
| // copies missing, no setup |
| PrinterSemanticCapsAndDefaults caps; |
| CapsAndDefaultsFromPrinter(*printer_, &caps); |
| |
| EXPECT_FALSE(caps.copies_capable); |
| } |
| |
| TEST_F(PrintBackendCupsIppUtilTest, ColorPrinter) { |
| printer_->SetSupportedOptions( |
| "print-color-mode", MakeStringCollection(ipp_, {"color", "monochrome"})); |
| printer_->SetOptionDefault("print-color-mode", MakeString(ipp_, "color")); |
| |
| PrinterSemanticCapsAndDefaults caps; |
| CapsAndDefaultsFromPrinter(*printer_, &caps); |
| |
| EXPECT_TRUE(caps.color_changeable); |
| EXPECT_TRUE(caps.color_default); |
| } |
| |
| TEST_F(PrintBackendCupsIppUtilTest, BWPrinter) { |
| printer_->SetSupportedOptions("print-color-mode", |
| MakeStringCollection(ipp_, {"monochrome"})); |
| printer_->SetOptionDefault("print-color-mode", |
| MakeString(ipp_, "monochrome")); |
| |
| PrinterSemanticCapsAndDefaults caps; |
| CapsAndDefaultsFromPrinter(*printer_, &caps); |
| |
| EXPECT_FALSE(caps.color_changeable); |
| EXPECT_FALSE(caps.color_default); |
| } |
| |
| TEST_F(PrintBackendCupsIppUtilTest, DuplexSupported) { |
| printer_->SetSupportedOptions( |
| "sides", |
| MakeStringCollection(ipp_, {"two-sided-long-edge", "one-sided"})); |
| printer_->SetOptionDefault("sides", MakeString(ipp_, "one-sided")); |
| |
| PrinterSemanticCapsAndDefaults caps; |
| CapsAndDefaultsFromPrinter(*printer_, &caps); |
| |
| EXPECT_THAT(caps.duplex_modes, |
| testing::UnorderedElementsAre(SIMPLEX, LONG_EDGE)); |
| EXPECT_EQ(SIMPLEX, caps.duplex_default); |
| } |
| |
| TEST_F(PrintBackendCupsIppUtilTest, DuplexNotSupported) { |
| printer_->SetSupportedOptions("sides", |
| MakeStringCollection(ipp_, {"one-sided"})); |
| printer_->SetOptionDefault("sides", MakeString(ipp_, "one-sided")); |
| |
| PrinterSemanticCapsAndDefaults caps; |
| CapsAndDefaultsFromPrinter(*printer_, &caps); |
| |
| EXPECT_THAT(caps.duplex_modes, testing::UnorderedElementsAre(SIMPLEX)); |
| EXPECT_EQ(SIMPLEX, caps.duplex_default); |
| } |
| |
| TEST_F(PrintBackendCupsIppUtilTest, A4PaperSupported) { |
| printer_->SetSupportedOptions( |
| "media", MakeStringCollection(ipp_, {"iso_a4_210x297mm"})); |
| |
| PrinterSemanticCapsAndDefaults caps; |
| CapsAndDefaultsFromPrinter(*printer_, &caps); |
| |
| PrinterSemanticCapsAndDefaults::Paper paper = caps.papers[0]; |
| EXPECT_EQ("iso a4", paper.display_name); |
| EXPECT_EQ("iso_a4_210x297mm", paper.vendor_id); |
| EXPECT_EQ(210000, paper.size_um.width()); |
| EXPECT_EQ(297000, paper.size_um.height()); |
| } |
| |
| TEST_F(PrintBackendCupsIppUtilTest, LegalPaperDefault) { |
| printer_->SetOptionDefault("media", MakeString(ipp_, "na_legal_8.5x14in")); |
| |
| PrinterSemanticCapsAndDefaults caps; |
| CapsAndDefaultsFromPrinter(*printer_, &caps); |
| |
| EXPECT_EQ("na legal", caps.default_paper.display_name); |
| EXPECT_EQ("na_legal_8.5x14in", caps.default_paper.vendor_id); |
| EXPECT_EQ(215900, caps.default_paper.size_um.width()); |
| EXPECT_EQ(355600, caps.default_paper.size_um.height()); |
| } |
| |
| } // namespace printing |