| // Copyright 2017 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/sync/test/integration/printers_helper.h" |
| |
| #include <algorithm> |
| #include <ostream> |
| #include <string> |
| #include <unordered_map> |
| #include <utility> |
| #include <vector> |
| |
| #include "base/functional/bind.h" |
| #include "base/strings/stringprintf.h" |
| #include "chrome/browser/ash/printing/synced_printers_manager.h" |
| #include "chrome/browser/ash/printing/synced_printers_manager_factory.h" |
| #include "chrome/browser/sync/test/integration/sync_datatype_helper.h" |
| #include "chrome/browser/sync/test/integration/sync_test.h" |
| #include "content/public/test/test_utils.h" |
| |
| using sync_datatype_helper::test; |
| |
| namespace printers_helper { |
| |
| namespace { |
| |
| using PrinterList = std::vector<chromeos::Printer>; |
| |
| // Returns true if Printer#id, Printer#description, and Printer#uri all match. |
| bool PrintersAreMostlyEqual(const chromeos::Printer& left, |
| const chromeos::Printer& right) { |
| return left.id() == right.id() && left.description() == right.description() && |
| left.uri() == right.uri(); |
| } |
| |
| // Returns true if both lists have the same elements irrespective of order. |
| bool ListsContainTheSamePrinters(const PrinterList& list_a, |
| const PrinterList& list_b) { |
| std::unordered_multimap<std::string, const chromeos::Printer*> map_b; |
| for (const chromeos::Printer& b : list_b) { |
| map_b.insert({b.id(), &b}); |
| } |
| |
| for (const chromeos::Printer& a : list_a) { |
| auto [begin, end] = map_b.equal_range(a.id()); |
| |
| auto it = std::find_if( |
| begin, end, |
| [&a](const std::pair<std::string, const chromeos::Printer*>& entry) { |
| return PrintersAreMostlyEqual(a, *(entry.second)); |
| }); |
| |
| if (it == end) { |
| // Element in a does not match an element in b. Lists do not contain the |
| // same elements. |
| return false; |
| } |
| |
| map_b.erase(it); |
| } |
| |
| return map_b.empty(); |
| } |
| |
| std::string PrinterId(int index) { |
| return base::StringPrintf("printer%d", index); |
| } |
| |
| ash::SyncedPrintersManager* GetPrinterStore(content::BrowserContext* context) { |
| return ash::SyncedPrintersManagerFactory::GetForBrowserContext(context); |
| } |
| |
| } // namespace |
| |
| void AddPrinter(ash::SyncedPrintersManager* manager, |
| const chromeos::Printer& printer) { |
| manager->UpdateSavedPrinter(printer); |
| } |
| |
| void RemovePrinter(ash::SyncedPrintersManager* manager, int index) { |
| chromeos::Printer testPrinter(CreateTestPrinter(index)); |
| manager->RemoveSavedPrinter(testPrinter.id()); |
| } |
| |
| bool EditPrinterDescription(ash::SyncedPrintersManager* manager, |
| int index, |
| const std::string& description) { |
| PrinterList printers = manager->GetSavedPrinters(); |
| std::string printer_id = PrinterId(index); |
| auto found = std::ranges::find(printers, printer_id, &chromeos::Printer::id); |
| |
| if (found == printers.end()) { |
| return false; |
| } |
| |
| found->set_description(description); |
| manager->UpdateSavedPrinter(*found); |
| |
| return true; |
| } |
| |
| chromeos::Printer CreateTestPrinter(int index) { |
| chromeos::Printer printer(PrinterId(index)); |
| printer.set_description("Description"); |
| printer.SetUri(base::StringPrintf("ipp://192.168.1.%d", index)); |
| |
| return printer; |
| } |
| |
| std::unique_ptr<sync_pb::PrinterSpecifics> CreateTestPrinterSpecifics( |
| int index) { |
| auto specifics = std::make_unique<sync_pb::PrinterSpecifics>(); |
| specifics->set_id(PrinterId(index)); |
| specifics->set_description("Description"); |
| specifics->set_uri(base::StringPrintf("ipp://192.168.1.%d", index)); |
| |
| return specifics; |
| } |
| |
| void WaitForPrinterStoreToLoad(content::BrowserContext* context) { |
| GetPrinterStore(context); |
| // Run tasks to allow a DataTypeStore to be associated with the |
| // SyncedPrinterManager. |
| // |
| // TODO(sync): Remove this forced initialization once there is a mechanism |
| // to queue writes/reads before the DataTypeStore is associated with the |
| // SyncedPrinterManager. https://crbug.com/709094. |
| content::RunAllTasksUntilIdle(); |
| } |
| |
| ash::SyncedPrintersManager* GetVerifierPrinterStore() { |
| ash::SyncedPrintersManager* manager = |
| GetPrinterStore(sync_datatype_helper::test()->verifier()); |
| |
| return manager; |
| } |
| |
| ash::SyncedPrintersManager* GetPrinterStore(int index) { |
| ash::SyncedPrintersManager* manager = |
| GetPrinterStore(sync_datatype_helper::test()->GetProfile(index)); |
| |
| return manager; |
| } |
| |
| int GetVerifierPrinterCount() { |
| return GetVerifierPrinterStore()->GetSavedPrinters().size(); |
| } |
| |
| int GetPrinterCount(int index) { |
| return GetPrinterStore(index)->GetSavedPrinters().size(); |
| } |
| |
| bool AllProfilesContainSamePrinters(std::ostream* os) { |
| std::vector<chromeos::Printer> reference_printers = |
| GetPrinterStore(0)->GetSavedPrinters(); |
| for (int i = 1; i < test()->num_clients(); ++i) { |
| std::vector<chromeos::Printer> printers = |
| GetPrinterStore(i)->GetSavedPrinters(); |
| if (!ListsContainTheSamePrinters(reference_printers, printers)) { |
| if (os) { |
| *os << "Printers in client [" << i << "] don't match client 0"; |
| } |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| bool ProfileContainsSamePrintersAsVerifier(int index) { |
| return ListsContainTheSamePrinters( |
| GetVerifierPrinterStore()->GetSavedPrinters(), |
| GetPrinterStore(index)->GetSavedPrinters()); |
| } |
| |
| PrintersMatchChecker::PrintersMatchChecker() |
| : AwaitMatchStatusChangeChecker(base::BindRepeating( |
| &printers_helper::AllProfilesContainSamePrinters)) {} |
| |
| PrintersMatchChecker::~PrintersMatchChecker() = default; |
| |
| } // namespace printers_helper |