Skip to content

Commit

Permalink
Add unit tests for the Chrome OS printing context.
Browse files Browse the repository at this point in the history
Add unit tests for SettingsToCupsOptions() in
printing_context_chromeos.cc.

Also refactor the code a bit to expose this function for testing.

Bug: 1001398
Test: ./printing_unittests

Cq-Depend: 2390967
Change-Id: Id0c0765e5ce6a3f3cde3d294afce33c9720f215a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2389102
Commit-Queue: Pranav Batra <batrapranav@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Cr-Commit-Position: refs/heads/master@{#805084}
  • Loading branch information
tsite authored and Commit Bot committed Sep 8, 2020
1 parent 90d3de3 commit 3074423
Show file tree
Hide file tree
Showing 6 changed files with 185 additions and 76 deletions.
4 changes: 3 additions & 1 deletion printing/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,9 @@ test("printing_unittests") {
sources += [ "backend/cups_ipp_helper_unittest.cc" ]
}

if (!is_chromeos) {
if (is_chromeos) {
sources += [ "printing_context_chromeos_unittest.cc" ]
} else {
sources += [
"backend/cups_helper_unittest.cc",
"backend/print_backend_cups_unittest.cc",
Expand Down
10 changes: 6 additions & 4 deletions printing/backend/cups_deleters.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,23 @@
#include <cups/cups.h>
#include <memory>

#include "printing/printing_export.h"

namespace printing {

struct HttpDeleter {
struct PRINTING_EXPORT HttpDeleter {
void operator()(http_t* http) const;
};

struct DestinationDeleter {
struct PRINTING_EXPORT DestinationDeleter {
void operator()(cups_dest_t* dest) const;
};

struct DestInfoDeleter {
struct PRINTING_EXPORT DestInfoDeleter {
void operator()(cups_dinfo_t* info) const;
};

struct OptionDeleter {
struct PRINTING_EXPORT OptionDeleter {
void operator()(cups_option_t* option) const;
};

Expand Down
34 changes: 18 additions & 16 deletions printing/backend/cups_ipp_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,34 @@
#ifndef PRINTING_BACKEND_CUPS_IPP_CONSTANTS_H_
#define PRINTING_BACKEND_CUPS_IPP_CONSTANTS_H_

#include "printing/printing_export.h"

namespace printing {

// property names
extern const char kIppCollate[];
extern const char kIppCopies[];
extern const char kIppColor[];
extern const char kIppMedia[];
extern const char kIppDuplex[];
extern const char kIppRequestingUserName[];
extern const char kIppResolution[];
extern const char kIppPin[];
extern const char kIppPinEncryption[];
PRINTING_EXPORT extern const char kIppCollate[];
PRINTING_EXPORT extern const char kIppCopies[];
PRINTING_EXPORT extern const char kIppColor[];
PRINTING_EXPORT extern const char kIppMedia[];
PRINTING_EXPORT extern const char kIppDuplex[];
PRINTING_EXPORT extern const char kIppRequestingUserName[];
PRINTING_EXPORT extern const char kIppResolution[];
PRINTING_EXPORT extern const char kIppPin[];
PRINTING_EXPORT extern const char kIppPinEncryption[];

// collation values
extern const char kCollated[];
extern const char kUncollated[];
PRINTING_EXPORT extern const char kCollated[];
PRINTING_EXPORT extern const char kUncollated[];

#if defined(OS_CHROMEOS)

extern const char kIppDocumentAttributes[];
extern const char kIppJobAttributes[];
PRINTING_EXPORT extern const char kIppDocumentAttributes[];
PRINTING_EXPORT extern const char kIppJobAttributes[];

extern const char kPinEncryptionNone[];
PRINTING_EXPORT extern const char kPinEncryptionNone[];

extern const char kOptionFalse[];
extern const char kOptionTrue[];
PRINTING_EXPORT extern const char kOptionFalse[];
PRINTING_EXPORT extern const char kOptionTrue[];

#endif // defined(OS_CHROMEOS)

Expand Down
109 changes: 54 additions & 55 deletions printing/printing_context_chromeos.cc
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,60 @@ void ReportEnumUsage(const std::string& attribute_name) {
base::UmaHistogramEnumeration("Printing.CUPS.IppAttributes", it->second);
}

// This records UMA for advanced attributes usage, so only call once per job.
// Given an integral |value| expressed in PWG units (1/100 mm), returns
// the same value expressed in device units.
int PwgUnitsToDeviceUnits(int value, float micrometers_per_device_unit) {
return ConvertUnitDouble(value, micrometers_per_device_unit, 10);
}

// Given a |media_size|, the specification of the media's |margins|, and
// the number of micrometers per device unit, returns the rectangle
// bounding the apparent printable area of said media.
gfx::Rect RepresentPrintableArea(const gfx::Size& media_size,
const CupsPrinter::CupsMediaMargins& margins,
float micrometers_per_device_unit) {
// These values express inward encroachment by margins, away from the
// edges of the |media_size|.
int left_bound =
PwgUnitsToDeviceUnits(margins.left, micrometers_per_device_unit);
int bottom_bound =
PwgUnitsToDeviceUnits(margins.bottom, micrometers_per_device_unit);
int right_bound =
PwgUnitsToDeviceUnits(margins.right, micrometers_per_device_unit);
int top_bound =
PwgUnitsToDeviceUnits(margins.top, micrometers_per_device_unit);

// These values express the bounding box of the printable area on the
// page.
int printable_width = media_size.width() - (left_bound + right_bound);
int printable_height = media_size.height() - (top_bound + bottom_bound);

if (printable_width > 0 && printable_height > 0) {
return {left_bound, bottom_bound, printable_width, printable_height};
}

return {0, 0, media_size.width(), media_size.height()};
}

void SetPrintableArea(PrintSettings* settings,
const PrintSettings::RequestedMedia& media,
const CupsPrinter::CupsMediaMargins& margins,
bool flip) {
if (!media.size_microns.IsEmpty()) {
float device_microns_per_device_unit =
static_cast<float>(kMicronsPerInch) / settings->device_units_per_inch();
gfx::Size paper_size =
gfx::Size(media.size_microns.width() / device_microns_per_device_unit,
media.size_microns.height() / device_microns_per_device_unit);

gfx::Rect paper_rect = RepresentPrintableArea(
paper_size, margins, device_microns_per_device_unit);
settings->SetPrinterPrintableArea(paper_size, paper_rect, flip);
}
}

} // namespace

std::vector<ScopedCupsOption> SettingsToCupsOptions(
const PrintSettings& settings) {
const char* sides = nullptr;
Expand Down Expand Up @@ -182,60 +235,6 @@ std::vector<ScopedCupsOption> SettingsToCupsOptions(
return options;
}

// Given an integral |value| expressed in PWG units (1/100 mm), returns
// the same value expressed in device units.
int PwgUnitsToDeviceUnits(int value, float micrometers_per_device_unit) {
return ConvertUnitDouble(value, micrometers_per_device_unit, 10);
}

// Given a |media_size|, the specification of the media's |margins|, and
// the number of micrometers per device unit, returns the rectangle
// bounding the apparent printable area of said media.
gfx::Rect RepresentPrintableArea(const gfx::Size& media_size,
const CupsPrinter::CupsMediaMargins& margins,
float micrometers_per_device_unit) {
// These values express inward encroachment by margins, away from the
// edges of the |media_size|.
int left_bound =
PwgUnitsToDeviceUnits(margins.left, micrometers_per_device_unit);
int bottom_bound =
PwgUnitsToDeviceUnits(margins.bottom, micrometers_per_device_unit);
int right_bound =
PwgUnitsToDeviceUnits(margins.right, micrometers_per_device_unit);
int top_bound =
PwgUnitsToDeviceUnits(margins.top, micrometers_per_device_unit);

// These values express the bounding box of the printable area on the
// page.
int printable_width = media_size.width() - (left_bound + right_bound);
int printable_height = media_size.height() - (top_bound + bottom_bound);

if (printable_width > 0 && printable_height > 0) {
return {left_bound, bottom_bound, printable_width, printable_height};
}

return {0, 0, media_size.width(), media_size.height()};
}

void SetPrintableArea(PrintSettings* settings,
const PrintSettings::RequestedMedia& media,
const CupsPrinter::CupsMediaMargins& margins,
bool flip) {
if (!media.size_microns.IsEmpty()) {
float device_microns_per_device_unit =
static_cast<float>(kMicronsPerInch) / settings->device_units_per_inch();
gfx::Size paper_size =
gfx::Size(media.size_microns.width() / device_microns_per_device_unit,
media.size_microns.height() / device_microns_per_device_unit);

gfx::Rect paper_rect = RepresentPrintableArea(
paper_size, margins, device_microns_per_device_unit);
settings->SetPrinterPrintableArea(paper_size, paper_rect, flip);
}
}

} // namespace

// static
std::unique_ptr<PrintingContext> PrintingContext::Create(Delegate* delegate) {
return std::make_unique<PrintingContextChromeos>(delegate);
Expand Down
5 changes: 5 additions & 0 deletions printing/printing_context_chromeos.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ class PRINTING_EXPORT PrintingContextChromeos : public PrintingContext {
std::string username_;
};

// This has the side effect of recording UMA for advanced attributes usage,
// so only call once per job.
PRINTING_EXPORT std::vector<ScopedCupsOption> SettingsToCupsOptions(
const PrintSettings& settings);

} // namespace printing

#endif // PRINTING_PRINTING_CONTEXT_CHROMEOS_H_
99 changes: 99 additions & 0 deletions printing/printing_context_chromeos_unittest.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Copyright 2020 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 "printing/printing_context_chromeos.h"

#include <string.h>

#include "printing/backend/cups_ipp_constants.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace printing {

namespace {

const char* GetOptionValue(const std::vector<ScopedCupsOption>& options,
const char* option_name) {
DCHECK(option_name);
const char* ret = nullptr;
for (const auto& option : options) {
EXPECT_TRUE(option->name);
EXPECT_TRUE(option->value);
if (option->name && !strcmp(option_name, option->name)) {
EXPECT_EQ(nullptr, ret)
<< "Multiple options with name " << option_name << " found.";
ret = option->value;
}
}
return ret;
}

class TestPrintSettings : public PrintSettings {
public:
TestPrintSettings() { set_duplex_mode(mojom::DuplexMode::kSimplex); }
};

class PrintingContextTest : public testing::Test {
public:
const char* Get(const char* name) const {
return GetOptionValue(SettingsToCupsOptions(settings_), name);
}
TestPrintSettings settings_;
};

TEST_F(PrintingContextTest, SettingsToCupsOptions_Color) {
settings_.set_color(mojom::ColorModel::kGray);
EXPECT_STREQ("monochrome", Get(kIppColor));
settings_.set_color(mojom::ColorModel::kColor);
EXPECT_STREQ("color", Get(kIppColor));
}

TEST_F(PrintingContextTest, SettingsToCupsOptions_Duplex) {
settings_.set_duplex_mode(mojom::DuplexMode::kSimplex);
EXPECT_STREQ("one-sided", Get(kIppDuplex));
settings_.set_duplex_mode(mojom::DuplexMode::kLongEdge);
EXPECT_STREQ("two-sided-long-edge", Get(kIppDuplex));
settings_.set_duplex_mode(mojom::DuplexMode::kShortEdge);
EXPECT_STREQ("two-sided-short-edge", Get(kIppDuplex));
}

TEST_F(PrintingContextTest, SettingsToCupsOptions_Media) {
EXPECT_STREQ("", Get(kIppMedia));
settings_.set_requested_media(
{gfx::Size(297000, 420000), "iso_a3_297x420mm"});
EXPECT_STREQ("iso_a3_297x420mm", Get(kIppMedia));
}

TEST_F(PrintingContextTest, SettingsToCupsOptions_Copies) {
settings_.set_copies(3);
EXPECT_STREQ("3", Get(kIppCopies));
}

TEST_F(PrintingContextTest, SettingsToCupsOptions_Collate) {
EXPECT_STREQ("separate-documents-uncollated-copies", Get(kIppCollate));
settings_.set_collate(true);
EXPECT_STREQ("separate-documents-collated-copies", Get(kIppCollate));
}

TEST_F(PrintingContextTest, SettingsToCupsOptions_Pin) {
EXPECT_STREQ(nullptr, Get(kIppPin));
settings_.set_pin_value("1234");
EXPECT_STREQ("1234", Get(kIppPin));
}

TEST_F(PrintingContextTest, SettingsToCupsOptions_Resolution) {
EXPECT_STREQ(nullptr, Get(kIppResolution));
settings_.set_dpi_xy(0, 300);
EXPECT_STREQ(nullptr, Get(kIppResolution));
settings_.set_dpi_xy(300, 0);
EXPECT_STREQ(nullptr, Get(kIppResolution));
settings_.set_dpi(600);
EXPECT_STREQ("600dpi", Get(kIppResolution));
settings_.set_dpi_xy(600, 1200);
EXPECT_STREQ("600x1200dpi", Get(kIppResolution));
}

} // namespace

} // namespace printing

0 comments on commit 3074423

Please sign in to comment.