1 // Copyright 2019 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 
5 #include "chrome/browser/chromeos/printing/calculators_policies_binder.h"
6 
7 #include <array>
8 #include <string>
9 
10 #include "base/test/task_environment.h"
11 #include "chrome/browser/chromeos/printing/bulk_printers_calculator.h"
12 #include "chrome/browser/chromeos/settings/cros_settings.h"
13 #include "chrome/browser/chromeos/settings/scoped_testing_cros_settings.h"
14 #include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
15 #include "chrome/common/pref_names.h"
16 #include "components/prefs/testing_pref_service.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 
19 namespace chromeos {
20 
21 namespace {
22 
23 constexpr size_t kNumPrinters = 5;
24 
25 constexpr size_t kAllowlistPrinters = 4;
26 constexpr std::array<const char*, kAllowlistPrinters> kAllowlistIds = {
27     "First", "Second", "Third", "Fifth"};
28 
29 constexpr std::array<const char*, 3> kBlocklistIds = {"Second", "Third",
30                                                       "Fourth"};
31 // kNumPrinters - kBlocklistIds.size() = kBlocklistPrinters (2)
32 constexpr size_t kBlocklistPrinters = 2;
33 
34 constexpr char kBulkPolicyContentsJson[] = R"json(
35 [
36   {
37     "id": "First",
38     "display_name": "LexaPrint",
39     "description": "Laser on the test shelf",
40     "manufacturer": "LexaPrint, Inc.",
41     "model": "MS610de",
42     "uri": "ipp://192.168.1.5",
43     "ppd_resource": {
44       "effective_model": "MS610de"
45     }
46   }, {
47     "id": "Second",
48     "display_name": "Color Laser",
49     "description": "The printer next to the water cooler.",
50     "manufacturer": "Printer Manufacturer",
51     "model":"Color Laser 2004",
52     "uri":"ipps://print-server.intranet.example.com:443/ipp/cl2k4",
53     "uuid":"1c395fdb-5d93-4904-b246-b2c046e79d12",
54     "ppd_resource":{
55       "effective_manufacturer": "MakesPrinters",
56       "effective_model": "ColorLaser2k4"
57     }
58   }, {
59     "id": "Third",
60     "display_name": "YaLP",
61     "description": "Fancy Fancy Fancy",
62     "manufacturer": "LexaPrint, Inc.",
63     "model": "MS610de",
64     "uri": "ipp://192.168.1.8",
65     "ppd_resource": {
66       "effective_manufacturer": "LexaPrint",
67       "effective_model": "MS610de"
68     }
69   }, {
70     "id": "Fourth",
71     "display_name": "Yon",
72     "description": "Another printer",
73     "manufacturer": "CrosPrints",
74     "model": "1000d7",
75     "uri": "ipp://192.168.1.9",
76     "ppd_resource": {
77       "effective_manufacturer": "Printer",
78       "effective_model": "Model"
79     }
80   }, {
81     "id": "Fifth",
82     "display_name": "ABCDE",
83     "description": "Yep yep yep",
84     "manufacturer": "Ink and toner",
85     "model": "34343434l",
86     "uri": "ipp://192.168.1.10",
87     "ppd_resource": {
88       "effective_manufacturer": "Blah",
89       "effective_model": "Blah blah Blah"
90     }
91   }
92 ])json";
93 
94 template <class Container>
StringsToList(Container container)95 std::unique_ptr<base::Value> StringsToList(Container container) {
96   auto first = container.begin();
97   auto last = container.end();
98   auto list = std::make_unique<base::Value>(base::Value::Type::LIST);
99 
100   while (first != last) {
101     list->Append(*first);
102     first++;
103   }
104   return list;
105 }
106 
107 class CalculatorsPoliciesBinderTest : public testing::Test {
108  protected:
109   void SetUp() override {
110     CalculatorsPoliciesBinder::RegisterProfilePrefs(prefs_.registry());
111   }
112 
113   std::unique_ptr<BulkPrintersCalculator> UserCalculator() {
114     auto calculator = BulkPrintersCalculator::Create();
115     binder_ =
116         CalculatorsPoliciesBinder::UserBinder(&prefs_, calculator->AsWeakPtr());
117 
118     // Populate data
119     calculator->SetData(std::make_unique<std::string>(kBulkPolicyContentsJson));
120     return calculator;
121   }
122 
123   std::unique_ptr<BulkPrintersCalculator> DeviceCalculator() {
124     auto calculator = BulkPrintersCalculator::Create();
125     binder_ = CalculatorsPoliciesBinder::DeviceBinder(CrosSettings::Get(),
126                                                       calculator->AsWeakPtr());
127 
128     // Populate data
129     calculator->SetData(std::make_unique<std::string>(kBulkPolicyContentsJson));
130     return calculator;
131   }
132 
133   void SetDeviceSetting(const std::string& path, const base::Value& value) {
134     testing_settings_.device_settings()->Set(path, value);
135   }
136 
137   base::test::TaskEnvironment env_;
138   ScopedTestingCrosSettings testing_settings_;
139   TestingPrefServiceSimple prefs_;
140 
141   // Class under test.  Expected to be destroyed first.
142   std::unique_ptr<CalculatorsPoliciesBinder> binder_;
143 };
144 
145 TEST_F(CalculatorsPoliciesBinderTest, PrefsAllAccess) {
146   auto calculator = UserCalculator();
147 
148   // Set prefs to complete computation
149   prefs_.SetManagedPref(prefs::kRecommendedPrintersAccessMode,
150                         std::make_unique<base::Value>(
151                             BulkPrintersCalculator::AccessMode::ALL_ACCESS));
152 
153   env_.RunUntilIdle();
154   EXPECT_TRUE(calculator->IsComplete());
155   EXPECT_EQ(calculator->GetPrinters().size(), kNumPrinters);
156 }
157 
158 TEST_F(CalculatorsPoliciesBinderTest, PrefsAllowlist) {
159   auto calculator = UserCalculator();
160 
161   // Set prefs to complete computation
162   prefs_.SetManagedPref(
163       prefs::kRecommendedPrintersAccessMode,
164       std::make_unique<base::Value>(
165           BulkPrintersCalculator::AccessMode::ALLOWLIST_ONLY));
166   prefs_.SetManagedPref(prefs::kRecommendedPrintersAllowlist,
167                         StringsToList(kAllowlistIds));
168 
169   env_.RunUntilIdle();
170   EXPECT_TRUE(calculator->IsComplete());
171   EXPECT_EQ(calculator->GetPrinters().size(), kAllowlistPrinters);
172 }
173 
174 TEST_F(CalculatorsPoliciesBinderTest, PrefsBlocklist) {
175   auto calculator = UserCalculator();
176 
177   // Set prefs to complete computation
178   prefs_.SetManagedPref(
179       prefs::kRecommendedPrintersAccessMode,
180       std::make_unique<base::Value>(
181           BulkPrintersCalculator::AccessMode::BLOCKLIST_ONLY));
182   prefs_.SetManagedPref(prefs::kRecommendedPrintersBlocklist,
183                         StringsToList(kBlocklistIds));
184 
185   env_.RunUntilIdle();
186   EXPECT_TRUE(calculator->IsComplete());
187   EXPECT_EQ(calculator->GetPrinters().size(), kBlocklistPrinters);
188 }
189 
190 TEST_F(CalculatorsPoliciesBinderTest, PrefsBeforeBind) {
191   // Verify that if preferences are set before we bind to policies, the
192   // calculator is still properly populated.
193   prefs_.SetManagedPref(
194       prefs::kRecommendedPrintersAccessMode,
195       std::make_unique<base::Value>(
196           BulkPrintersCalculator::AccessMode::ALLOWLIST_ONLY));
197   prefs_.SetManagedPref(prefs::kRecommendedPrintersAllowlist,
198                         StringsToList(kAllowlistIds));
199 
200   auto calculator = UserCalculator();
201 
202   env_.RunUntilIdle();
203   EXPECT_TRUE(calculator->IsComplete());
204   EXPECT_EQ(calculator->GetPrinters().size(), kAllowlistPrinters);
205 }
206 
207 TEST_F(CalculatorsPoliciesBinderTest, SettingsAllAccess) {
208   auto calculator = DeviceCalculator();
209 
210   SetDeviceSetting(kDevicePrintersAccessMode,
211                    base::Value(BulkPrintersCalculator::AccessMode::ALL_ACCESS));
212 
213   env_.RunUntilIdle();
214   EXPECT_TRUE(calculator->IsComplete());
215   EXPECT_EQ(calculator->GetPrinters().size(), kNumPrinters);
216 }
217 
218 TEST_F(CalculatorsPoliciesBinderTest, SettingsAllowlist) {
219   auto calculator = DeviceCalculator();
220 
221   SetDeviceSetting(
222       kDevicePrintersAccessMode,
223       base::Value(BulkPrintersCalculator::AccessMode::ALLOWLIST_ONLY));
224   SetDeviceSetting(kDevicePrintersAllowlist, *StringsToList(kAllowlistIds));
225 
226   env_.RunUntilIdle();
227   EXPECT_TRUE(calculator->IsComplete());
228   EXPECT_EQ(calculator->GetPrinters().size(), kAllowlistPrinters);
229 }
230 
231 TEST_F(CalculatorsPoliciesBinderTest, SettingsBlocklist) {
232   auto calculator = DeviceCalculator();
233 
234   SetDeviceSetting(
235       kDevicePrintersAccessMode,
236       base::Value(BulkPrintersCalculator::AccessMode::BLOCKLIST_ONLY));
237   SetDeviceSetting(kDevicePrintersBlocklist, *StringsToList(kBlocklistIds));
238 
239   env_.RunUntilIdle();
240   EXPECT_TRUE(calculator->IsComplete());
241   EXPECT_EQ(calculator->GetPrinters().size(), kBlocklistPrinters);
242 }
243 
244 TEST_F(CalculatorsPoliciesBinderTest, SettingsBeforeBind) {
245   // Set policy before binding to the calculator.
246   SetDeviceSetting(kDevicePrintersAccessMode,
247                    base::Value(BulkPrintersCalculator::AccessMode::ALL_ACCESS));
248 
249   auto calculator = DeviceCalculator();
250 
251   env_.RunUntilIdle();
252   EXPECT_TRUE(calculator->IsComplete());
253   EXPECT_EQ(calculator->GetPrinters().size(), kNumPrinters);
254 }
255 
256 }  // namespace
257 }  // namespace chromeos
258