printing_context_chromeos_unittest.cc 10 KB

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