printing_context_chromeos_unittest.cc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. // Copyright 2020 The Chromium Authors
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "printing/printing_context_chromeos.h"
  5. #include <string>
  6. #include "base/memory/raw_ptr.h"
  7. #include "base/strings/utf_string_conversions.h"
  8. #include "printing/backend/cups_ipp_constants.h"
  9. #include "testing/gmock/include/gmock/gmock.h"
  10. #include "testing/gtest/include/gtest/gtest.h"
  11. namespace printing {
  12. namespace {
  13. using ::testing::_;
  14. using ::testing::ByMove;
  15. using ::testing::DoAll;
  16. using ::testing::Return;
  17. using ::testing::SaveArg;
  18. constexpr char kPrinterName[] = "printer";
  19. constexpr char16_t kPrinterName16[] = u"printer";
  20. constexpr char kUsername[] = "test user";
  21. constexpr char kDocumentName[] = "document name";
  22. constexpr char16_t kDocumentName16[] = u"document name";
  23. class MockCupsPrinter : public CupsPrinter {
  24. public:
  25. MOCK_CONST_METHOD0(is_default, bool());
  26. MOCK_CONST_METHOD0(GetName, std::string());
  27. MOCK_CONST_METHOD0(GetMakeAndModel, std::string());
  28. MOCK_CONST_METHOD0(GetInfo, std::string());
  29. MOCK_CONST_METHOD0(GetUri, std::string());
  30. MOCK_CONST_METHOD0(EnsureDestInfo, bool());
  31. MOCK_CONST_METHOD1(ToPrinterInfo, bool(PrinterBasicInfo* basic_info));
  32. MOCK_METHOD4(CreateJob,
  33. ipp_status_t(int* job_id,
  34. const std::string& title,
  35. const std::string& username,
  36. const std::vector<cups_option_t>& options));
  37. MOCK_METHOD5(StartDocument,
  38. bool(int job_id,
  39. const std::string& docname,
  40. bool last_doc,
  41. const std::string& username,
  42. const std::vector<cups_option_t>& options));
  43. MOCK_METHOD1(StreamData, bool(const std::vector<char>& buffer));
  44. MOCK_METHOD0(FinishDocument, bool());
  45. MOCK_METHOD2(CloseJob, ipp_status_t(int job_id, const std::string& username));
  46. MOCK_METHOD1(CancelJob, bool(int job_id));
  47. MOCK_METHOD1(GetMediaMarginsByName,
  48. CupsMediaMargins(const std::string& media_id));
  49. MOCK_CONST_METHOD1(GetSupportedOptionValues,
  50. ipp_attribute_t*(const char* option_name));
  51. MOCK_CONST_METHOD1(GetSupportedOptionValueStrings,
  52. std::vector<base::StringPiece>(const char* option_name));
  53. MOCK_CONST_METHOD1(GetDefaultOptionValue,
  54. ipp_attribute_t*(const char* option_name));
  55. MOCK_CONST_METHOD2(CheckOptionSupported,
  56. bool(const char* name, const char* value));
  57. };
  58. class MockCupsConnection : public CupsConnection {
  59. public:
  60. MOCK_METHOD1(GetDests, bool(std::vector<std::unique_ptr<CupsPrinter>>&));
  61. MOCK_METHOD2(GetJobs,
  62. bool(const std::vector<std::string>& printer_ids,
  63. std::vector<QueueStatus>* jobs));
  64. MOCK_METHOD2(GetPrinterStatus,
  65. bool(const std::string& printer_id,
  66. PrinterStatus* printer_status));
  67. MOCK_CONST_METHOD0(server_name, std::string());
  68. MOCK_CONST_METHOD0(last_error, int());
  69. MOCK_CONST_METHOD0(last_error_message, std::string());
  70. MOCK_METHOD1(GetPrinter,
  71. std::unique_ptr<CupsPrinter>(const std::string& printer_name));
  72. };
  73. class TestPrintSettings : public PrintSettings {
  74. public:
  75. TestPrintSettings() { set_duplex_mode(mojom::DuplexMode::kSimplex); }
  76. };
  77. class PrintingContextTest : public testing::Test,
  78. public PrintingContext::Delegate {
  79. public:
  80. void SetDefaultSettings(bool send_user_info, const std::string& uri) {
  81. auto unique_connection = std::make_unique<MockCupsConnection>();
  82. auto* connection = unique_connection.get();
  83. auto unique_printer = std::make_unique<MockCupsPrinter>();
  84. printer_ = unique_printer.get();
  85. EXPECT_CALL(*printer_, GetUri()).WillRepeatedly(Return(uri));
  86. EXPECT_CALL(*connection, GetPrinter(kPrinterName))
  87. .WillOnce(Return(ByMove(std::move(unique_printer))));
  88. printing_context_ = PrintingContextChromeos::CreateForTesting(
  89. this, std::move(unique_connection));
  90. auto settings = std::make_unique<PrintSettings>();
  91. settings->set_device_name(kPrinterName16);
  92. settings->set_send_user_info(send_user_info);
  93. settings->set_duplex_mode(mojom::DuplexMode::kLongEdge);
  94. settings->set_username(kUsername);
  95. printing_context_->UpdatePrintSettingsFromPOD(std::move(settings));
  96. }
  97. void TestCupsOptionValue(const char* option_name,
  98. const char* expected_option_value) const {
  99. DCHECK(option_name);
  100. auto cups_options = SettingsToCupsOptions(settings_);
  101. const char* ret = nullptr;
  102. for (const auto& option : cups_options) {
  103. EXPECT_TRUE(option->name);
  104. EXPECT_TRUE(option->value);
  105. if (option->name && !strcmp(option_name, option->name)) {
  106. EXPECT_EQ(nullptr, ret)
  107. << "Multiple options with name " << option_name << " found.";
  108. ret = option->value;
  109. }
  110. }
  111. EXPECT_STREQ(expected_option_value, ret);
  112. }
  113. TestPrintSettings settings_;
  114. // PrintingContext::Delegate methods.
  115. gfx::NativeView GetParentView() override { return nullptr; }
  116. std::string GetAppLocale() override { return std::string(); }
  117. std::unique_ptr<PrintingContextChromeos> printing_context_;
  118. raw_ptr<MockCupsPrinter> printer_;
  119. };
  120. TEST_F(PrintingContextTest, SettingsToCupsOptions_Color) {
  121. settings_.set_color(mojom::ColorModel::kGray);
  122. TestCupsOptionValue(kIppColor, "monochrome");
  123. settings_.set_color(mojom::ColorModel::kColor);
  124. TestCupsOptionValue(kIppColor, "color");
  125. }
  126. TEST_F(PrintingContextTest, SettingsToCupsOptions_Duplex) {
  127. settings_.set_duplex_mode(mojom::DuplexMode::kSimplex);
  128. TestCupsOptionValue(kIppDuplex, "one-sided");
  129. settings_.set_duplex_mode(mojom::DuplexMode::kLongEdge);
  130. TestCupsOptionValue(kIppDuplex, "two-sided-long-edge");
  131. settings_.set_duplex_mode(mojom::DuplexMode::kShortEdge);
  132. TestCupsOptionValue(kIppDuplex, "two-sided-short-edge");
  133. }
  134. TEST_F(PrintingContextTest, SettingsToCupsOptions_Media) {
  135. TestCupsOptionValue(kIppMedia, "");
  136. settings_.set_requested_media(
  137. {gfx::Size(297000, 420000), "iso_a3_297x420mm"});
  138. TestCupsOptionValue(kIppMedia, "iso_a3_297x420mm");
  139. }
  140. TEST_F(PrintingContextTest, SettingsToCupsOptions_Copies) {
  141. settings_.set_copies(3);
  142. TestCupsOptionValue(kIppCopies, "3");
  143. }
  144. TEST_F(PrintingContextTest, SettingsToCupsOptions_Collate) {
  145. TestCupsOptionValue(kIppCollate, "separate-documents-uncollated-copies");
  146. settings_.set_collate(true);
  147. TestCupsOptionValue(kIppCollate, "separate-documents-collated-copies");
  148. }
  149. TEST_F(PrintingContextTest, SettingsToCupsOptions_Pin) {
  150. TestCupsOptionValue(kIppPin, nullptr);
  151. settings_.set_pin_value("1234");
  152. TestCupsOptionValue(kIppPin, "1234");
  153. }
  154. TEST_F(PrintingContextTest, SettingsToCupsOptions_Resolution) {
  155. TestCupsOptionValue(kIppResolution, nullptr);
  156. settings_.set_dpi_xy(0, 300);
  157. TestCupsOptionValue(kIppResolution, nullptr);
  158. settings_.set_dpi_xy(300, 0);
  159. TestCupsOptionValue(kIppResolution, nullptr);
  160. settings_.set_dpi(600);
  161. TestCupsOptionValue(kIppResolution, "600dpi");
  162. settings_.set_dpi_xy(600, 1200);
  163. TestCupsOptionValue(kIppResolution, "600x1200dpi");
  164. }
  165. TEST_F(PrintingContextTest, SettingsToCupsOptions_SendUserInfo_Secure) {
  166. ipp_status_t status = ipp_status_t::IPP_STATUS_OK;
  167. std::u16string document_name = kDocumentName16;
  168. SetDefaultSettings(/*send_user_info=*/true, "ipps://test-uri");
  169. std::string create_job_document_name;
  170. std::string create_job_username;
  171. std::string start_document_document_name;
  172. std::string start_document_username;
  173. EXPECT_CALL(*printer_, CreateJob)
  174. .WillOnce(DoAll(SaveArg<1>(&create_job_document_name),
  175. SaveArg<2>(&create_job_username), Return(status)));
  176. EXPECT_CALL(*printer_, StartDocument)
  177. .WillOnce(DoAll(SaveArg<1>(&start_document_document_name),
  178. SaveArg<3>(&start_document_username), Return(true)));
  179. printing_context_->NewDocument(document_name);
  180. EXPECT_EQ(create_job_document_name, kDocumentName);
  181. EXPECT_EQ(start_document_document_name, kDocumentName);
  182. EXPECT_EQ(create_job_username, kUsername);
  183. EXPECT_EQ(start_document_username, kUsername);
  184. }
  185. TEST_F(PrintingContextTest, SettingsToCupsOptions_SendUserInfo_Insecure) {
  186. ipp_status_t status = ipp_status_t::IPP_STATUS_OK;
  187. std::u16string document_name = kDocumentName16;
  188. std::string default_username = "chronos";
  189. std::string default_document_name = "-";
  190. SetDefaultSettings(/*send_user_info=*/true, "ipp://test-uri");
  191. std::string create_job_document_name;
  192. std::string create_job_username;
  193. std::string start_document_document_name;
  194. std::string start_document_username;
  195. EXPECT_CALL(*printer_, CreateJob)
  196. .WillOnce(DoAll(SaveArg<1>(&create_job_document_name),
  197. SaveArg<2>(&create_job_username), Return(status)));
  198. EXPECT_CALL(*printer_, StartDocument)
  199. .WillOnce(DoAll(SaveArg<1>(&start_document_document_name),
  200. SaveArg<3>(&start_document_username), Return(true)));
  201. printing_context_->NewDocument(document_name);
  202. EXPECT_EQ(create_job_document_name, default_document_name);
  203. EXPECT_EQ(start_document_document_name, default_document_name);
  204. EXPECT_EQ(create_job_username, default_username);
  205. EXPECT_EQ(start_document_username, default_username);
  206. }
  207. TEST_F(PrintingContextTest, SettingsToCupsOptions_DoNotSendUserInfo) {
  208. ipp_status_t status = ipp_status_t::IPP_STATUS_OK;
  209. std::u16string document_name = kDocumentName16;
  210. SetDefaultSettings(/*send_user_info=*/false, "ipps://test-uri");
  211. std::string create_job_document_name;
  212. std::string create_job_username;
  213. std::string start_document_document_name;
  214. std::string start_document_username;
  215. EXPECT_CALL(*printer_, CreateJob)
  216. .WillOnce(DoAll(SaveArg<1>(&create_job_document_name),
  217. SaveArg<2>(&create_job_username), Return(status)));
  218. EXPECT_CALL(*printer_, StartDocument)
  219. .WillOnce(DoAll(SaveArg<1>(&start_document_document_name),
  220. SaveArg<3>(&start_document_username), Return(true)));
  221. printing_context_->NewDocument(document_name);
  222. EXPECT_EQ(create_job_document_name, "");
  223. EXPECT_EQ(start_document_document_name, "");
  224. EXPECT_EQ(create_job_username, "");
  225. EXPECT_EQ(start_document_username, "");
  226. }
  227. } // namespace
  228. } // namespace printing