Fix emulator build error
[platform/framework/web/chromium-efl.git] / components / permissions / permission_decision_auto_blocker_unittest.cc
1 // Copyright 2016 The Chromium Authors
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 "components/permissions/permission_decision_auto_blocker.h"
6
7 #include <map>
8 #include <memory>
9
10 #include "base/functional/bind.h"
11 #include "base/run_loop.h"
12 #include "base/test/gtest_util.h"
13 #include "base/test/metrics/histogram_tester.h"
14 #include "base/test/scoped_feature_list.h"
15 #include "base/test/simple_test_clock.h"
16 #include "components/content_settings/core/common/content_settings_types.h"
17 #include "components/permissions/features.h"
18 #include "components/permissions/permission_util.h"
19 #include "components/permissions/test/test_permissions_client.h"
20 #include "content/public/test/browser_task_environment.h"
21 #include "content/public/test/test_browser_context.h"
22
23 namespace permissions {
24 namespace {
25
26 using PermissionStatus = blink::mojom::PermissionStatus;
27
28 bool FilterGoogle(const GURL& url) {
29   return url == "https://www.google.com/";
30 }
31
32 bool FilterAll(const GURL& url) {
33   return true;
34 }
35
36 }  // namespace
37
38 class PermissionDecisionAutoBlockerUnitTest : public testing::Test {
39  protected:
40   PermissionDecisionAutoBlockerUnitTest() {
41     feature_list_.InitWithFeatures({features::kBlockPromptsIfDismissedOften,
42                                     features::kBlockPromptsIfIgnoredOften},
43                                    {});
44     last_embargoed_status_ = false;
45     autoblocker()->SetClockForTesting(&clock_);
46     callback_was_run_ = false;
47   }
48
49   PermissionDecisionAutoBlocker* autoblocker() {
50     return PermissionsClient::Get()->GetPermissionDecisionAutoBlocker(
51         &browser_context_);
52   }
53
54   void SetLastEmbargoStatus(base::OnceClosure quit_closure, bool status) {
55     callback_was_run_ = true;
56     last_embargoed_status_ = status;
57     if (quit_closure) {
58       std::move(quit_closure).Run();
59     }
60   }
61
62   bool last_embargoed_status() { return last_embargoed_status_; }
63
64   bool callback_was_run() { return callback_was_run_; }
65
66   base::SimpleTestClock* clock() { return &clock_; }
67
68  private:
69   content::BrowserTaskEnvironment task_environment_;
70   base::SimpleTestClock clock_;
71   base::test::ScopedFeatureList feature_list_;
72   content::TestBrowserContext browser_context_;
73   TestPermissionsClient permissions_client_;
74   bool last_embargoed_status_;
75   bool callback_was_run_;
76 };
77
78 class MockObserver : public PermissionDecisionAutoBlocker::Observer {
79  public:
80   void OnEmbargoStarted(const GURL& origin,
81                         ContentSettingsType content_setting) override {
82     callbacks_[origin].push_back(content_setting);
83   }
84
85   std::map<GURL, std::vector<ContentSettingsType>>& GetCallbacks() {
86     return callbacks_;
87   }
88
89  private:
90   std::map<GURL, std::vector<ContentSettingsType>> callbacks_;
91 };
92
93 // Check removing the the embargo for a single permission on a site works, and
94 // that it doesn't interfere with other embargoed permissions or the same
95 // permission embargoed on other sites.
96 TEST_F(PermissionDecisionAutoBlockerUnitTest, RemoveEmbargoAndResetCounts) {
97   GURL url1("https://www.google.com");
98   GURL url2("https://www.example.com");
99
100   // Record dismissals for location and notifications in |url1|.
101   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
102       url1, ContentSettingsType::GEOLOCATION, false));
103   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
104       url1, ContentSettingsType::GEOLOCATION, false));
105   EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
106       url1, ContentSettingsType::GEOLOCATION, false));
107   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
108       url1, ContentSettingsType::NOTIFICATIONS, false));
109   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
110       url1, ContentSettingsType::NOTIFICATIONS, false));
111   EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
112       url1, ContentSettingsType::NOTIFICATIONS, false));
113   // Record dismissals for location in |url2|.
114   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
115       url2, ContentSettingsType::GEOLOCATION, false));
116   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
117       url2, ContentSettingsType::GEOLOCATION, false));
118   EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
119       url2, ContentSettingsType::GEOLOCATION, false));
120
121   // Verify all dismissals recorded above resulted in embargo.
122   absl::optional<content::PermissionResult> result =
123       autoblocker()->GetEmbargoResult(url1, ContentSettingsType::GEOLOCATION);
124   EXPECT_EQ(PermissionStatus::DENIED, result->status);
125   EXPECT_EQ(content::PermissionStatusSource::MULTIPLE_DISMISSALS,
126             result->source);
127   result =
128       autoblocker()->GetEmbargoResult(url1, ContentSettingsType::NOTIFICATIONS);
129   EXPECT_EQ(PermissionStatus::DENIED, result->status);
130   EXPECT_EQ(content::PermissionStatusSource::MULTIPLE_DISMISSALS,
131             result->source);
132   result =
133       autoblocker()->GetEmbargoResult(url2, ContentSettingsType::GEOLOCATION);
134   EXPECT_EQ(PermissionStatus::DENIED, result->status);
135   EXPECT_EQ(content::PermissionStatusSource::MULTIPLE_DISMISSALS,
136             result->source);
137
138   // Remove the embargo on notifications. Verify it is no longer under embargo,
139   // but location still is.
140   autoblocker()->RemoveEmbargoAndResetCounts(
141       url1, ContentSettingsType::NOTIFICATIONS);
142   result =
143       autoblocker()->GetEmbargoResult(url1, ContentSettingsType::GEOLOCATION);
144   EXPECT_EQ(PermissionStatus::DENIED, result->status);
145   EXPECT_EQ(content::PermissionStatusSource::MULTIPLE_DISMISSALS,
146             result->source);
147   result =
148       autoblocker()->GetEmbargoResult(url1, ContentSettingsType::NOTIFICATIONS);
149   // If not under embargo, GetEmbargoResult() returns absl::nullopt.
150   EXPECT_FALSE(result.has_value());
151   // Verify |url2|'s embargo is still intact as well.
152   result =
153       autoblocker()->GetEmbargoResult(url2, ContentSettingsType::GEOLOCATION);
154   EXPECT_EQ(PermissionStatus::DENIED, result->status);
155   EXPECT_EQ(content::PermissionStatusSource::MULTIPLE_DISMISSALS,
156             result->source);
157 }
158
159 // Test it does not take one more dismissal to re-trigger embargo after
160 // removing the embargo status for a site.
161 TEST_F(PermissionDecisionAutoBlockerUnitTest,
162        DismissAfterRemovingEmbargoByURL) {
163   GURL url("https://www.example.com");
164
165   // Record dismissals for location.
166   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
167       url, ContentSettingsType::GEOLOCATION, false));
168   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
169       url, ContentSettingsType::GEOLOCATION, false));
170   EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
171       url, ContentSettingsType::GEOLOCATION, false));
172
173   // Verify location is under embargo.
174   absl::optional<content::PermissionResult> result =
175       autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
176   EXPECT_EQ(PermissionStatus::DENIED, result->status);
177   EXPECT_EQ(content::PermissionStatusSource::MULTIPLE_DISMISSALS,
178             result->source);
179
180   // Remove embargo and verify this is true.
181   autoblocker()->RemoveEmbargoAndResetCounts(url,
182                                              ContentSettingsType::GEOLOCATION);
183   result =
184       autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
185   EXPECT_FALSE(result.has_value());
186
187   // Record another dismissal and verify location is not under embargo again.
188   autoblocker()->RecordDismissAndEmbargo(url, ContentSettingsType::GEOLOCATION,
189                                          false);
190   result =
191       autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
192   EXPECT_FALSE(result.has_value());
193 }
194
195 TEST_F(PermissionDecisionAutoBlockerUnitTest,
196        NonembargoedOriginRemoveEmbargoCounts) {
197   GURL gurl_to_embargo("https://www.google.com");
198
199   // Make sure that an origin's Dismiss count is 0.
200   EXPECT_EQ(0, autoblocker()->GetDismissCount(
201                    gurl_to_embargo, ContentSettingsType::GEOLOCATION));
202
203   // Dismiss the origin a few times but do not add under embargo.
204   autoblocker()->RecordDismissAndEmbargo(
205       gurl_to_embargo, ContentSettingsType::GEOLOCATION, false);
206   autoblocker()->RecordDismissAndEmbargo(
207       gurl_to_embargo, ContentSettingsType::GEOLOCATION, false);
208
209   EXPECT_EQ(2, autoblocker()->GetDismissCount(
210                    gurl_to_embargo, ContentSettingsType::GEOLOCATION));
211
212   autoblocker()->RemoveEmbargoAndResetCounts(gurl_to_embargo,
213                                              ContentSettingsType::GEOLOCATION);
214
215   EXPECT_EQ(0, autoblocker()->GetDismissCount(
216                    gurl_to_embargo, ContentSettingsType::GEOLOCATION));
217
218   autoblocker()->RecordIgnoreAndEmbargo(gurl_to_embargo,
219                                         ContentSettingsType::MIDI_SYSEX, false);
220   autoblocker()->RecordIgnoreAndEmbargo(gurl_to_embargo,
221                                         ContentSettingsType::MIDI_SYSEX, false);
222
223   EXPECT_EQ(2, autoblocker()->GetIgnoreCount(gurl_to_embargo,
224                                              ContentSettingsType::MIDI_SYSEX));
225
226   autoblocker()->RemoveEmbargoAndResetCounts(gurl_to_embargo,
227                                              ContentSettingsType::MIDI_SYSEX);
228
229   EXPECT_EQ(0, autoblocker()->GetIgnoreCount(gurl_to_embargo,
230                                              ContentSettingsType::MIDI_SYSEX));
231 }
232
233 TEST_F(PermissionDecisionAutoBlockerUnitTest, RemoveEmbargoCounts) {
234   GURL gurl_to_embargo("https://www.google.com");
235
236   // Add an origin under embargo for 2 dismissed and 1 ignored
237   // ContentSettingsType.
238   autoblocker()->RecordDismissAndEmbargo(
239       gurl_to_embargo, ContentSettingsType::GEOLOCATION, false);
240   autoblocker()->RecordDismissAndEmbargo(
241       gurl_to_embargo, ContentSettingsType::GEOLOCATION, false);
242   autoblocker()->RecordDismissAndEmbargo(
243       gurl_to_embargo, ContentSettingsType::GEOLOCATION, false);
244
245   EXPECT_EQ(3, autoblocker()->GetDismissCount(
246                    gurl_to_embargo, ContentSettingsType::GEOLOCATION));
247
248   autoblocker()->RecordDismissAndEmbargo(
249       gurl_to_embargo, ContentSettingsType::NOTIFICATIONS, false);
250   autoblocker()->RecordDismissAndEmbargo(
251       gurl_to_embargo, ContentSettingsType::NOTIFICATIONS, false);
252   autoblocker()->RecordDismissAndEmbargo(
253       gurl_to_embargo, ContentSettingsType::NOTIFICATIONS, false);
254
255   EXPECT_EQ(3, autoblocker()->GetDismissCount(
256                    gurl_to_embargo, ContentSettingsType::NOTIFICATIONS));
257
258   autoblocker()->RecordIgnoreAndEmbargo(gurl_to_embargo,
259                                         ContentSettingsType::MIDI_SYSEX, false);
260   autoblocker()->RecordIgnoreAndEmbargo(gurl_to_embargo,
261                                         ContentSettingsType::MIDI_SYSEX, false);
262   autoblocker()->RecordIgnoreAndEmbargo(gurl_to_embargo,
263                                         ContentSettingsType::MIDI_SYSEX, false);
264   autoblocker()->RecordIgnoreAndEmbargo(gurl_to_embargo,
265                                         ContentSettingsType::MIDI_SYSEX, false);
266
267   EXPECT_EQ(4, autoblocker()->GetIgnoreCount(gurl_to_embargo,
268                                              ContentSettingsType::MIDI_SYSEX));
269
270   autoblocker()->RemoveEmbargoAndResetCounts(gurl_to_embargo,
271                                              ContentSettingsType::GEOLOCATION);
272
273   // GEOLOCATION has been cleared, a dismiss count should be 0.
274   EXPECT_EQ(0, autoblocker()->GetDismissCount(
275                    gurl_to_embargo, ContentSettingsType::GEOLOCATION));
276   // GEOLOCATION has been cleared, but other counts should be
277   // preservet.
278   EXPECT_EQ(3, autoblocker()->GetDismissCount(
279                    gurl_to_embargo, ContentSettingsType::NOTIFICATIONS));
280   EXPECT_EQ(4, autoblocker()->GetIgnoreCount(gurl_to_embargo,
281                                              ContentSettingsType::MIDI_SYSEX));
282 }
283
284 TEST_F(PermissionDecisionAutoBlockerUnitTest, RemoveEmbargoAndResetCounts_All) {
285   GURL url1("https://www.google.com");
286   GURL url2("https://www.example.com");
287
288   // Record some dismissals.
289   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
290       url1, ContentSettingsType::GEOLOCATION, false));
291   EXPECT_EQ(1, autoblocker()->GetDismissCount(
292                    url1, ContentSettingsType::GEOLOCATION));
293
294   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
295       url1, ContentSettingsType::GEOLOCATION, false));
296   EXPECT_EQ(2, autoblocker()->GetDismissCount(
297                    url1, ContentSettingsType::GEOLOCATION));
298
299   EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
300       url1, ContentSettingsType::GEOLOCATION, false));
301   EXPECT_EQ(3, autoblocker()->GetDismissCount(
302                    url1, ContentSettingsType::GEOLOCATION));
303
304   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
305       url2, ContentSettingsType::GEOLOCATION, false));
306   EXPECT_EQ(1, autoblocker()->GetDismissCount(
307                    url2, ContentSettingsType::GEOLOCATION));
308
309   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
310       url1, ContentSettingsType::NOTIFICATIONS, false));
311   EXPECT_EQ(1, autoblocker()->GetDismissCount(
312                    url1, ContentSettingsType::NOTIFICATIONS));
313
314   // Record some ignores.
315   EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
316       url1, ContentSettingsType::MIDI_SYSEX, false));
317   EXPECT_EQ(
318       1, autoblocker()->GetIgnoreCount(url1, ContentSettingsType::MIDI_SYSEX));
319   EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
320       url1, ContentSettingsType::DURABLE_STORAGE, false));
321   EXPECT_EQ(1, autoblocker()->GetIgnoreCount(
322                    url1, ContentSettingsType::DURABLE_STORAGE));
323   EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
324       url2, ContentSettingsType::GEOLOCATION, false));
325   EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
326       url2, ContentSettingsType::GEOLOCATION, false));
327   EXPECT_EQ(
328       2, autoblocker()->GetIgnoreCount(url2, ContentSettingsType::GEOLOCATION));
329
330   autoblocker()->RemoveEmbargoAndResetCounts(
331       base::BindRepeating(&FilterGoogle));
332
333   // Expect that url1's actions are gone, but url2's remain.
334   EXPECT_EQ(0, autoblocker()->GetDismissCount(
335                    url1, ContentSettingsType::GEOLOCATION));
336   EXPECT_EQ(0, autoblocker()->GetDismissCount(
337                    url1, ContentSettingsType::NOTIFICATIONS));
338   EXPECT_EQ(
339       0, autoblocker()->GetIgnoreCount(url1, ContentSettingsType::MIDI_SYSEX));
340   EXPECT_EQ(0, autoblocker()->GetIgnoreCount(
341                    url1, ContentSettingsType::DURABLE_STORAGE));
342
343   EXPECT_EQ(1, autoblocker()->GetDismissCount(
344                    url2, ContentSettingsType::GEOLOCATION));
345   EXPECT_EQ(
346       2, autoblocker()->GetIgnoreCount(url2, ContentSettingsType::GEOLOCATION));
347
348   // Add some more actions.
349   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
350       url1, ContentSettingsType::GEOLOCATION, false));
351   EXPECT_EQ(1, autoblocker()->GetDismissCount(
352                    url1, ContentSettingsType::GEOLOCATION));
353
354   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
355       url1, ContentSettingsType::NOTIFICATIONS, false));
356   EXPECT_EQ(1, autoblocker()->GetDismissCount(
357                    url1, ContentSettingsType::NOTIFICATIONS));
358
359   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
360       url2, ContentSettingsType::GEOLOCATION, false));
361   EXPECT_EQ(2, autoblocker()->GetDismissCount(
362                    url2, ContentSettingsType::GEOLOCATION));
363
364   EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
365       url1, ContentSettingsType::GEOLOCATION, false));
366   EXPECT_EQ(
367       1, autoblocker()->GetIgnoreCount(url1, ContentSettingsType::GEOLOCATION));
368   EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
369       url1, ContentSettingsType::NOTIFICATIONS, false));
370   EXPECT_EQ(1, autoblocker()->GetIgnoreCount(
371                    url1, ContentSettingsType::NOTIFICATIONS));
372   EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
373       url1, ContentSettingsType::DURABLE_STORAGE, false));
374   EXPECT_EQ(1, autoblocker()->GetIgnoreCount(
375                    url1, ContentSettingsType::DURABLE_STORAGE));
376   EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
377       url2, ContentSettingsType::MIDI_SYSEX, false));
378   EXPECT_EQ(
379       1, autoblocker()->GetIgnoreCount(url2, ContentSettingsType::MIDI_SYSEX));
380
381   // Remove everything and expect that it's all gone.
382   autoblocker()->RemoveEmbargoAndResetCounts(base::BindRepeating(&FilterAll));
383
384   EXPECT_EQ(0, autoblocker()->GetDismissCount(
385                    url1, ContentSettingsType::GEOLOCATION));
386   EXPECT_EQ(0, autoblocker()->GetDismissCount(
387                    url1, ContentSettingsType::NOTIFICATIONS));
388   EXPECT_EQ(0, autoblocker()->GetDismissCount(
389                    url2, ContentSettingsType::GEOLOCATION));
390
391   EXPECT_EQ(
392       0, autoblocker()->GetIgnoreCount(url1, ContentSettingsType::GEOLOCATION));
393   EXPECT_EQ(0, autoblocker()->GetIgnoreCount(
394                    url1, ContentSettingsType::NOTIFICATIONS));
395   EXPECT_EQ(
396       0, autoblocker()->GetIgnoreCount(url2, ContentSettingsType::GEOLOCATION));
397   EXPECT_EQ(0, autoblocker()->GetIgnoreCount(
398                    url2, ContentSettingsType::DURABLE_STORAGE));
399   EXPECT_EQ(
400       0, autoblocker()->GetIgnoreCount(url2, ContentSettingsType::MIDI_SYSEX));
401 }
402
403 // Check that GetEmbargoedOrigins only returns origins where embargo is the
404 // effective permission enforcement mechanism.
405 TEST_F(PermissionDecisionAutoBlockerUnitTest, CheckEmbargoedOrigins) {
406   GURL url1("https://www.google.com");
407   GURL url2("https://www.google.com:8443");
408   std::vector<ContentSettingsType> content_types = {
409       ContentSettingsType::GEOLOCATION, ContentSettingsType::NOTIFICATIONS};
410   std::set<GURL> origins;
411   clock()->SetNow(base::Time::Now());
412
413   EXPECT_EQ(0UL, autoblocker()->GetEmbargoedOrigins(content_types).size());
414
415   // Place both origins under embargo and verify.
416   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
417       url1, ContentSettingsType::GEOLOCATION, false));
418   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
419       url1, ContentSettingsType::GEOLOCATION, false));
420   EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
421       url1, ContentSettingsType::GEOLOCATION, false));
422   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
423       url2, ContentSettingsType::NOTIFICATIONS, false));
424   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
425       url2, ContentSettingsType::NOTIFICATIONS, false));
426   EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
427       url2, ContentSettingsType::NOTIFICATIONS, false));
428
429   origins = autoblocker()->GetEmbargoedOrigins(content_types);
430   EXPECT_EQ(2UL, origins.size());
431   EXPECT_EQ(1UL, origins.count(url1));
432   EXPECT_EQ(1UL, origins.count(url2));
433
434   // Check no leakage between content types
435   origins =
436       autoblocker()->GetEmbargoedOrigins(ContentSettingsType::GEOLOCATION);
437   EXPECT_EQ(1UL, origins.count(url1));
438   origins =
439       autoblocker()->GetEmbargoedOrigins(ContentSettingsType::NOTIFICATIONS);
440   EXPECT_EQ(1UL, origins.count(url2));
441
442   // Remove an embargo and confirm it's removed from origins
443   autoblocker()->RemoveEmbargoAndResetCounts(url1,
444                                              ContentSettingsType::GEOLOCATION);
445   origins = autoblocker()->GetEmbargoedOrigins(content_types);
446   EXPECT_EQ(1UL, origins.size());
447   EXPECT_EQ(1UL, origins.count(url2));
448
449   // Expire the remaining embargo and confirm the origin is removed
450   clock()->Advance(base::Days(8));
451   origins = autoblocker()->GetEmbargoedOrigins(content_types);
452   EXPECT_EQ(0UL, origins.size());
453 }
454
455 // Check that GetEmbargoResult returns the correct value when the embargo is set
456 // and expires.
457 TEST_F(PermissionDecisionAutoBlockerUnitTest, CheckEmbargoStatus) {
458   GURL url("https://www.google.com");
459   clock()->SetNow(base::Time::Now());
460
461   // Check the default state.
462   absl::optional<content::PermissionResult> result =
463       autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
464   EXPECT_FALSE(result.has_value());
465
466   // Place under embargo and verify.
467   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
468       url, ContentSettingsType::GEOLOCATION, false));
469   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
470       url, ContentSettingsType::GEOLOCATION, false));
471   EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
472       url, ContentSettingsType::GEOLOCATION, false));
473   result =
474       autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
475   EXPECT_EQ(PermissionStatus::DENIED, result->status);
476   EXPECT_EQ(content::PermissionStatusSource::MULTIPLE_DISMISSALS,
477             result->source);
478
479   // Check that the origin is not under embargo for a different permission.
480   result =
481       autoblocker()->GetEmbargoResult(url, ContentSettingsType::NOTIFICATIONS);
482   EXPECT_FALSE(result.has_value());
483
484   // Confirm embargo status during the embargo period.
485   clock()->Advance(base::Days(5));
486   result =
487       autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
488   EXPECT_EQ(PermissionStatus::DENIED, result->status);
489   EXPECT_EQ(content::PermissionStatusSource::MULTIPLE_DISMISSALS,
490             result->source);
491
492   // Check embargo is lifted on expiry day. A small offset after the exact
493   // embargo expiration date has been added to account for any precision errors
494   // when removing the date stored as a double from the permission dictionary.
495   clock()->Advance(base::Hours(3 * 24 + 1));
496   result =
497       autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
498   EXPECT_FALSE(result.has_value());
499
500   // Check embargo is lifted well after the expiry day.
501   clock()->Advance(base::Days(1));
502   result =
503       autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
504   EXPECT_FALSE(result.has_value());
505
506   // Place under embargo again and verify the embargo status.
507   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
508       url, ContentSettingsType::NOTIFICATIONS, false));
509   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
510       url, ContentSettingsType::NOTIFICATIONS, false));
511   EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
512       url, ContentSettingsType::NOTIFICATIONS, false));
513   clock()->Advance(base::Days(1));
514   result =
515       autoblocker()->GetEmbargoResult(url, ContentSettingsType::NOTIFICATIONS);
516   EXPECT_EQ(PermissionStatus::DENIED, result->status);
517   EXPECT_EQ(content::PermissionStatusSource::MULTIPLE_DISMISSALS,
518             result->source);
519   result =
520       autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
521   EXPECT_FALSE(result.has_value());
522 }
523
524 // Check that GetEmbargoStartTime returns the correct time for embargoes whether
525 // they are nonexistent, expired or active.
526 TEST_F(PermissionDecisionAutoBlockerUnitTest, CheckEmbargoStartTime) {
527   GURL url("https://www.google.com");
528
529   // The time recorded for embargoes will be stored as a double, which will
530   // cause aliasing to a limited set of base::Time values upon retrieval. We
531   // thus pick a base::Time for our test time that is part of this set via
532   // aliasing the current time by passing it through a double. This allows us
533   // to directly compare the test time and times retrieved from storage.
534   base::Time test_time = base::Time::FromDeltaSinceWindowsEpoch(
535       base::Microseconds(static_cast<double>(
536           base::Time::Now().ToDeltaSinceWindowsEpoch().InMicroseconds())));
537   clock()->SetNow(test_time);
538
539   // Check the default non embargod state.
540   base::Time embargo_start_time =
541       autoblocker()->GetEmbargoStartTime(url, ContentSettingsType::GEOLOCATION);
542   EXPECT_EQ(base::Time(), embargo_start_time);
543
544   // Ensure that dismissing less than the required number for an embargo
545   // does not record an embargo start time.
546   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
547       url, ContentSettingsType::GEOLOCATION, false));
548   embargo_start_time =
549       autoblocker()->GetEmbargoStartTime(url, ContentSettingsType::GEOLOCATION);
550   EXPECT_EQ(base::Time(), embargo_start_time);
551
552   // Place site under geolocation dismissal embargo.
553   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
554       url, ContentSettingsType::GEOLOCATION, false));
555   EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
556       url, ContentSettingsType::GEOLOCATION, false));
557
558   // Confirm embargo is recorded as starting at the correct time.
559   embargo_start_time =
560       autoblocker()->GetEmbargoStartTime(url, ContentSettingsType::GEOLOCATION);
561   EXPECT_EQ(test_time, embargo_start_time);
562
563   // Ensure moving clock while within embargo period does not affect embargo
564   // start time.
565   clock()->Advance(base::Days(5));
566   embargo_start_time =
567       autoblocker()->GetEmbargoStartTime(url, ContentSettingsType::GEOLOCATION);
568   EXPECT_EQ(test_time, embargo_start_time);
569
570   // Move clock beyond embaro (plus a small offset for potential precision
571   // errors) and confirm start time is unaffected but embargo is suspended.
572   clock()->Advance(base::Hours(3 * 24 + 1));
573   embargo_start_time =
574       autoblocker()->GetEmbargoStartTime(url, ContentSettingsType::GEOLOCATION);
575   EXPECT_EQ(test_time, embargo_start_time);
576   absl::optional<content::PermissionResult> result =
577       autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
578   EXPECT_FALSE(result.has_value());
579
580   // Advance time, reinstate embargo and confirm that time is updated.
581   test_time += base::Days(9);
582   test_time = base::Time::FromDeltaSinceWindowsEpoch(
583       base::Microseconds(static_cast<double>(
584           test_time.ToDeltaSinceWindowsEpoch().InMicroseconds())));
585   clock()->SetNow(test_time);
586
587   EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
588       url, ContentSettingsType::GEOLOCATION, false));
589   embargo_start_time =
590       autoblocker()->GetEmbargoStartTime(url, ContentSettingsType::GEOLOCATION);
591   EXPECT_EQ(test_time, embargo_start_time);
592
593   // Advance time to expire dismiss embargo and create new embargo for ignoring.
594   test_time += base::Days(7);
595   test_time = base::Time::FromDeltaSinceWindowsEpoch(
596       base::Microseconds(static_cast<double>(
597           test_time.ToDeltaSinceWindowsEpoch().InMicroseconds())));
598   clock()->SetNow(test_time);
599
600   EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
601       url, ContentSettingsType::GEOLOCATION, false));
602   EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
603       url, ContentSettingsType::GEOLOCATION, false));
604   EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
605       url, ContentSettingsType::GEOLOCATION, false));
606   EXPECT_TRUE(autoblocker()->RecordIgnoreAndEmbargo(
607       url, ContentSettingsType::GEOLOCATION, false));
608
609   // Confirm the most recent embargo is updated to match new ignore embargo.
610   embargo_start_time =
611       autoblocker()->GetEmbargoStartTime(url, ContentSettingsType::GEOLOCATION);
612   EXPECT_EQ(test_time, embargo_start_time);
613
614   // Advance time, reinstate the dismiss embargo via a single action, and
615   // confirm that time is updated.
616   test_time += base::Days(1);
617   test_time = base::Time::FromDeltaSinceWindowsEpoch(
618       base::Microseconds(static_cast<double>(
619           test_time.ToDeltaSinceWindowsEpoch().InMicroseconds())));
620   clock()->SetNow(test_time);
621
622   EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
623       url, ContentSettingsType::GEOLOCATION, false));
624   embargo_start_time =
625       autoblocker()->GetEmbargoStartTime(url, ContentSettingsType::GEOLOCATION);
626   EXPECT_EQ(test_time, embargo_start_time);
627
628   // Remove records of dismiss and ignore embargoes and confirm start time
629   // reverts to default.
630   autoblocker()->RemoveEmbargoAndResetCounts(
631       base::BindRepeating(&FilterGoogle));
632   embargo_start_time =
633       autoblocker()->GetEmbargoStartTime(url, ContentSettingsType::GEOLOCATION);
634   EXPECT_EQ(base::Time(), embargo_start_time);
635 }
636
637 // Tests the alternating pattern of the block on multiple dismiss behaviour. On
638 // N dismissals, the origin to be embargoed for the requested permission and
639 // automatically blocked. Each time the embargo is lifted, the site gets another
640 // chance to request the permission, but if it is again dismissed it is placed
641 // under embargo again and its permission requests blocked.
642 TEST_F(PermissionDecisionAutoBlockerUnitTest, TestDismissEmbargoBackoff) {
643   GURL url("https://www.google.com");
644   clock()->SetNow(base::Time::Now());
645   base::HistogramTester histograms;
646
647   // Record some dismisses.
648   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
649       url, ContentSettingsType::GEOLOCATION, false));
650   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
651       url, ContentSettingsType::GEOLOCATION, false));
652
653   // A request with < 3 prior dismisses should not be automatically blocked.
654   absl::optional<content::PermissionResult> result =
655       autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
656   EXPECT_FALSE(result.has_value());
657
658   // After the 3rd dismiss subsequent permission requests should be autoblocked.
659   EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
660       url, ContentSettingsType::GEOLOCATION, false));
661   result =
662       autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
663   EXPECT_EQ(PermissionStatus::DENIED, result->status);
664   EXPECT_EQ(content::PermissionStatusSource::MULTIPLE_DISMISSALS,
665             result->source);
666
667   // Accelerate time forward, check that the embargo status is lifted and the
668   // request won't be automatically blocked.
669   clock()->Advance(base::Days(8));
670   result =
671       autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
672   EXPECT_FALSE(result.has_value());
673
674   // Record another dismiss, subsequent requests should be autoblocked again.
675   EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
676       url, ContentSettingsType::GEOLOCATION, false));
677   result =
678       autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
679   EXPECT_EQ(PermissionStatus::DENIED, result->status);
680   EXPECT_EQ(content::PermissionStatusSource::MULTIPLE_DISMISSALS,
681             result->source);
682
683   // Accelerate time again, check embargo is lifted and another permission
684   // request is let through.
685   clock()->Advance(base::Days(8));
686   result =
687       autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
688   EXPECT_FALSE(result.has_value());
689
690   // Record another dismiss, subsequent requests should be autoblocked again.
691   EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
692       url, ContentSettingsType::GEOLOCATION, false));
693   result =
694       autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
695   EXPECT_EQ(PermissionStatus::DENIED, result->status);
696   EXPECT_EQ(content::PermissionStatusSource::MULTIPLE_DISMISSALS,
697             result->source);
698 }
699
700 // Tests the alternating pattern of the block on multiple ignores behaviour.
701 TEST_F(PermissionDecisionAutoBlockerUnitTest, TestIgnoreEmbargoBackoff) {
702   GURL url("https://www.google.com");
703   clock()->SetNow(base::Time::Now());
704   base::HistogramTester histograms;
705
706   // Record some ignores.
707   EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
708       url, ContentSettingsType::MIDI_SYSEX, false));
709   EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
710       url, ContentSettingsType::MIDI_SYSEX, false));
711
712   // A request with < 4 prior ignores should not be automatically blocked.
713   absl::optional<content::PermissionResult> result =
714       autoblocker()->GetEmbargoResult(url, ContentSettingsType::MIDI_SYSEX);
715   EXPECT_FALSE(result.has_value());
716
717   // After the 4th ignore subsequent permission requests should be autoblocked.
718   EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
719       url, ContentSettingsType::MIDI_SYSEX, false));
720   EXPECT_TRUE(autoblocker()->RecordIgnoreAndEmbargo(
721       url, ContentSettingsType::MIDI_SYSEX, false));
722   result =
723       autoblocker()->GetEmbargoResult(url, ContentSettingsType::MIDI_SYSEX);
724   EXPECT_EQ(PermissionStatus::DENIED, result->status);
725   EXPECT_EQ(content::PermissionStatusSource::MULTIPLE_IGNORES, result->source);
726
727   // Accelerate time forward, check that the embargo status is lifted and the
728   // request won't be automatically blocked.
729   clock()->Advance(base::Days(8));
730   result =
731       autoblocker()->GetEmbargoResult(url, ContentSettingsType::MIDI_SYSEX);
732   EXPECT_FALSE(result.has_value());
733
734   // Record another dismiss, subsequent requests should be autoblocked again.
735   EXPECT_TRUE(autoblocker()->RecordIgnoreAndEmbargo(
736       url, ContentSettingsType::MIDI_SYSEX, false));
737   result =
738       autoblocker()->GetEmbargoResult(url, ContentSettingsType::MIDI_SYSEX);
739   EXPECT_EQ(PermissionStatus::DENIED, result->status);
740   EXPECT_EQ(content::PermissionStatusSource::MULTIPLE_IGNORES, result->source);
741
742   // Accelerate time again, check embargo is lifted and another permission
743   // request is let through.
744   clock()->Advance(base::Days(8));
745   result =
746       autoblocker()->GetEmbargoResult(url, ContentSettingsType::MIDI_SYSEX);
747   EXPECT_FALSE(result.has_value());
748
749   // Record another dismiss, subsequent requests should be autoblocked again.
750   EXPECT_TRUE(autoblocker()->RecordIgnoreAndEmbargo(
751       url, ContentSettingsType::MIDI_SYSEX, false));
752   result =
753       autoblocker()->GetEmbargoResult(url, ContentSettingsType::MIDI_SYSEX);
754   EXPECT_EQ(PermissionStatus::DENIED, result->status);
755   EXPECT_EQ(content::PermissionStatusSource::MULTIPLE_IGNORES, result->source);
756 }
757
758 // Test that quiet ui embargo has a different threshold for ignores.
759 TEST_F(PermissionDecisionAutoBlockerUnitTest, TestIgnoreEmbargoUsingQuietUi) {
760   GURL url("https://www.google.com");
761   clock()->SetNow(base::Time::Now());
762
763   // Check the default state.
764   absl::optional<content::PermissionResult> result =
765       autoblocker()->GetEmbargoResult(url, ContentSettingsType::NOTIFICATIONS);
766   EXPECT_FALSE(result.has_value());
767
768   // One quiet ui ignore is not enough to trigger embargo.
769   EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
770       url, ContentSettingsType::NOTIFICATIONS, true));
771   result =
772       autoblocker()->GetEmbargoResult(url, ContentSettingsType::NOTIFICATIONS);
773   EXPECT_FALSE(result.has_value());
774
775   // Loud ui ignores are counted separately.
776   EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
777       url, ContentSettingsType::NOTIFICATIONS, false));
778   result =
779       autoblocker()->GetEmbargoResult(url, ContentSettingsType::NOTIFICATIONS);
780   EXPECT_FALSE(result.has_value());
781
782   // The second quiet ui ignore puts the url under embargo.
783   EXPECT_TRUE(autoblocker()->RecordIgnoreAndEmbargo(
784       url, ContentSettingsType::NOTIFICATIONS, true));
785   result =
786       autoblocker()->GetEmbargoResult(url, ContentSettingsType::NOTIFICATIONS);
787   EXPECT_EQ(PermissionStatus::DENIED, result->status);
788   EXPECT_EQ(content::PermissionStatusSource::MULTIPLE_IGNORES, result->source);
789 }
790
791 // Test that quiet ui embargo has a different threshold for dismisses.
792 TEST_F(PermissionDecisionAutoBlockerUnitTest, TestDismissEmbargoUsingQuietUi) {
793   GURL url("https://www.google.com");
794   clock()->SetNow(base::Time::Now());
795
796   // Check the default state.
797   absl::optional<content::PermissionResult> result =
798       autoblocker()->GetEmbargoResult(url, ContentSettingsType::NOTIFICATIONS);
799   EXPECT_FALSE(result.has_value());
800
801   // One loud ui dismiss does not trigger embargo.
802   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
803       url, ContentSettingsType::NOTIFICATIONS, false));
804   result =
805       autoblocker()->GetEmbargoResult(url, ContentSettingsType::NOTIFICATIONS);
806   EXPECT_FALSE(result.has_value());
807
808   // One quiet ui dismiss puts the url under embargo.
809   EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
810       url, ContentSettingsType::NOTIFICATIONS, true));
811   result =
812       autoblocker()->GetEmbargoResult(url, ContentSettingsType::NOTIFICATIONS);
813   EXPECT_EQ(PermissionStatus::DENIED, result->status);
814   EXPECT_EQ(content::PermissionStatusSource::MULTIPLE_DISMISSALS,
815             result->source);
816 }
817
818 namespace {
819
820 // Checks that embargo on federated identity permission is lifted only after the
821 // passed-in |time_delta| has elapsed.
822 void CheckFederatedIdentityApiEmbargoLiftedAfterTimeElapsing(
823     PermissionDecisionAutoBlocker* autoblocker,
824     base::SimpleTestClock* clock,
825     const GURL& url,
826     base::TimeDelta time_delta) {
827   ASSERT_LT(base::Minutes(1), time_delta);
828
829   clock->Advance(time_delta - base::Minutes(1));
830   absl::optional<content::PermissionResult> result =
831       autoblocker->GetEmbargoResult(
832           url, ContentSettingsType::FEDERATED_IDENTITY_API);
833   EXPECT_EQ(PermissionStatus::DENIED, result->status);
834   EXPECT_EQ(content::PermissionStatusSource::MULTIPLE_DISMISSALS,
835             result->source);
836
837   clock->Advance(base::Minutes(2));
838   result = autoblocker->GetEmbargoResult(
839       url, ContentSettingsType::FEDERATED_IDENTITY_API);
840   EXPECT_FALSE(result.has_value());
841 }
842
843 // Checks that embargo on federated identity auto re-authn permission is lifted
844 // only after the passed-in |time_delta| has elapsed.
845 void CheckFederatedIdentityAutoReauthnEmbargoLiftedAfterTimeElapsing(
846     PermissionDecisionAutoBlocker* autoblocker,
847     base::SimpleTestClock* clock,
848     const GURL& url,
849     base::TimeDelta time_delta) {
850   ASSERT_LT(base::Minutes(1), time_delta);
851
852   clock->Advance(time_delta - base::Minutes(1));
853   absl::optional<content::PermissionResult> result =
854       autoblocker->GetEmbargoResult(
855           url, ContentSettingsType::FEDERATED_IDENTITY_AUTO_REAUTHN_PERMISSION);
856   EXPECT_EQ(PermissionStatus::DENIED, result->status);
857   EXPECT_EQ(content::PermissionStatusSource::RECENT_DISPLAY, result->source);
858
859   clock->Advance(base::Minutes(2));
860   result = autoblocker->GetEmbargoResult(
861       url, ContentSettingsType::FEDERATED_IDENTITY_AUTO_REAUTHN_PERMISSION);
862   EXPECT_FALSE(result.has_value());
863 }
864
865 }  // namespace
866
867 TEST_F(PermissionDecisionAutoBlockerUnitTest,
868        TestDismissFederatedIdentityApiBackoff) {
869   GURL url("https://www.google.com");
870   clock()->SetNow(base::Time::Now());
871
872   absl::optional<content::PermissionResult> result =
873       autoblocker()->GetEmbargoResult(
874           url, ContentSettingsType::FEDERATED_IDENTITY_API);
875   EXPECT_FALSE(result.has_value());
876
877   // 2 hour embargo for 1st dismissal
878   EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
879       url, ContentSettingsType::FEDERATED_IDENTITY_API, false));
880   CheckFederatedIdentityApiEmbargoLiftedAfterTimeElapsing(
881       autoblocker(), clock(), url, base::Hours(2));
882
883   // 1 day embargo for 2nd dismissal
884   EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
885       url, ContentSettingsType::FEDERATED_IDENTITY_API, false));
886   CheckFederatedIdentityApiEmbargoLiftedAfterTimeElapsing(
887       autoblocker(), clock(), url, base::Days(1));
888
889   // 7 day embargo for 3rd dismissal
890   EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
891       url, ContentSettingsType::FEDERATED_IDENTITY_API, false));
892   CheckFederatedIdentityApiEmbargoLiftedAfterTimeElapsing(
893       autoblocker(), clock(), url, base::Days(7));
894
895   // 28 day embargo for 4th dismissal (and all additional dismissals)
896   EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
897       url, ContentSettingsType::FEDERATED_IDENTITY_API, false));
898   CheckFederatedIdentityApiEmbargoLiftedAfterTimeElapsing(
899       autoblocker(), clock(), url, base::Days(28));
900
901   EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
902       url, ContentSettingsType::FEDERATED_IDENTITY_API, false));
903   CheckFederatedIdentityApiEmbargoLiftedAfterTimeElapsing(
904       autoblocker(), clock(), url, base::Days(28));
905
906   // Return to 2 hour embargo after
907   // PermissionDecisionAutoBlocker::RemoveEmbargoAndResetCounts()
908   autoblocker()->RemoveEmbargoAndResetCounts(
909       url, ContentSettingsType::FEDERATED_IDENTITY_API);
910   result = autoblocker()->GetEmbargoResult(
911       url, ContentSettingsType::FEDERATED_IDENTITY_API);
912   EXPECT_FALSE(result.has_value());
913
914   EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
915       url, ContentSettingsType::FEDERATED_IDENTITY_API, false));
916   CheckFederatedIdentityApiEmbargoLiftedAfterTimeElapsing(
917       autoblocker(), clock(), url, base::Hours(2));
918 }
919
920 TEST_F(PermissionDecisionAutoBlockerUnitTest,
921        TestLogoutFederatedIdentityAutoReauthnBackoff) {
922   GURL url("https://www.google.com");
923   clock()->SetNow(base::Time::Now());
924
925   absl::optional<content::PermissionResult> result =
926       autoblocker()->GetEmbargoResult(
927           url, ContentSettingsType::FEDERATED_IDENTITY_AUTO_REAUTHN_PERMISSION);
928   EXPECT_FALSE(result.has_value());
929
930   // 10 minute embargo
931   EXPECT_TRUE(autoblocker()->RecordDisplayAndEmbargo(
932       url, ContentSettingsType::FEDERATED_IDENTITY_AUTO_REAUTHN_PERMISSION));
933   CheckFederatedIdentityAutoReauthnEmbargoLiftedAfterTimeElapsing(
934       autoblocker(), clock(), url, base::Minutes(10));
935 }
936
937 TEST_F(PermissionDecisionAutoBlockerUnitTest,
938        ObserverIsNotifiedWhenEmbargoStarts) {
939   GURL url("https://www.google.com");
940   MockObserver observer;
941   autoblocker()->AddObserver(&observer);
942
943   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
944       url, ContentSettingsType::GEOLOCATION, false));
945   EXPECT_EQ(0u, observer.GetCallbacks().size());
946
947   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
948       url, ContentSettingsType::GEOLOCATION, false));
949   EXPECT_EQ(0u, observer.GetCallbacks().size());
950
951   EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
952       url, ContentSettingsType::GEOLOCATION, false));
953   EXPECT_EQ(1u, observer.GetCallbacks().size());
954   EXPECT_EQ(url, observer.GetCallbacks().begin()->first);
955   EXPECT_EQ(ContentSettingsType::GEOLOCATION, observer.GetCallbacks()[url][0]);
956
957   autoblocker()->RemoveObserver(&observer);
958 }
959
960 TEST_F(PermissionDecisionAutoBlockerUnitTest,
961        RemovedObserverIsNotNotifiedWhenEmbargoStarts) {
962   GURL url("https://www.google.com");
963   MockObserver observer;
964   autoblocker()->AddObserver(&observer);
965
966   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
967       url, ContentSettingsType::GEOLOCATION, false));
968   EXPECT_EQ(0u, observer.GetCallbacks().size());
969
970   EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
971       url, ContentSettingsType::GEOLOCATION, false));
972   EXPECT_EQ(0u, observer.GetCallbacks().size());
973   autoblocker()->RemoveObserver(&observer);
974
975   EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
976       url, ContentSettingsType::GEOLOCATION, false));
977   EXPECT_EQ(0u, observer.GetCallbacks().size());
978 }
979
980 }  // namespace permissions