chromium/chrome/browser/chromeos/printing/print_preview/print_settings_converter_unittest.cc

// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/printing/print_preview/print_settings_converter.h"

#include <stdint.h>

#include <map>
#include <memory>
#include <string>
#include <string_view>
#include <vector>

#include "base/containers/flat_map.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chromeos/crosapi/mojom/print_preview_cros.mojom.h"
#include "components/printing/common/print.mojom.h"
#include "printing/mojom/print.mojom-shared.h"
#include "printing/mojom/print.mojom.h"
#include "printing/print_job_constants.h"
#include "printing/print_settings_conversion_chromeos.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

namespace chromeos {

namespace {

constexpr char kAdvancedSettingKey[] = "foo";
constexpr char kUrl[] = "https://www.google.com";
constexpr char kVendorId[] = "google";
constexpr int kMargin = 1;
constexpr int kAdvancedSettingValue = 1;
constexpr int kMediaSize = 100;

}  // namespace

class PrintSettingsConverterTest : public testing::Test {
 public:
  PrintSettingsConverterTest() = default;

  PrintSettingsConverterTest(const PrintSettingsConverterTest&) = delete;
  PrintSettingsConverterTest& operator=(const PrintSettingsConverterTest&) =
      delete;

  ~PrintSettingsConverterTest() override = default;
};

TEST_F(PrintSettingsConverterTest, SerializePrintSettings) {
  const uint32_t preview_id = 1;
  const uint32_t request_id = 1;
  const bool is_first_request = true;
  const ::printing::mojom::PrinterType printer_type =
      ::printing::mojom::PrinterType::kLocal;
  const ::printing::mojom::MarginType margin_type =
      ::printing::mojom::MarginType::kDefaultMargins;
  const crosapi::mojom::ScalingType scaling_type =
      crosapi::mojom::ScalingType::kCustom;
  const bool collate = true;
  const uint32_t copies = 1;
  const ::printing::mojom::ColorModel color =
      ::printing::mojom::ColorModel::kColor;
  const ::printing::mojom::DuplexMode duplex_mode =
      ::printing::mojom::DuplexMode::kSimplex;
  const bool landscape = true;
  const uint32_t scale_factor = 1;
  const bool rasterize_pdf = true;
  const uint32_t pages_per_sheet = 1;
  const uint32_t dpi_horizontal = 100;
  const uint32_t dpi_vertical = 100;
  const bool header_footer_enabled = true;
  const bool should_print_backgrounds = true;
  const bool should_print_selection_only = true;
  const std::u16string_view title = u"Title";
  const GURL url(kUrl);
  const std::u16string_view device_name = u"device";
  const bool borderless = true;
  const std::u16string_view media_type = u"LETTER";
  const bool preview_modifiable = true;
  const bool send_user_info = false;
  const std::u16string_view user_name = u"username";
  const std::u16string_view chromeos_access_oauth_token = u"123abc";
  const std::u16string_view pin_value = u"pin";
  const bool printer_manually_selected = true;
  const crosapi::mojom::StatusReason::Reason status_reason =
      crosapi::mojom::StatusReason::Reason::kDeviceError;
  const std::u16string_view capabilities = u"{has_selection: true}";
  const bool open_pdf_in_preview = true;
  const bool dpi_default = true;
  const uint32_t page_count = 1;
  const bool show_system_dialog = false;
  const std::vector<uint32_t> page_range({1, 2});

  std::vector<::printing::mojom::IppClientInfoPtr> client_info_list;
  const ::printing::mojom::IppClientInfoPtr client_info =
      ::printing::mojom::IppClientInfo::New();
  client_info_list.push_back(client_info.Clone());

  base::flat_map<std::string, base::Value> advanced_settings;
  advanced_settings.insert_or_assign(kAdvancedSettingKey, base::Value(1));

  crosapi::mojom::MarginsCustomPtr margins_custom =
      crosapi::mojom::MarginsCustom::New();
  margins_custom->margin_top = kMargin;
  margins_custom->margin_bottom = kMargin;
  margins_custom->margin_left = kMargin;
  margins_custom->margin_right = kMargin;

  crosapi::mojom::MediaSizePtr media_size = crosapi::mojom::MediaSize::New();
  media_size->width_microns = kMediaSize;
  media_size->height_microns = kMediaSize;
  media_size->imageable_area_bottom_microns = kMediaSize;
  media_size->imageable_area_top_microns = kMediaSize;
  media_size->imageable_area_left_microns = kMediaSize;
  media_size->imageable_area_right_microns = kMediaSize;
  media_size->vendor_id = base::UTF8ToUTF16(std::string(kVendorId));
  media_size->custom_display_name = u"custom_display_name";
  media_size->is_default = true;
  media_size->name = u"name";

  auto print_settings = crosapi::mojom::PrintSettings::New();
  print_settings->preview_id = preview_id;
  print_settings->request_id = request_id;
  print_settings->is_first_request = is_first_request;
  print_settings->printer_type = printer_type;
  print_settings->margin_type = margin_type;
  print_settings->scaling_type = scaling_type;
  print_settings->margin_type = margin_type;
  print_settings->collate = collate;
  print_settings->copies = copies;
  print_settings->color = color;
  print_settings->duplex = duplex_mode;
  print_settings->landscape = landscape;
  print_settings->scale_factor = scale_factor;
  print_settings->rasterize_pdf = rasterize_pdf;
  print_settings->pages_per_sheet = pages_per_sheet;
  print_settings->dpi_horizontal = dpi_horizontal;
  print_settings->dpi_vertical = dpi_vertical;
  print_settings->header_footer_enabled = header_footer_enabled;
  print_settings->should_print_backgrounds = should_print_backgrounds;
  print_settings->should_print_selection_only = should_print_selection_only;
  print_settings->title = title;
  print_settings->url = url;
  print_settings->device_name = device_name;
  print_settings->borderless = borderless;
  print_settings->media_type = media_type;
  print_settings->preview_modifiable = preview_modifiable;
  print_settings->send_user_info = send_user_info;
  print_settings->user_name = user_name;
  print_settings->chromeos_access_oauth_token = chromeos_access_oauth_token;
  print_settings->pin_value = pin_value;
  print_settings->printer_manually_selected = printer_manually_selected;
  print_settings->printer_status_reason = status_reason;
  print_settings->capabilities = capabilities;
  print_settings->open_pdf_in_preview = open_pdf_in_preview;
  print_settings->dpi_default = dpi_default;
  print_settings->page_count = page_count;
  print_settings->show_system_dialog = show_system_dialog;
  print_settings->ipp_client_info = mojo::Clone(client_info_list);
  print_settings->advanced_settings = mojo::Clone(advanced_settings);
  print_settings->page_range = page_range;
  print_settings->margins_custom = margins_custom.Clone();
  print_settings->media_size = media_size.Clone();

  // Serialize the settings.
  base::Value::Dict serialized_settings =
      SerializePrintSettings(print_settings);

  // Validate the serialization.
  EXPECT_EQ(static_cast<int>(preview_id),
            *serialized_settings.FindInt(::printing::kPreviewUIID));
  EXPECT_EQ(static_cast<int>(request_id),
            *serialized_settings.FindInt(::printing::kPreviewRequestID));
  EXPECT_EQ(is_first_request,
            *serialized_settings.FindBool(::printing::kIsFirstRequest));
  EXPECT_EQ(static_cast<int>(printer_type),
            *serialized_settings.FindInt(::printing::kSettingPrinterType));
  EXPECT_EQ(static_cast<int>(margin_type),
            *serialized_settings.FindInt(::printing::kSettingMarginsType));
  EXPECT_EQ(static_cast<int>(scaling_type),
            *serialized_settings.FindInt(::printing::kSettingScalingType));
  EXPECT_EQ(collate,
            *serialized_settings.FindBool(::printing::kSettingCollate));
  EXPECT_EQ(static_cast<int>(copies),
            *serialized_settings.FindInt(::printing::kSettingCopies));
  EXPECT_EQ(static_cast<int>(color),
            *serialized_settings.FindInt(::printing::kSettingColor));
  EXPECT_EQ(static_cast<int>(duplex_mode),
            *serialized_settings.FindInt(::printing::kSettingDuplexMode));
  EXPECT_EQ(landscape,
            *serialized_settings.FindBool(::printing::kSettingLandscape));
  EXPECT_EQ(static_cast<int>(scale_factor),
            *serialized_settings.FindInt(::printing::kSettingScaleFactor));
  EXPECT_EQ(rasterize_pdf,
            *serialized_settings.FindBool(::printing::kSettingRasterizePdf));
  EXPECT_EQ(static_cast<int>(pages_per_sheet),
            *serialized_settings.FindInt(::printing::kSettingPagesPerSheet));
  EXPECT_EQ(static_cast<int>(dpi_horizontal),
            *serialized_settings.FindInt(::printing::kSettingDpiHorizontal));
  EXPECT_EQ(static_cast<int>(dpi_vertical),
            *serialized_settings.FindInt(::printing::kSettingDpiVertical));
  EXPECT_EQ(
      header_footer_enabled,
      *serialized_settings.FindBool(::printing::kSettingHeaderFooterEnabled));
  EXPECT_EQ(should_print_backgrounds,
            *serialized_settings.FindBool(
                ::printing::kSettingShouldPrintBackgrounds));
  EXPECT_EQ(should_print_selection_only,
            *serialized_settings.FindBool(
                ::printing::kSettingShouldPrintSelectionOnly));
  std::string expected_title;
  base::UTF16ToUTF8(title.data(), title.size(), &expected_title);
  EXPECT_EQ(expected_title, *serialized_settings.FindString(
                                ::printing::kSettingHeaderFooterTitle));
  EXPECT_EQ(url.spec(), *serialized_settings.FindString(
                            ::printing::kSettingHeaderFooterURL));
  std::string expected_device_name;
  base::UTF16ToUTF8(device_name.data(), device_name.size(),
                    &expected_device_name);
  EXPECT_EQ(expected_device_name,
            *serialized_settings.FindString(::printing::kSettingDeviceName));
  EXPECT_EQ(borderless,
            *serialized_settings.FindBool(::printing::kSettingBorderless));
  std::string expected_media_type;
  base::UTF16ToUTF8(media_type.data(), media_type.size(), &expected_media_type);
  EXPECT_EQ(expected_media_type,
            *serialized_settings.FindString(::printing::kSettingMediaType));
  EXPECT_EQ(preview_modifiable, *serialized_settings.FindBool(
                                    ::printing::kSettingPreviewModifiable));
  EXPECT_EQ(send_user_info,
            *serialized_settings.FindBool(::printing::kSettingSendUserInfo));
  std::string expected_user_name;
  base::UTF16ToUTF8(user_name.data(), user_name.size(), &expected_user_name);
  EXPECT_EQ(expected_user_name,
            *serialized_settings.FindString(::printing::kSettingUsername));
  std::string expected_oath_token;
  base::UTF16ToUTF8(chromeos_access_oauth_token.data(),
                    chromeos_access_oauth_token.size(), &expected_oath_token);
  EXPECT_EQ(expected_oath_token,
            *serialized_settings.FindString(
                ::printing::kSettingChromeOSAccessOAuthToken));
  std::string expected_pin_value;
  base::UTF16ToUTF8(pin_value.data(), pin_value.size(), &expected_pin_value);
  EXPECT_EQ(expected_pin_value,
            *serialized_settings.FindString(::printing::kSettingPinValue));
  EXPECT_EQ(printer_manually_selected,
            *serialized_settings.FindBool(
                ::printing::kSettingPrinterManuallySelected));
  EXPECT_EQ(
      static_cast<int>(status_reason),
      *serialized_settings.FindInt(::printing::kSettingPrinterStatusReason));
  std::string expected_capabilities;
  base::UTF16ToUTF8(capabilities.data(), capabilities.size(),
                    &expected_capabilities);
  EXPECT_EQ(expected_capabilities,
            *serialized_settings.FindString(::printing::kSettingCapabilities));
  EXPECT_EQ(open_pdf_in_preview, *serialized_settings.FindBool(
                                     ::printing::kSettingOpenPDFInPreview));
  EXPECT_EQ(dpi_default,
            *serialized_settings.FindBool(::printing::kSettingDpiDefault));
  EXPECT_EQ(static_cast<int>(page_count),
            *serialized_settings.FindInt(::printing::kSettingPreviewPageCount));
  EXPECT_EQ(show_system_dialog, *serialized_settings.FindBool(
                                    ::printing::kSettingShowSystemDialog));

  const base::Value::List actual_ipp_clients =
      (*serialized_settings.FindList(::printing::kSettingIppClientInfo))
          .Clone();

  EXPECT_EQ(client_info_list.size(), actual_ipp_clients.size());
  // Only one entry in the list.
  EXPECT_EQ(client_info_list[0]->client_name,
            *(actual_ipp_clients[0].GetDict().FindString(
                ::printing::kSettingIppClientName)));
  EXPECT_EQ(client_info_list[0]->client_string_version,
            *actual_ipp_clients[0].GetDict().FindString(
                ::printing::kSettingIppClientStringVersion));
  EXPECT_EQ(static_cast<int>(client_info_list[0]->client_type),
            actual_ipp_clients[0].GetDict().FindInt(
                ::printing::kSettingIppClientType));

  const base::Value::List actual_page_range =
      (*serialized_settings.FindList(::printing::kSettingPageRange)).Clone();
  // Only two entries in the list.
  EXPECT_EQ(static_cast<int>(page_range[0]),
            actual_page_range[0].GetDict().FindInt(
                ::printing::kSettingPageRangeFrom));
  EXPECT_EQ(
      static_cast<int>(page_range[1]),
      actual_page_range[0].GetDict().FindInt(::printing::kSettingPageRangeTo));

  const base::Value::Dict actual_margins_custom =
      (*serialized_settings.FindDict(::printing::kSettingMarginsCustom))
          .Clone();
  EXPECT_EQ(kMargin,
            actual_margins_custom.FindInt(::printing::kSettingMarginTop));
  EXPECT_EQ(kMargin,
            actual_margins_custom.FindInt(::printing::kSettingMarginBottom));
  EXPECT_EQ(kMargin,
            actual_margins_custom.FindInt(::printing::kSettingMarginTop));
  EXPECT_EQ(kMargin,
            actual_margins_custom.FindInt(::printing::kSettingMarginTop));

  const base::Value::Dict actual_media_size =
      (*serialized_settings.FindDict(::printing::kSettingMediaSize)).Clone();
  EXPECT_EQ(kMediaSize, actual_media_size.FindInt(
                            ::printing::kSettingMediaSizeWidthMicrons));
  EXPECT_EQ(kMediaSize, actual_media_size.FindInt(
                            ::printing::kSettingMediaSizeHeightMicrons));
  EXPECT_EQ(kMediaSize, actual_media_size.FindInt(
                            printing::kSettingsImageableAreaBottomMicrons));
  EXPECT_EQ(kMediaSize, actual_media_size.FindInt(
                            printing::kSettingsImageableAreaTopMicrons));
  EXPECT_EQ(kMediaSize, actual_media_size.FindInt(
                            printing::kSettingsImageableAreaLeftMicrons));
  EXPECT_EQ(kMediaSize, actual_media_size.FindInt(
                            printing::kSettingsImageableAreaRightMicrons));
  EXPECT_EQ(kVendorId, *actual_media_size.FindString(
                           ::printing::kSettingMediaSizeVendorId));
  EXPECT_EQ(media_size->is_default,
            actual_media_size.FindBool(::printing::kSettingMediaSizeIsDefault));

  const base::Value::Dict actual_advanced_settings =
      (*serialized_settings.FindDict(::printing::kSettingAdvancedSettings))
          .Clone();
  EXPECT_EQ(kAdvancedSettingValue,
            actual_advanced_settings.FindInt(kAdvancedSettingKey));
}

}  // namespace chromeos