| // Copyright 2020 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/ash/printing/enterprise/enterprise_printers_provider.h" |
| |
| #include <algorithm> |
| #include <memory> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include "base/containers/to_vector.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/run_loop.h" |
| #include "base/scoped_observation.h" |
| #include "base/values.h" |
| #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h" |
| #include "chrome/browser/ash/printing/enterprise/bulk_printers_calculator.h" |
| #include "chrome/browser/ash/printing/enterprise/bulk_printers_calculator_factory.h" |
| #include "chrome/browser/ash/profiles/profile_helper.h" |
| #include "chrome/common/pref_names.h" |
| #include "chrome/test/base/testing_profile.h" |
| #include "chromeos/ash/components/settings/cros_settings.h" |
| #include "chromeos/ash/components/settings/cros_settings_names.h" |
| #include "chromeos/printing/printer_configuration.h" |
| #include "components/sync_preferences/testing_pref_service_syncable.h" |
| #include "components/user_manager/scoped_user_manager.h" |
| #include "content/public/test/browser_task_environment.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace ash { |
| |
| namespace { |
| |
| using ::chromeos::Printer; |
| using ::testing::UnorderedElementsAre; |
| |
| std::vector<std::string> GetPrinterIds(const std::vector<Printer>& printers) { |
| return base::ToVector(printers, &Printer::id); |
| } |
| |
| base::Value::List StringsToValueList(const std::vector<std::string>& strings) { |
| base::Value::List list; |
| list.reserve(strings.size()); |
| for (const std::string& s : strings) { |
| list.Append(s); |
| } |
| return list; |
| } |
| |
| constexpr char kFirstId[] = "First"; |
| constexpr char kSecondId[] = "Second"; |
| constexpr char kThirdId[] = "Third"; |
| |
| constexpr char kRecommendedPrinter[] = R"json( |
| { |
| "id": "First", |
| "display_name": "LexaPrint", |
| "description": "Laser on the test shelf", |
| "manufacturer": "LexaPrint, Inc.", |
| "model": "MS610de", |
| "uri": "ipp://192.168.1.5", |
| "ppd_resource": { |
| "effective_model": "MS610de" |
| } |
| } |
| )json"; |
| |
| // Bulk printer configuration file. |
| constexpr char kBulkPolicyContents[] = R"json( |
| [ |
| { |
| "guid": "First", |
| "display_name": "LexaPrint", |
| "description": "Laser on the test shelf", |
| "uri": "ipp://192.168.1.5", |
| "ppd_resource": { |
| "effective_model": "MS610de" |
| } |
| }, { |
| "guid": "Incorrect uri", |
| "display_name": "aaa", |
| "description": "bbbb", |
| "uri":"ipp://:", |
| "ppd_resource":{ |
| "effective_model": "fff" |
| } |
| }, { |
| "guid": "Second", |
| "display_name": "Color Laser", |
| "description": "The printer next to the water cooler.", |
| "uri":"ipps://print-server.intranet.example.com:443/ipp/cl2k4", |
| "ppd_resource":{ |
| "effective_model": "ColorLaser2k4" |
| } |
| }, { |
| "guid": "Third", |
| "display_name": "YaLP", |
| "description": "Fancy Fancy Fancy", |
| "uri": "ipp://192.168.1.8", |
| "ppd_resource": { |
| "effective_model": "MS610de" |
| } |
| } |
| ])json"; |
| |
| // Helper class to record observed events. |
| class LoggingObserver : public EnterprisePrintersProvider::Observer { |
| public: |
| explicit LoggingObserver(EnterprisePrintersProvider* source) { |
| observation_.Observe(source); |
| } |
| |
| void OnPrintersChanged(bool complete, |
| const std::vector<Printer>& printers) override { |
| complete_ = complete; |
| printers_ = printers; |
| } |
| |
| const std::vector<Printer>& printers() const { return printers_; } |
| |
| private: |
| bool complete_ = false; |
| std::vector<Printer> printers_; |
| base::ScopedObservation<EnterprisePrintersProvider, |
| EnterprisePrintersProvider::Observer> |
| observation_{this}; |
| }; |
| |
| class EnterprisePrintersProviderTest : public testing::Test { |
| protected: |
| EnterprisePrintersProviderTest() { |
| const AccountId kUserAccountId = |
| AccountId::FromUserEmail(TestingProfile::kDefaultProfileUserName); |
| fake_user_manager_->AddUser(kUserAccountId); |
| fake_user_manager_->SwitchActiveUser(kUserAccountId); |
| } |
| |
| void SetUp() override { |
| device_printers_calculator_ = bulk_factory.GetForDevice(); |
| ASSERT_TRUE(device_printers_calculator_); |
| user_printers_calculator_ = bulk_factory.GetForAccountId( |
| AccountId::FromUserEmail(TestingProfile::kDefaultProfileUserName)); |
| ASSERT_TRUE(user_printers_calculator_); |
| |
| prefs_ = profile_.GetTestingPrefService(); |
| cros_settings_ = profile_.ScopedCrosSettingsTestHelper(); |
| cros_settings_->ReplaceDeviceSettingsProviderWithStub(); |
| |
| // Explicitly set empty allowlist to disable all printers. Individual test |
| // cases will override this. |
| prefs_->SetManagedPref(prefs::kRecommendedPrintersAllowlist, |
| base::Value::List()); |
| cros_settings_->Set(kDevicePrintersAllowlist, base::Value()); |
| |
| prefs_->SetManagedPref( |
| prefs::kRecommendedPrintersAccessMode, |
| base::Value(BulkPrintersCalculator::AccessMode::ALLOWLIST_ONLY)); |
| cros_settings_->Set( |
| kDevicePrintersAccessMode, |
| base::Value(BulkPrintersCalculator::AccessMode::ALLOWLIST_ONLY)); |
| |
| device_printers_calculator_->SetData( |
| std::make_unique<std::string>(kBulkPolicyContents)); |
| user_printers_calculator_->SetData( |
| std::make_unique<std::string>(kBulkPolicyContents)); |
| |
| provider_ = |
| EnterprisePrintersProvider::Create(CrosSettings::Get(), &profile_); |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| void SetRecommendedPrinters(const std::vector<std::string>& printer_jsons) { |
| prefs_->SetManagedPref(prefs::kRecommendedPrinters, |
| StringsToValueList(printer_jsons)); |
| task_environment_.RunUntilIdle(); |
| } |
| |
| void SetDevicePolicyPrinters( |
| const std::vector<std::string>& allowed_printer_ids) { |
| profile_.ScopedCrosSettingsTestHelper()->Set( |
| kDevicePrintersAllowlist, |
| base::Value(StringsToValueList(allowed_printer_ids))); |
| task_environment_.RunUntilIdle(); |
| } |
| |
| void SetUserPolicyPrinters( |
| const std::vector<std::string>& allowed_printer_ids) { |
| prefs_->SetManagedPref(prefs::kRecommendedPrintersAllowlist, |
| StringsToValueList(allowed_printer_ids)); |
| |
| task_environment_.RunUntilIdle(); |
| } |
| |
| // Must outlive |profile_|. |
| content::BrowserTaskEnvironment task_environment_; |
| |
| TestingProfile profile_; |
| |
| raw_ptr<ash::ScopedCrosSettingsTestHelper> cros_settings_; |
| |
| raw_ptr<sync_preferences::TestingPrefServiceSyncable> prefs_; |
| |
| // Must outlive |provider_|. |
| user_manager::TypedScopedUserManager<ash::FakeChromeUserManager> |
| fake_user_manager_{std::make_unique<ash::FakeChromeUserManager>()}; |
| |
| BulkPrintersCalculatorFactory bulk_factory; |
| base::WeakPtr<BulkPrintersCalculator> user_printers_calculator_; |
| base::WeakPtr<BulkPrintersCalculator> device_printers_calculator_; |
| std::unique_ptr<EnterprisePrintersProvider> provider_; |
| }; |
| |
| TEST_F(EnterprisePrintersProviderTest, SingleUserPrinter) { |
| LoggingObserver observer(provider_.get()); |
| SetUserPolicyPrinters({kFirstId}); |
| EXPECT_THAT(GetPrinterIds(observer.printers()), |
| UnorderedElementsAre(kFirstId)); |
| } |
| |
| TEST_F(EnterprisePrintersProviderTest, SingleDevicePrinter) { |
| LoggingObserver observer(provider_.get()); |
| SetDevicePolicyPrinters({kThirdId}); |
| EXPECT_THAT(GetPrinterIds(observer.printers()), |
| UnorderedElementsAre(kThirdId)); |
| } |
| |
| TEST_F(EnterprisePrintersProviderTest, RecommendedPrinters) { |
| LoggingObserver observer(provider_.get()); |
| SetRecommendedPrinters({kRecommendedPrinter}); |
| |
| ASSERT_EQ(1u, observer.printers().size()); |
| // Printer IDs are generated for recommended printers, so we check the display |
| // name in this test. |
| EXPECT_EQ("LexaPrint", observer.printers().front().display_name()); |
| } |
| |
| TEST_F(EnterprisePrintersProviderTest, MultiplePrinters) { |
| LoggingObserver observer(provider_.get()); |
| SetDevicePolicyPrinters({kFirstId, kSecondId}); |
| EXPECT_THAT(GetPrinterIds(observer.printers()), |
| UnorderedElementsAre(kFirstId, kSecondId)); |
| } |
| |
| TEST_F(EnterprisePrintersProviderTest, ChangingEnterprisePrinter) { |
| LoggingObserver observer(provider_.get()); |
| SetUserPolicyPrinters({kFirstId}); |
| EXPECT_THAT(GetPrinterIds(observer.printers()), |
| UnorderedElementsAre(kFirstId)); |
| |
| SetUserPolicyPrinters({kSecondId}); |
| EXPECT_THAT(GetPrinterIds(observer.printers()), |
| UnorderedElementsAre(kSecondId)); |
| } |
| |
| TEST_F(EnterprisePrintersProviderTest, PrintersMergedWithNoDuplicates) { |
| LoggingObserver observer(provider_.get()); |
| SetUserPolicyPrinters({kFirstId, kSecondId}); |
| SetDevicePolicyPrinters({kSecondId, kThirdId}); |
| EXPECT_THAT(GetPrinterIds(observer.printers()), |
| UnorderedElementsAre(kFirstId, kSecondId, kThirdId)); |
| } |
| |
| TEST_F(EnterprisePrintersProviderTest, PrinterSourceIsPolicy) { |
| LoggingObserver observer(provider_.get()); |
| SetDevicePolicyPrinters({kFirstId}); |
| SetUserPolicyPrinters({kSecondId}); |
| |
| std::vector<Printer> printers = observer.printers(); |
| ASSERT_EQ(2u, printers.size()); |
| EXPECT_THAT(printers[0].source(), Printer::SRC_POLICY); |
| EXPECT_THAT(printers[1].source(), Printer::SRC_POLICY); |
| } |
| |
| } // namespace |
| } // namespace ash |