Commit bba4fd12 authored by Gavin Williams's avatar Gavin Williams Committed by Commit Bot

Add CupsPrinterStatus to the Printer object

- Add CupsPrinterStatus as a private member of the Printer object.

- Create a new map for caching and retrieving printer statuses.

- Add logic for serializing CupsPrinterStatus to JSON.

Bug: 1059607
Change-Id: I86c176df9d23f799486c521b604bebbac9611caa
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2118760Reviewed-by: default avatarZentaro Kavanagh <zentaro@chromium.org>
Reviewed-by: default avatarBailey Berro <baileyberro@chromium.org>
Commit-Queue: Gavin Williams <gavinwill@chromium.org>
Cr-Commit-Position: refs/heads/master@{#760178}
parent fa3f1204
...@@ -67,16 +67,43 @@ void PrintersMap::Insert(PrinterClass printer_class, const Printer& printer) { ...@@ -67,16 +67,43 @@ void PrintersMap::Insert(PrinterClass printer_class, const Printer& printer) {
printers_[printer_class][printer.id()] = printer; printers_[printer_class][printer.id()] = printer;
} }
void PrintersMap::Insert(PrinterClass printer_class,
const Printer& printer,
const CupsPrinterStatus& cups_printer_status) {
Insert(printer_class, printer);
printers_[printer_class][printer.id()].set_printer_status(
cups_printer_status);
}
void PrintersMap::Clear(PrinterClass printer_class) { void PrintersMap::Clear(PrinterClass printer_class) {
printers_[printer_class].clear(); printers_[printer_class].clear();
} }
void PrintersMap::ReplacePrintersInClass(PrinterClass printer_class, void PrintersMap::ReplacePrintersInClass(PrinterClass printer_class,
const std::vector<Printer>& printers) { const std::vector<Printer>& printers) {
// Get set of printer ids that initially existed in |printer_class| so the
// printers that aren't replaced by |printers| have their statuses deleted.
std::set<std::string> statuses_to_remove =
GetPrinterIdsInClass(printer_class);
Clear(printer_class); Clear(printer_class);
for (const auto& printer : printers) { for (const auto& printer : printers) {
// Printer was replaced so remove the id from the set so its status won't be
// deleted.
statuses_to_remove.erase(printer.id());
base::Optional<CupsPrinterStatus> printer_status =
GetPrinterStatus(printer.id());
if (printer_status) {
Insert(printer_class, printer, printer_status.value());
continue;
}
Insert(printer_class, printer); Insert(printer_class, printer);
} }
for (const std::string& printer_id : statuses_to_remove) {
printer_statuses_.erase(printer_id);
}
} }
std::vector<Printer> PrintersMap::GetSecurePrinters() const { std::vector<Printer> PrintersMap::GetSecurePrinters() const {
...@@ -101,8 +128,9 @@ std::vector<Printer> PrintersMap::GetSecurePrinters( ...@@ -101,8 +128,9 @@ std::vector<Printer> PrintersMap::GetSecurePrinters(
result.reserve(printers_.at(printer_class).size()); result.reserve(printers_.at(printer_class).size());
for (const auto& kv : printers_.at(printer_class)) { for (const auto& kv : printers_.at(printer_class)) {
const Printer& printer = kv.second; const Printer& printer = kv.second;
if (printer.HasSecureProtocol()) if (printer.HasSecureProtocol()) {
result.push_back(printer); result.push_back(printer);
}
} }
return result; return result;
...@@ -114,6 +142,7 @@ void PrintersMap::Remove(PrinterClass printer_class, ...@@ -114,6 +142,7 @@ void PrintersMap::Remove(PrinterClass printer_class,
return; return;
} }
printers_[printer_class].erase(printer_id); printers_[printer_class].erase(printer_id);
printer_statuses_.erase(printer_id);
DCHECK(!IsExistingPrinter(printer_id)); DCHECK(!IsExistingPrinter(printer_id));
} }
...@@ -132,4 +161,40 @@ bool PrintersMap::IsExistingPrinter(const std::string& printer_id) const { ...@@ -132,4 +161,40 @@ bool PrintersMap::IsExistingPrinter(const std::string& printer_id) const {
return Get(printer_id).has_value(); return Get(printer_id).has_value();
} }
void PrintersMap::SavePrinterStatus(
const std::string& printer_id,
const CupsPrinterStatus& cups_printer_status) {
printer_statuses_[printer_id] = cups_printer_status;
for (auto& kv : printers_) {
std::unordered_map<std::string, Printer>& printers_map = kv.second;
auto printer_iter = printers_map.find(printer_id);
if (printer_iter != printers_map.end()) {
printer_iter->second.set_printer_status(cups_printer_status);
return;
}
}
}
base::Optional<CupsPrinterStatus> PrintersMap::GetPrinterStatus(
const std::string& printer_id) const {
auto printer_iter = printer_statuses_.find(printer_id);
if (printer_iter != printer_statuses_.end()) {
return printer_iter->second;
}
return base::nullopt;
}
std::set<std::string> PrintersMap::GetPrinterIdsInClass(
PrinterClass printer_class) const {
std::set<std::string> result;
if (HasPrintersInClass(printer_class)) {
for (const auto& kv : printers_.at(printer_class)) {
const Printer& printer = kv.second;
result.insert(printer.id());
}
}
return result;
}
} // namespace chromeos } // namespace chromeos
...@@ -5,12 +5,15 @@ ...@@ -5,12 +5,15 @@
#ifndef CHROME_BROWSER_CHROMEOS_PRINTING_PRINTERS_MAP_H_ #ifndef CHROME_BROWSER_CHROMEOS_PRINTING_PRINTERS_MAP_H_
#define CHROME_BROWSER_CHROMEOS_PRINTING_PRINTERS_MAP_H_ #define CHROME_BROWSER_CHROMEOS_PRINTING_PRINTERS_MAP_H_
#include <set>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include "base/containers/flat_map.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/optional.h" #include "base/optional.h"
#include "chromeos/printing/cups_printer_status.h"
#include "chromeos/printing/printer_configuration.h" #include "chromeos/printing/printer_configuration.h"
namespace chromeos { namespace chromeos {
...@@ -44,10 +47,16 @@ class PrintersMap { ...@@ -44,10 +47,16 @@ class PrintersMap {
// Adds |printer| to |printer_class|. // Adds |printer| to |printer_class|.
void Insert(PrinterClass printer_class, const Printer& printer); void Insert(PrinterClass printer_class, const Printer& printer);
// Adds |printer| with status |cups_printer_status| to |printer_class|.
void Insert(PrinterClass printer_class,
const Printer& printer,
const CupsPrinterStatus& cups_printer_status);
// Removes all printers in |printer_class|. // Removes all printers in |printer_class|.
void Clear(PrinterClass printer_class); void Clear(PrinterClass printer_class);
// Replaces the printers in |printer_class| with |printers|. // Replaces the printers in |printer_class| with |printers|. Adds a status to
// the printer if a status was previously saved in the printer status map.
void ReplacePrintersInClass(PrinterClass printer_class, void ReplacePrintersInClass(PrinterClass printer_class,
const std::vector<Printer>& printers); const std::vector<Printer>& printers);
...@@ -59,6 +68,11 @@ class PrintersMap { ...@@ -59,6 +68,11 @@ class PrintersMap {
bool IsPrinterInClass(PrinterClass printer_class, bool IsPrinterInClass(PrinterClass printer_class,
const std::string& printer_id) const; const std::string& printer_id) const;
// Adds printer status to existing printers in |printers_| map and also saves
// to |printer_statuses_| cache for future printer retrievals.
void SavePrinterStatus(const std::string& printer_id,
const CupsPrinterStatus& cups_printer_status);
private: private:
// Returns true if |printer_class| exists and contains at least 1 printer. // Returns true if |printer_class| exists and contains at least 1 printer.
bool HasPrintersInClass(PrinterClass printer_class) const; bool HasPrintersInClass(PrinterClass printer_class) const;
...@@ -66,11 +80,22 @@ class PrintersMap { ...@@ -66,11 +80,22 @@ class PrintersMap {
// Returns true if |printer_id| exists in any class. Used only for DCHECKs. // Returns true if |printer_id| exists in any class. Used only for DCHECKs.
bool IsExistingPrinter(const std::string& printer_id) const; bool IsExistingPrinter(const std::string& printer_id) const;
base::Optional<CupsPrinterStatus> GetPrinterStatus(
const std::string& printer_id) const;
// Returns set of printer id's for printers in class |printer_class|.
std::set<std::string> GetPrinterIdsInClass(PrinterClass printer_class) const;
// Categorized printers. Outer map keyed on PrinterClass, inner map keyed on // Categorized printers. Outer map keyed on PrinterClass, inner map keyed on
// PrinterId. // PrinterId.
std::unordered_map<PrinterClass, std::unordered_map<std::string, Printer>> std::unordered_map<PrinterClass, std::unordered_map<std::string, Printer>>
printers_; printers_;
// Stores printer statuses returned from performing printer status queries.
// This map is used to persist the printer statuses so when |printers_| map is
// rebuilt, all the statuses aren't lost. Key for this map is a printer id.
base::flat_map<std::string, CupsPrinterStatus> printer_statuses_;
DISALLOW_COPY_AND_ASSIGN(PrintersMap); DISALLOW_COPY_AND_ASSIGN(PrintersMap);
}; };
......
...@@ -21,6 +21,33 @@ bool IsPrinterInPrinters(const std::vector<Printer>& printers, ...@@ -21,6 +21,33 @@ bool IsPrinterInPrinters(const std::vector<Printer>& printers,
return false; return false;
} }
CupsPrinterStatus CreatePrinterStatus(const std::string& printer_id) {
CupsPrinterStatus cups_printer_status(printer_id);
cups_printer_status.AddStatusReason(
CupsPrinterStatus::CupsPrinterStatusReason::Reason::kNoError,
CupsPrinterStatus::CupsPrinterStatusReason::Severity::kReport);
return cups_printer_status;
}
void ExpectPrinterStatusesEqual(const CupsPrinterStatus expected_printer_status,
const CupsPrinterStatus actual_printer_status) {
EXPECT_EQ(expected_printer_status.GetPrinterId(),
actual_printer_status.GetPrinterId());
auto expected_status_reasons = expected_printer_status.GetStatusReasons();
auto actual_status_reasons = actual_printer_status.GetStatusReasons();
EXPECT_EQ(expected_status_reasons.size(), actual_status_reasons.size());
for (const auto& expected_status_reason : expected_status_reasons) {
for (const auto& actual_status_reason : actual_status_reasons) {
EXPECT_EQ(expected_status_reason.GetReason(),
actual_status_reason.GetReason());
EXPECT_EQ(expected_status_reason.GetSeverity(),
actual_status_reason.GetSeverity());
}
}
}
} // namespace } // namespace
class PrintersMapTest : public testing::Test { class PrintersMapTest : public testing::Test {
...@@ -366,4 +393,222 @@ TEST_F(PrintersMapTest, IsPrinterInClass) { ...@@ -366,4 +393,222 @@ TEST_F(PrintersMapTest, IsPrinterInClass) {
printers_map.IsPrinterInClass(PrinterClass::kDiscovered, printer_id)); printers_map.IsPrinterInClass(PrinterClass::kDiscovered, printer_id));
} }
TEST_F(PrintersMapTest, PrinterStatusMapSavePrinterStatus) {
PrintersMap printers_map;
const std::string printer_id = "id";
printers_map.Insert(PrinterClass::kDiscovered, Printer(printer_id));
printers_map.SavePrinterStatus(printer_id, CupsPrinterStatus(printer_id));
base::Optional<Printer> printer = printers_map.Get(printer_id);
CupsPrinterStatus printer_status = printer->printer_status();
EXPECT_EQ(printer_id, printer_status.GetPrinterId());
}
TEST_F(PrintersMapTest, PrinterStatusMapMultipleStatuses) {
PrintersMap printers_map;
const std::string printer_id1 = "id1";
const std::string printer_id2 = "id2";
printers_map.Insert(PrinterClass::kDiscovered, Printer(printer_id1));
printers_map.Insert(PrinterClass::kEnterprise, Printer(printer_id2));
printers_map.SavePrinterStatus(printer_id1, CupsPrinterStatus(printer_id1));
printers_map.SavePrinterStatus(printer_id2, CupsPrinterStatus(printer_id2));
base::Optional<Printer> printer1 = printers_map.Get(printer_id1);
CupsPrinterStatus printer_status1 = printer1->printer_status();
EXPECT_EQ(printer_id1, printer_status1.GetPrinterId());
base::Optional<Printer> printer2 = printers_map.Get(printer_id2);
CupsPrinterStatus printer_status2 = printer2->printer_status();
EXPECT_EQ(printer_id2, printer_status2.GetPrinterId());
}
TEST_F(PrintersMapTest, PrinterStatusMapMissingRequestedPrinter) {
PrintersMap printers_map;
const std::string new_printer_id = "new_printer";
const std::string wrong_printer_id = "wrong_printer";
printers_map.Insert(PrinterClass::kDiscovered, Printer(new_printer_id));
printers_map.Insert(PrinterClass::kDiscovered, Printer(wrong_printer_id));
printers_map.SavePrinterStatus(new_printer_id, CupsPrinterStatus());
base::Optional<Printer> wrong_printer = printers_map.Get(wrong_printer_id);
CupsPrinterStatus printer_status = wrong_printer->printer_status();
EXPECT_TRUE(printer_status.GetPrinterId().empty());
}
TEST_F(PrintersMapTest, PrinterStatusMapEmpty) {
PrintersMap printers_map;
const std::string printer_id = "id";
printers_map.Insert(PrinterClass::kDiscovered, Printer(printer_id));
base::Optional<Printer> printer = printers_map.Get(printer_id);
CupsPrinterStatus printer_status = printer->printer_status();
EXPECT_TRUE(printer_status.GetPrinterId().empty());
}
TEST_F(PrintersMapTest, GetByIdWithStatus) {
PrintersMap printers_map;
const std::string printer_id = "id";
printers_map.Insert(PrinterClass::kDiscovered, Printer(printer_id));
CupsPrinterStatus saved_printer_status = CreatePrinterStatus(printer_id);
printers_map.SavePrinterStatus(printer_id, saved_printer_status);
base::Optional<Printer> printer = printers_map.Get(printer_id);
EXPECT_TRUE(printer);
ExpectPrinterStatusesEqual(saved_printer_status, printer->printer_status());
}
TEST_F(PrintersMapTest, GetByIdAndClassWithStatus) {
PrintersMap printers_map;
const std::string printer_id = "id";
printers_map.Insert(PrinterClass::kDiscovered, Printer(printer_id));
CupsPrinterStatus saved_printer_status = CreatePrinterStatus(printer_id);
printers_map.SavePrinterStatus(printer_id, saved_printer_status);
base::Optional<Printer> printer =
printers_map.Get(PrinterClass::kDiscovered, printer_id);
EXPECT_TRUE(printer);
ExpectPrinterStatusesEqual(saved_printer_status, printer->printer_status());
}
TEST_F(PrintersMapTest, GetByClassWithStatus) {
PrintersMap printers_map;
const std::string printer_id = "id";
printers_map.Insert(PrinterClass::kDiscovered, Printer(printer_id));
CupsPrinterStatus saved_printer_status = CreatePrinterStatus(printer_id);
printers_map.SavePrinterStatus(printer_id, saved_printer_status);
std::vector<Printer> printers = printers_map.Get(PrinterClass::kDiscovered);
EXPECT_EQ(1u, printers.size());
for (auto printer : printers) {
ExpectPrinterStatusesEqual(saved_printer_status, printer.printer_status());
}
}
TEST_F(PrintersMapTest, GetAllPrintersWithStatus) {
PrintersMap printers_map;
const std::string printer_id = "id";
printers_map.Insert(PrinterClass::kDiscovered, Printer(printer_id));
CupsPrinterStatus saved_printer_status = CreatePrinterStatus(printer_id);
printers_map.SavePrinterStatus(printer_id, saved_printer_status);
std::vector<Printer> printers = printers_map.Get();
EXPECT_EQ(1u, printers.size());
for (auto printer : printers) {
ExpectPrinterStatusesEqual(saved_printer_status, printer.printer_status());
}
}
TEST_F(PrintersMapTest, GetSecurePrintersWithStatus) {
PrintersMap printers_map;
const std::string printer_id = "id";
Printer ipps_printer = Printer(printer_id);
ipps_printer.set_uri("ipps:printer");
printers_map.Insert(PrinterClass::kDiscovered, ipps_printer);
CupsPrinterStatus saved_printer_status = CreatePrinterStatus(printer_id);
printers_map.SavePrinterStatus(printer_id, saved_printer_status);
std::vector<Printer> printers =
printers_map.GetSecurePrinters(PrinterClass::kDiscovered);
EXPECT_EQ(1u, printers.size());
for (auto printer : printers) {
ExpectPrinterStatusesEqual(saved_printer_status, printer.printer_status());
}
}
TEST_F(PrintersMapTest, ReplacePrintersInClassAddsStatus) {
PrintersMap printers_map;
const std::string printer_id1 = "id1";
const std::string printer_id2 = "id2";
std::vector<Printer> printers{Printer(printer_id1), Printer(printer_id2)};
CupsPrinterStatus saved_printer_status1 = CreatePrinterStatus(printer_id1);
CupsPrinterStatus saved_printer_status2 = CreatePrinterStatus(printer_id2);
printers_map.SavePrinterStatus(printer_id1, saved_printer_status1);
printers_map.SavePrinterStatus(printer_id2, saved_printer_status2);
printers_map.ReplacePrintersInClass(PrinterClass::kDiscovered, printers);
base::Optional<Printer> printer1 = printers_map.Get(printer_id1);
ExpectPrinterStatusesEqual(saved_printer_status1, printer1->printer_status());
base::Optional<Printer> printer2 = printers_map.Get(printer_id2);
ExpectPrinterStatusesEqual(saved_printer_status2, printer2->printer_status());
}
TEST_F(PrintersMapTest, ReplacePrintersInClassDeletesAllStatuses) {
PrintersMap printers_map;
const std::string printer_id1 = "id1";
const std::string printer_id2 = "id2";
printers_map.Insert(PrinterClass::kDiscovered, Printer(printer_id1));
printers_map.Insert(PrinterClass::kDiscovered, Printer(printer_id2));
CupsPrinterStatus saved_printer_status1 = CreatePrinterStatus(printer_id1);
CupsPrinterStatus saved_printer_status2 = CreatePrinterStatus(printer_id2);
printers_map.SavePrinterStatus(printer_id1, saved_printer_status1);
printers_map.SavePrinterStatus(printer_id2, saved_printer_status2);
// Only printer1 is part of printers vector so status for printer2 should be
// deleted.
std::vector<Printer> printer1_list{Printer(printer_id1)};
printers_map.ReplacePrintersInClass(PrinterClass::kDiscovered, printer1_list);
base::Optional<Printer> printer1 = printers_map.Get(printer_id1);
ExpectPrinterStatusesEqual(saved_printer_status1, printer1->printer_status());
// Add printer2 back to the map so it can be fetched then confirm no status
// was leftover from the replace.
std::vector<Printer> printer2_list{Printer(printer_id2)};
printers_map.ReplacePrintersInClass(PrinterClass::kDiscovered, printer2_list);
base::Optional<Printer> printer2 = printers_map.Get(printer_id2);
CupsPrinterStatus printer_status2 = printer2->printer_status();
EXPECT_TRUE(printer_status2.GetPrinterId().empty());
}
TEST_F(PrintersMapTest, ReplacePrintersOnlyDeletesStatusInSameClass) {
PrintersMap printers_map;
const std::string printer_id1 = "id1";
const std::string printer_id2 = "id2";
printers_map.Insert(PrinterClass::kDiscovered, Printer(printer_id1));
printers_map.Insert(PrinterClass::kEnterprise, Printer(printer_id2));
CupsPrinterStatus saved_printer_status1 = CreatePrinterStatus(printer_id1);
CupsPrinterStatus saved_printer_status2 = CreatePrinterStatus(printer_id2);
printers_map.SavePrinterStatus(printer_id1, saved_printer_status1);
printers_map.SavePrinterStatus(printer_id2, saved_printer_status2);
std::vector<Printer> printer1_list{Printer(printer_id1)};
printers_map.ReplacePrintersInClass(PrinterClass::kDiscovered, printer1_list);
base::Optional<Printer> printer1 = printers_map.Get(printer_id1);
ExpectPrinterStatusesEqual(saved_printer_status1, printer1->printer_status());
base::Optional<Printer> printer2 = printers_map.Get(printer_id2);
CupsPrinterStatus printer_status2 = printer2->printer_status();
ExpectPrinterStatusesEqual(saved_printer_status2, printer2->printer_status());
}
TEST_F(PrintersMapTest, RemovePrinterRemovesStatus) {
PrintersMap printers_map;
const std::string printer_id = "id";
printers_map.Insert(PrinterClass::kDiscovered, Printer(printer_id));
// Confirm the printer status is attached to the printer
CupsPrinterStatus saved_printer_status = CreatePrinterStatus(printer_id);
printers_map.SavePrinterStatus(printer_id, saved_printer_status);
base::Optional<Printer> saved_printer = printers_map.Get(printer_id);
CupsPrinterStatus printer_status = saved_printer->printer_status();
EXPECT_EQ(printer_id, printer_status.GetPrinterId());
// Remove then resinsert the printer, retrieve that printer and confirm that
// the associated printer status was deleted.
printers_map.Remove(PrinterClass::kDiscovered, printer_id);
std::vector<Printer> printers{Printer(printer_id)};
printers_map.ReplacePrintersInClass(PrinterClass::kDiscovered, printers);
base::Optional<Printer> printer = printers_map.Get(printer_id);
CupsPrinterStatus empty_printer_status = printer->printer_status();
EXPECT_TRUE(empty_printer_status.GetPrinterId().empty());
}
} // namespace chromeos } // namespace chromeos
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/optional.h" #include "base/optional.h"
#include "chromeos/chromeos_export.h" #include "chromeos/chromeos_export.h"
#include "chromeos/printing/cups_printer_status.h"
#include "net/base/host_port_pair.h" #include "net/base/host_port_pair.h"
namespace net { namespace net {
...@@ -186,6 +187,11 @@ class CHROMEOS_EXPORT Printer { ...@@ -186,6 +187,11 @@ class CHROMEOS_EXPORT Printer {
// successfully parsed. // successfully parsed.
base::Optional<UriComponents> GetUriComponents() const; base::Optional<UriComponents> GetUriComponents() const;
const CupsPrinterStatus& printer_status() const { return printer_status_; }
void set_printer_status(const chromeos::CupsPrinterStatus& printer_status) {
printer_status_ = printer_status;
}
private: private:
// Globally unique identifier. Empty indicates a new printer. // Globally unique identifier. Empty indicates a new printer.
std::string id_; std::string id_;
...@@ -237,6 +243,9 @@ class CHROMEOS_EXPORT Printer { ...@@ -237,6 +243,9 @@ class CHROMEOS_EXPORT Printer {
// The datastore which holds this printer. // The datastore which holds this printer.
Source source_; Source source_;
// The current status of the printer
chromeos::CupsPrinterStatus printer_status_;
}; };
} // namespace chromeos } // namespace chromeos
......
...@@ -6,10 +6,12 @@ ...@@ -6,10 +6,12 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <utility>
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "base/values.h" #include "base/values.h"
#include "chromeos/printing/cups_printer_status.h"
#include "chromeos/printing/printer_configuration.h" #include "chromeos/printing/printer_configuration.h"
#include "chromeos/printing/uri_components.h" #include "chromeos/printing/uri_components.h"
...@@ -229,4 +231,27 @@ std::unique_ptr<base::DictionaryValue> GetCupsPrinterInfo( ...@@ -229,4 +231,27 @@ std::unique_ptr<base::DictionaryValue> GetCupsPrinterInfo(
return printer_info; return printer_info;
} }
base::Value CreateCupsPrinterStatusDictionary(
const CupsPrinterStatus& cups_printer_status) {
base::Value printer_status(base::Value::Type::DICTIONARY);
printer_status.SetKey("printerId",
base::Value(cups_printer_status.GetPrinterId()));
printer_status.SetKey(
"timestamp",
base::Value(cups_printer_status.GetTimestamp().ToJsTimeIgnoringNull()));
base::Value status_reasons(base::Value::Type::LIST);
for (auto reason : cups_printer_status.GetStatusReasons()) {
base::Value status_reason(base::Value::Type::DICTIONARY);
status_reason.SetKey("reason",
base::Value(static_cast<int>(reason.GetReason())));
status_reason.SetKey("severity",
base::Value(static_cast<int>(reason.GetSeverity())));
status_reasons.Append(std::move(status_reason));
}
printer_status.SetKey("status_reasons", std::move(status_reasons));
return printer_status;
}
} // namespace chromeos } // namespace chromeos
...@@ -12,10 +12,13 @@ ...@@ -12,10 +12,13 @@
namespace base { namespace base {
class DictionaryValue; class DictionaryValue;
class Value;
} }
namespace chromeos { namespace chromeos {
class CupsPrinterStatus;
CHROMEOS_EXPORT extern const char kPrinterId[]; CHROMEOS_EXPORT extern const char kPrinterId[];
// Returns a new printer populated with the fields from |pref|. Processes // Returns a new printer populated with the fields from |pref|. Processes
...@@ -29,6 +32,9 @@ CHROMEOS_EXPORT std::unique_ptr<Printer> RecommendedPrinterToPrinter( ...@@ -29,6 +32,9 @@ CHROMEOS_EXPORT std::unique_ptr<Printer> RecommendedPrinterToPrinter(
CHROMEOS_EXPORT std::unique_ptr<base::DictionaryValue> GetCupsPrinterInfo( CHROMEOS_EXPORT std::unique_ptr<base::DictionaryValue> GetCupsPrinterInfo(
const Printer& printer); const Printer& printer);
// Returns a JSON representation of a CupsPrinterStatus
CHROMEOS_EXPORT base::Value CreateCupsPrinterStatusDictionary(
const CupsPrinterStatus& cups_printer_status);
} // namespace chromeos } // namespace chromeos
#endif // CHROMEOS_PRINTING_PRINTER_TRANSLATOR_H_ #endif // CHROMEOS_PRINTING_PRINTER_TRANSLATOR_H_
...@@ -2,19 +2,23 @@ ...@@ -2,19 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include <utility> #include "chromeos/printing/printer_translator.h"
#include <string>
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "base/test/values_test_util.h" #include "base/test/values_test_util.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "base/values.h" #include "base/values.h"
#include "chromeos/printing/cups_printer_status.h"
#include "chromeos/printing/printer_configuration.h" #include "chromeos/printing/printer_configuration.h"
#include "chromeos/printing/printer_translator.h"
#include "testing/gmock/include/gmock/gmock-matchers.h" #include "testing/gmock/include/gmock/gmock-matchers.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
namespace chromeos { namespace chromeos {
using CupsPrinterStatusReason = CupsPrinterStatus::CupsPrinterStatusReason;
namespace { namespace {
// Printer test data // Printer test data
...@@ -317,4 +321,61 @@ TEST(PrinterTranslatorTest, GetCupsPrinterInfoAutoconfPrinter) { ...@@ -317,4 +321,61 @@ TEST(PrinterTranslatorTest, GetCupsPrinterInfoAutoconfPrinter) {
ExpectDictBooleanValue(true, *printer_info, "printerPpdReference.autoconf"); ExpectDictBooleanValue(true, *printer_info, "printerPpdReference.autoconf");
} }
TEST(PrinterTranslatorTest, GetCupsPrinterStatusOneReason) {
CupsPrinterStatus cups_printer_status("id");
cups_printer_status.AddStatusReason(
CupsPrinterStatusReason::Reason::kDoorOpen,
CupsPrinterStatusReason::Severity::kError);
base::Value printer_status_dict =
CreateCupsPrinterStatusDictionary(cups_printer_status);
EXPECT_EQ("id", *printer_status_dict.FindStringPath("printerId"));
EXPECT_EQ(cups_printer_status.GetTimestamp().ToJsTimeIgnoringNull(),
*printer_status_dict.FindDoublePath("timestamp"));
const base::Value* status_reasons =
printer_status_dict.FindListPath("status_reasons");
EXPECT_EQ(1u, status_reasons->GetList().size());
for (const base::Value& status_reason : status_reasons->GetList()) {
EXPECT_EQ(static_cast<int>(CupsPrinterStatusReason::Reason::kDoorOpen),
*status_reason.FindIntPath("reason"));
EXPECT_EQ(static_cast<int>(CupsPrinterStatusReason::Severity::kError),
*status_reason.FindIntPath("severity"));
}
}
TEST(PrinterTranslatorTest, GetCupsPrinterStatusTwoReasons) {
CupsPrinterStatus cups_printer_status("id");
cups_printer_status.AddStatusReason(
CupsPrinterStatusReason::Reason::kLowOnPaper,
CupsPrinterStatusReason::Severity::kWarning);
cups_printer_status.AddStatusReason(
CupsPrinterStatusReason::Reason::kPaperJam,
CupsPrinterStatusReason::Severity::kError);
base::Value printer_status_dict =
CreateCupsPrinterStatusDictionary(cups_printer_status);
EXPECT_EQ("id", *printer_status_dict.FindStringPath("printerId"));
EXPECT_EQ(cups_printer_status.GetTimestamp().ToJsTimeIgnoringNull(),
*printer_status_dict.FindDoublePath("timestamp"));
const base::Value* status_reasons =
printer_status_dict.FindListPath("status_reasons");
auto status_reasons_list = status_reasons->GetList();
EXPECT_EQ(2u, status_reasons_list.size());
EXPECT_EQ(static_cast<int>(CupsPrinterStatusReason::Reason::kLowOnPaper),
status_reasons_list[0].FindIntPath("reason"));
EXPECT_EQ(static_cast<int>(CupsPrinterStatusReason::Severity::kWarning),
status_reasons_list[0].FindIntPath("severity"));
EXPECT_EQ(static_cast<int>(CupsPrinterStatusReason::Reason::kPaperJam),
status_reasons_list[1].FindIntPath("reason"));
EXPECT_EQ(static_cast<int>(CupsPrinterStatusReason::Severity::kError),
status_reasons_list[1].FindIntPath("severity"));
}
} // namespace chromeos } // namespace chromeos
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment