1 // Copyright 2017 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 "content/browser/browsing_data/browsing_data_remover_impl.h"
6 
7 #include <stddef.h>
8 #include <stdint.h>
9 
10 #include <list>
11 #include <memory>
12 #include <set>
13 #include <string>
14 #include <utility>
15 #include <vector>
16 
17 #include "base/bind.h"
18 #include "base/bind_helpers.h"
19 #include "base/files/file_path.h"
20 #include "base/files/file_util.h"
21 #include "base/location.h"
22 #include "base/logging.h"
23 #include "base/macros.h"
24 #include "base/memory/ptr_util.h"
25 #include "base/run_loop.h"
26 #include "base/single_thread_task_runner.h"
27 #include "base/strings/strcat.h"
28 #include "base/strings/utf_string_conversions.h"
29 #include "base/task/cancelable_task_tracker.h"
30 #include "base/task/post_task.h"
31 #include "base/threading/thread_task_runner_handle.h"
32 #include "base/time/time.h"
33 #include "content/public/browser/browser_context.h"
34 #include "content/public/browser/browser_task_traits.h"
35 #include "content/public/browser/browsing_data_filter_builder.h"
36 #include "content/public/browser/browsing_data_remover.h"
37 #include "content/public/browser/cookie_store_factory.h"
38 #include "content/public/browser/dom_storage_context.h"
39 #include "content/public/browser/storage_partition.h"
40 #include "content/public/browser/storage_usage_info.h"
41 #include "content/public/test/browser_task_environment.h"
42 #include "content/public/test/browsing_data_remover_test_util.h"
43 #include "content/public/test/mock_download_manager.h"
44 #include "content/public/test/test_browser_context.h"
45 #include "content/public/test/test_storage_partition.h"
46 #include "content/public/test/test_utils.h"
47 #include "net/cookies/canonical_cookie.h"
48 #include "net/cookies/cookie_deletion_info.h"
49 #include "net/cookies/cookie_store.h"
50 #include "net/http/http_network_session.h"
51 #include "net/http/http_transaction_factory.h"
52 #include "net/ssl/ssl_client_cert_type.h"
53 #include "net/url_request/url_request_context.h"
54 #include "net/url_request/url_request_context_getter.h"
55 #include "ppapi/buildflags/buildflags.h"
56 #include "services/network/cookie_manager.h"
57 #include "services/network/public/cpp/features.h"
58 #include "services/network/test/test_network_context.h"
59 #include "storage/browser/test/mock_special_storage_policy.h"
60 #include "testing/gmock/include/gmock/gmock.h"
61 #include "testing/gtest/include/gtest/gtest.h"
62 #include "url/origin.h"
63 
64 #if BUILDFLAG(ENABLE_REPORTING)
65 #include "net/network_error_logging/mock_persistent_nel_store.h"
66 #include "net/network_error_logging/network_error_logging_service.h"
67 #include "net/reporting/mock_persistent_reporting_store.h"
68 #include "net/reporting/reporting_cache.h"
69 #include "net/reporting/reporting_endpoint.h"
70 #include "net/reporting/reporting_report.h"
71 #include "net/reporting/reporting_service.h"
72 #include "net/reporting/reporting_test_util.h"
73 #endif  // BUILDFLAG(ENABLE_REPORTING)
74 
75 using testing::_;
76 using testing::ByRef;
77 using testing::Eq;
78 using testing::Invoke;
79 using testing::IsEmpty;
80 using testing::MakeMatcher;
81 using testing::Matcher;
82 using testing::MatcherInterface;
83 using testing::MatchResultListener;
84 using testing::Not;
85 using testing::Return;
86 using testing::SizeIs;
87 using testing::UnorderedElementsAre;
88 using testing::WithArgs;
89 using CookieDeletionFilterPtr = network::mojom::CookieDeletionFilterPtr;
90 
91 namespace content {
92 
93 namespace {
94 
95 struct StoragePartitionRemovalData {
StoragePartitionRemovalDatacontent::__anonec3671970111::StoragePartitionRemovalData96   StoragePartitionRemovalData()
97       : remove_mask(0),
98         quota_storage_remove_mask(0),
99         cookie_deletion_filter(network::mojom::CookieDeletionFilter::New()),
100         remove_code_cache(false) {}
101 
StoragePartitionRemovalDatacontent::__anonec3671970111::StoragePartitionRemovalData102   StoragePartitionRemovalData(const StoragePartitionRemovalData& other)
103       : remove_mask(other.remove_mask),
104         quota_storage_remove_mask(other.quota_storage_remove_mask),
105         remove_begin(other.remove_begin),
106         remove_end(other.remove_end),
107         origin_matcher(other.origin_matcher),
108         cookie_deletion_filter(other.cookie_deletion_filter.Clone()),
109         remove_code_cache(other.remove_code_cache),
110         url_matcher(other.url_matcher) {}
111 
operator =content::__anonec3671970111::StoragePartitionRemovalData112   StoragePartitionRemovalData& operator=(
113       const StoragePartitionRemovalData& rhs) {
114     remove_mask = rhs.remove_mask;
115     quota_storage_remove_mask = rhs.quota_storage_remove_mask;
116     remove_begin = rhs.remove_begin;
117     remove_end = rhs.remove_end;
118     origin_matcher = rhs.origin_matcher;
119     cookie_deletion_filter = rhs.cookie_deletion_filter.Clone();
120     remove_code_cache = rhs.remove_code_cache;
121     url_matcher = rhs.url_matcher;
122     return *this;
123   }
124 
125   uint32_t remove_mask;
126   uint32_t quota_storage_remove_mask;
127   base::Time remove_begin;
128   base::Time remove_end;
129   StoragePartition::OriginMatcherFunction origin_matcher;
130   CookieDeletionFilterPtr cookie_deletion_filter;
131   bool remove_code_cache;
132   base::RepeatingCallback<bool(const GURL&)> url_matcher;
133 };
134 
CreateCookieWithHost(const url::Origin & origin)135 net::CanonicalCookie CreateCookieWithHost(const url::Origin& origin) {
136   std::unique_ptr<net::CanonicalCookie> cookie(
137       std::make_unique<net::CanonicalCookie>(
138           "A", "1", origin.host(), "/", base::Time::Now(), base::Time::Now(),
139           base::Time(), false, false, net::CookieSameSite::NO_RESTRICTION,
140           net::COOKIE_PRIORITY_MEDIUM));
141   EXPECT_TRUE(cookie);
142   return *cookie;
143 }
144 
145 class StoragePartitionRemovalTestStoragePartition
146     : public TestStoragePartition {
147  public:
148   StoragePartitionRemovalTestStoragePartition() = default;
149   ~StoragePartitionRemovalTestStoragePartition() override = default;
150 
ClearDataForOrigin(uint32_t remove_mask,uint32_t quota_storage_remove_mask,const GURL & storage_origin)151   void ClearDataForOrigin(uint32_t remove_mask,
152                           uint32_t quota_storage_remove_mask,
153                           const GURL& storage_origin) override {}
154 
ClearData(uint32_t remove_mask,uint32_t quota_storage_remove_mask,const GURL & storage_origin,const base::Time begin,const base::Time end,base::OnceClosure callback)155   void ClearData(uint32_t remove_mask,
156                  uint32_t quota_storage_remove_mask,
157                  const GURL& storage_origin,
158                  const base::Time begin,
159                  const base::Time end,
160                  base::OnceClosure callback) override {
161     // Store stuff to verify parameters' correctness later.
162     storage_partition_removal_data_.remove_mask = remove_mask;
163     storage_partition_removal_data_.quota_storage_remove_mask =
164         quota_storage_remove_mask;
165     storage_partition_removal_data_.remove_begin = begin;
166     storage_partition_removal_data_.remove_end = end;
167 
168     base::PostTask(FROM_HERE, {BrowserThread::UI}, std::move(callback));
169   }
170 
ClearData(uint32_t remove_mask,uint32_t quota_storage_remove_mask,OriginMatcherFunction origin_matcher,CookieDeletionFilterPtr cookie_deletion_filter,bool perform_storage_cleanup,const base::Time begin,const base::Time end,base::OnceClosure callback)171   void ClearData(uint32_t remove_mask,
172                  uint32_t quota_storage_remove_mask,
173                  OriginMatcherFunction origin_matcher,
174                  CookieDeletionFilterPtr cookie_deletion_filter,
175                  bool perform_storage_cleanup,
176                  const base::Time begin,
177                  const base::Time end,
178                  base::OnceClosure callback) override {
179     // Store stuff to verify parameters' correctness later.
180     storage_partition_removal_data_.remove_mask = remove_mask;
181     storage_partition_removal_data_.quota_storage_remove_mask =
182         quota_storage_remove_mask;
183     storage_partition_removal_data_.remove_begin = begin;
184     storage_partition_removal_data_.remove_end = end;
185     storage_partition_removal_data_.origin_matcher = std::move(origin_matcher);
186     storage_partition_removal_data_.cookie_deletion_filter =
187         std::move(cookie_deletion_filter);
188 
189     base::PostTask(FROM_HERE, {BrowserThread::UI}, std::move(callback));
190   }
191 
ClearCodeCaches(base::Time begin,base::Time end,const base::RepeatingCallback<bool (const GURL &)> & url_matcher,base::OnceClosure callback)192   void ClearCodeCaches(
193       base::Time begin,
194       base::Time end,
195       const base::RepeatingCallback<bool(const GURL&)>& url_matcher,
196       base::OnceClosure callback) override {
197     storage_partition_removal_data_.remove_code_cache = true;
198     storage_partition_removal_data_.remove_begin = begin;
199     storage_partition_removal_data_.remove_end = end;
200     storage_partition_removal_data_.url_matcher = url_matcher;
201   }
202 
GetStoragePartitionRemovalData() const203   const StoragePartitionRemovalData& GetStoragePartitionRemovalData() const {
204     return storage_partition_removal_data_;
205   }
206 
207  private:
208   StoragePartitionRemovalData storage_partition_removal_data_;
209 
210   DISALLOW_COPY_AND_ASSIGN(StoragePartitionRemovalTestStoragePartition);
211 };
212 
213 // Custom matcher to test the equivalence of two URL filters. Since those are
214 // blackbox predicates, we can only approximate the equivalence by testing
215 // whether the filter give the same answer for several URLs. This is currently
216 // good enough for our testing purposes, to distinguish whitelists
217 // and blacklists, empty and non-empty filters and such.
218 // TODO(msramek): BrowsingDataRemover and some of its backends support URL
219 // filters, but its constructor currently only takes a single URL and constructs
220 // its own url filter. If an url filter was directly passed to
221 // BrowsingDataRemover (what should eventually be the case), we can use the same
222 // instance in the test as well, and thus simply test
223 // base::RepeatingCallback::Equals() in this matcher.
224 class ProbablySameFilterMatcher
225     : public MatcherInterface<
226           const base::RepeatingCallback<bool(const GURL&)>&> {
227  public:
ProbablySameFilterMatcher(const base::RepeatingCallback<bool (const GURL &)> & filter)228   explicit ProbablySameFilterMatcher(
229       const base::RepeatingCallback<bool(const GURL&)>& filter)
230       : to_match_(filter) {}
231 
MatchAndExplain(const base::RepeatingCallback<bool (const GURL &)> & filter,MatchResultListener * listener) const232   bool MatchAndExplain(const base::RepeatingCallback<bool(const GURL&)>& filter,
233                        MatchResultListener* listener) const override {
234     if (!filter && !to_match_)
235       return true;
236     if (!filter || !to_match_)
237       return false;
238 
239     const GURL urls_to_test_[] = {GURL("a.com"), GURL("b.com"), GURL("c.com"),
240                                   GURL("invalid spec")};
241     for (GURL url : urls_to_test_) {
242       if (filter.Run(url) != to_match_.Run(url)) {
243         if (listener)
244           *listener << "The filters differ on the URL " << url;
245         return false;
246       }
247     }
248     return true;
249   }
250 
DescribeTo(::std::ostream * os) const251   void DescribeTo(::std::ostream* os) const override {
252     *os << "is probably the same url filter as " << &to_match_;
253   }
254 
DescribeNegationTo(::std::ostream * os) const255   void DescribeNegationTo(::std::ostream* os) const override {
256     *os << "is definitely NOT the same url filter as " << &to_match_;
257   }
258 
259  private:
260   const base::RepeatingCallback<bool(const GURL&)>& to_match_;
261 };
262 
263 inline Matcher<const base::RepeatingCallback<bool(const GURL&)>&>
ProbablySameFilter(const base::RepeatingCallback<bool (const GURL &)> & filter)264 ProbablySameFilter(const base::RepeatingCallback<bool(const GURL&)>& filter) {
265   return MakeMatcher(new ProbablySameFilterMatcher(filter));
266 }
267 
AnHourAgo()268 base::Time AnHourAgo() {
269   return base::Time::Now() - base::TimeDelta::FromHours(1);
270 }
271 
FilterMatchesCookie(const CookieDeletionFilterPtr & filter,const net::CanonicalCookie & cookie)272 bool FilterMatchesCookie(const CookieDeletionFilterPtr& filter,
273                          const net::CanonicalCookie& cookie) {
274   return network::DeletionFilterToInfo(filter.Clone()).Matches(cookie);
275 }
276 
277 }  // namespace
278 
279 // Testers -------------------------------------------------------------------
280 
281 class RemoveDownloadsTester {
282  public:
RemoveDownloadsTester(BrowserContext * browser_context)283   explicit RemoveDownloadsTester(BrowserContext* browser_context)
284       : download_manager_(new MockDownloadManager()) {
285     BrowserContext::SetDownloadManagerForTesting(
286         browser_context, base::WrapUnique(download_manager_));
287     EXPECT_EQ(download_manager_,
288               BrowserContext::GetDownloadManager(browser_context));
289     EXPECT_CALL(*download_manager_, Shutdown());
290   }
291 
292   ~RemoveDownloadsTester() = default;
293 
download_manager()294   MockDownloadManager* download_manager() { return download_manager_; }
295 
296  private:
297   MockDownloadManager* download_manager_;  // Owned by browser context.
298 
299   DISALLOW_COPY_AND_ASSIGN(RemoveDownloadsTester);
300 };
301 
302 // Test Class ----------------------------------------------------------------
303 
304 class BrowsingDataRemoverImplTest : public testing::Test {
305  public:
BrowsingDataRemoverImplTest()306   BrowsingDataRemoverImplTest() : browser_context_(new TestBrowserContext()) {
307     remover_ = static_cast<BrowsingDataRemoverImpl*>(
308         BrowserContext::GetBrowsingDataRemover(browser_context_.get()));
309   }
310 
311   ~BrowsingDataRemoverImplTest() override = default;
312 
TearDown()313   void TearDown() override {
314     mock_policy_ = nullptr;
315 
316     // BrowserContext contains a DOMStorageContext. BrowserContext's
317     // destructor posts a message to the WEBKIT thread to delete some of its
318     // member variables. We need to ensure that the browser context is
319     // destroyed, and that the message loop is cleared out, before destroying
320     // the threads and loop. Otherwise we leak memory.
321     browser_context_.reset();
322     RunAllTasksUntilIdle();
323   }
324 
BlockUntilBrowsingDataRemoved(const base::Time & delete_begin,const base::Time & delete_end,int remove_mask,bool include_protected_origins)325   void BlockUntilBrowsingDataRemoved(const base::Time& delete_begin,
326                                      const base::Time& delete_end,
327                                      int remove_mask,
328                                      bool include_protected_origins) {
329     StoragePartitionRemovalTestStoragePartition storage_partition;
330     network::TestNetworkContext nop_network_context;
331     storage_partition.set_network_context(&nop_network_context);
332     remover_->OverrideStoragePartitionForTesting(&storage_partition);
333 
334     int origin_type_mask = BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB;
335     if (include_protected_origins)
336       origin_type_mask |= BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB;
337 
338     BrowsingDataRemoverCompletionObserver completion_observer(remover_);
339     remover_->RemoveAndReply(delete_begin, delete_end, remove_mask,
340                              origin_type_mask, &completion_observer);
341     completion_observer.BlockUntilCompletion();
342 
343     // Save so we can verify later.
344     storage_partition_removal_data_ =
345         storage_partition.GetStoragePartitionRemovalData();
346   }
347 
BlockUntilOriginDataRemoved(const base::Time & delete_begin,const base::Time & delete_end,int remove_mask,std::unique_ptr<BrowsingDataFilterBuilder> filter_builder)348   void BlockUntilOriginDataRemoved(
349       const base::Time& delete_begin,
350       const base::Time& delete_end,
351       int remove_mask,
352       std::unique_ptr<BrowsingDataFilterBuilder> filter_builder) {
353     StoragePartitionRemovalTestStoragePartition storage_partition;
354     remover_->OverrideStoragePartitionForTesting(&storage_partition);
355 
356     BrowsingDataRemoverCompletionObserver completion_observer(remover_);
357     remover_->RemoveWithFilterAndReply(
358         delete_begin, delete_end, remove_mask,
359         BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
360         std::move(filter_builder), &completion_observer);
361     completion_observer.BlockUntilCompletion();
362 
363     // Save so we can verify later.
364     storage_partition_removal_data_ =
365         storage_partition.GetStoragePartitionRemovalData();
366   }
367 
GetBrowserContext()368   BrowserContext* GetBrowserContext() { return browser_context_.get(); }
369 
DestroyBrowserContext()370   void DestroyBrowserContext() { browser_context_.reset(); }
371 
GetBeginTime()372   const base::Time& GetBeginTime() {
373     return remover_->GetLastUsedBeginTimeForTesting();
374   }
375 
GetRemovalMask()376   int GetRemovalMask() { return remover_->GetLastUsedRemovalMaskForTesting(); }
377 
GetOriginTypeMask()378   int GetOriginTypeMask() {
379     return remover_->GetLastUsedOriginTypeMaskForTesting();
380   }
381 
GetStoragePartitionRemovalData() const382   const StoragePartitionRemovalData& GetStoragePartitionRemovalData() const {
383     return storage_partition_removal_data_;
384   }
385 
CreateMockPolicy()386   storage::MockSpecialStoragePolicy* CreateMockPolicy() {
387     mock_policy_ = base::MakeRefCounted<storage::MockSpecialStoragePolicy>();
388     return mock_policy_.get();
389   }
390 
mock_policy()391   storage::MockSpecialStoragePolicy* mock_policy() {
392     return mock_policy_.get();
393   }
394 
Match(const GURL & origin,int mask,storage::SpecialStoragePolicy * policy)395   bool Match(const GURL& origin,
396              int mask,
397              storage::SpecialStoragePolicy* policy) {
398     return remover_->DoesOriginMatchMaskForTesting(
399         mask, url::Origin::Create(origin), policy);
400   }
401 
402  private:
403   // Cached pointer to BrowsingDataRemoverImpl for access to testing methods.
404   BrowsingDataRemoverImpl* remover_;
405 
406   BrowserTaskEnvironment task_environment_;
407   std::unique_ptr<BrowserContext> browser_context_;
408 
409   StoragePartitionRemovalData storage_partition_removal_data_;
410 
411   scoped_refptr<storage::MockSpecialStoragePolicy> mock_policy_;
412 
413   DISALLOW_COPY_AND_ASSIGN(BrowsingDataRemoverImplTest);
414 };
415 
416 // Tests ---------------------------------------------------------------------
417 
TEST_F(BrowsingDataRemoverImplTest,RemoveCookieForever)418 TEST_F(BrowsingDataRemoverImplTest, RemoveCookieForever) {
419   BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(),
420                                 BrowsingDataRemover::DATA_TYPE_COOKIES, false);
421 
422   EXPECT_EQ(BrowsingDataRemover::DATA_TYPE_COOKIES, GetRemovalMask());
423   EXPECT_EQ(BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
424             GetOriginTypeMask());
425 
426   // Verify that storage partition was instructed to remove the cookies.
427   StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData();
428   EXPECT_EQ(removal_data.remove_mask,
429             StoragePartition::REMOVE_DATA_MASK_COOKIES);
430   EXPECT_EQ(removal_data.quota_storage_remove_mask,
431             StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL);
432   EXPECT_EQ(removal_data.remove_begin, GetBeginTime());
433 }
434 
TEST_F(BrowsingDataRemoverImplTest,RemoveCookieLastHour)435 TEST_F(BrowsingDataRemoverImplTest, RemoveCookieLastHour) {
436   BlockUntilBrowsingDataRemoved(AnHourAgo(), base::Time::Max(),
437                                 BrowsingDataRemover::DATA_TYPE_COOKIES, false);
438 
439   EXPECT_EQ(BrowsingDataRemover::DATA_TYPE_COOKIES, GetRemovalMask());
440   EXPECT_EQ(BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
441             GetOriginTypeMask());
442 
443   // Verify that storage partition was instructed to remove the cookies.
444   StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData();
445   EXPECT_EQ(removal_data.remove_mask,
446             StoragePartition::REMOVE_DATA_MASK_COOKIES);
447   // Removing with time period other than all time should not clear
448   // persistent storage data.
449   EXPECT_EQ(removal_data.quota_storage_remove_mask,
450             ~StoragePartition::QUOTA_MANAGED_STORAGE_MASK_PERSISTENT);
451   EXPECT_EQ(removal_data.remove_begin, GetBeginTime());
452 }
453 
TEST_F(BrowsingDataRemoverImplTest,RemoveCookiesDomainBlacklist)454 TEST_F(BrowsingDataRemoverImplTest, RemoveCookiesDomainBlacklist) {
455   std::unique_ptr<BrowsingDataFilterBuilder> filter(
456       BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::BLACKLIST));
457   const GURL kTestUrl1("http://host1.com");
458   const GURL kTestUrl3("http://host3.com");
459   filter->AddRegisterableDomain(kTestUrl1.host());
460   filter->AddRegisterableDomain(kTestUrl3.host());
461   BlockUntilOriginDataRemoved(AnHourAgo(), base::Time::Max(),
462                               BrowsingDataRemover::DATA_TYPE_COOKIES,
463                               std::move(filter));
464 
465   EXPECT_EQ(BrowsingDataRemover::DATA_TYPE_COOKIES, GetRemovalMask());
466   EXPECT_EQ(BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
467             GetOriginTypeMask());
468 
469   // Verify that storage partition was instructed to remove the cookies.
470   StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData();
471   EXPECT_EQ(removal_data.remove_mask,
472             StoragePartition::REMOVE_DATA_MASK_COOKIES);
473   // Removing with time period other than all time should not clear
474   // persistent storage data.
475   EXPECT_EQ(removal_data.quota_storage_remove_mask,
476             ~StoragePartition::QUOTA_MANAGED_STORAGE_MASK_PERSISTENT);
477   EXPECT_EQ(removal_data.remove_begin, GetBeginTime());
478   const url::Origin kTestOrigin1 = url::Origin::Create(kTestUrl1);
479   const url::Origin kTestOrigin2 =
480       url::Origin::Create(GURL("http://host2.com"));
481   const url::Origin kTestOrigin3 = url::Origin::Create(kTestUrl3);
482   const url::Origin kTestOrigin3Secure =
483       url::Origin::Create(GURL("https://host3.com"));
484   EXPECT_FALSE(removal_data.origin_matcher.Run(kTestOrigin1, mock_policy()));
485   EXPECT_TRUE(removal_data.origin_matcher.Run(kTestOrigin2, mock_policy()));
486   EXPECT_FALSE(removal_data.origin_matcher.Run(kTestOrigin3, mock_policy()));
487   // Even though it's a different origin, it's the same domain.
488   EXPECT_FALSE(
489       removal_data.origin_matcher.Run(kTestOrigin3Secure, mock_policy()));
490 
491   EXPECT_FALSE(FilterMatchesCookie(removal_data.cookie_deletion_filter,
492                                    CreateCookieWithHost(kTestOrigin1)));
493   EXPECT_TRUE(FilterMatchesCookie(removal_data.cookie_deletion_filter,
494                                   CreateCookieWithHost(kTestOrigin2)));
495   EXPECT_FALSE(FilterMatchesCookie(removal_data.cookie_deletion_filter,
496                                    CreateCookieWithHost(kTestOrigin3)));
497   // This is false, because this is the same domain as 3, just with a different
498   // scheme.
499   EXPECT_FALSE(FilterMatchesCookie(removal_data.cookie_deletion_filter,
500                                    CreateCookieWithHost(kTestOrigin3Secure)));
501 }
502 
TEST_F(BrowsingDataRemoverImplTest,RemoveUnprotectedLocalStorageForever)503 TEST_F(BrowsingDataRemoverImplTest, RemoveUnprotectedLocalStorageForever) {
504   storage::MockSpecialStoragePolicy* policy = CreateMockPolicy();
505   // Protect the test origin.
506   const url::Origin kTestOrigin = url::Origin::Create(GURL("http://host1.com"));
507   policy->AddProtected(kTestOrigin.GetURL());
508 
509   BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(),
510                                 BrowsingDataRemover::DATA_TYPE_LOCAL_STORAGE,
511                                 false);
512 
513   EXPECT_EQ(BrowsingDataRemover::DATA_TYPE_LOCAL_STORAGE, GetRemovalMask());
514   EXPECT_EQ(BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
515             GetOriginTypeMask());
516 
517   // Verify that storage partition was instructed to remove the data correctly.
518   StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData();
519   EXPECT_EQ(removal_data.remove_mask,
520             StoragePartition::REMOVE_DATA_MASK_LOCAL_STORAGE);
521   EXPECT_EQ(removal_data.quota_storage_remove_mask,
522             StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL);
523   EXPECT_EQ(removal_data.remove_begin, GetBeginTime());
524 
525   // Check origin matcher.
526   EXPECT_FALSE(removal_data.origin_matcher.Run(kTestOrigin, mock_policy()));
527   EXPECT_TRUE(removal_data.origin_matcher.Run(
528       url::Origin::Create(GURL("http://host2.com")), mock_policy()));
529   EXPECT_TRUE(removal_data.origin_matcher.Run(
530       url::Origin::Create(GURL("http://host3.com")), mock_policy()));
531   EXPECT_FALSE(removal_data.origin_matcher.Run(
532       url::Origin::Create(
533           GURL("chrome-extension://abcdefghijklmnopqrstuvwxyz/")),
534       mock_policy()));
535 }
536 
TEST_F(BrowsingDataRemoverImplTest,RemoveProtectedLocalStorageForever)537 TEST_F(BrowsingDataRemoverImplTest, RemoveProtectedLocalStorageForever) {
538   // Protect the test origin.
539   storage::MockSpecialStoragePolicy* policy = CreateMockPolicy();
540   const url::Origin kTestOrigin = url::Origin::Create(GURL("http://host1.com"));
541   policy->AddProtected(kTestOrigin.GetURL());
542 
543   BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(),
544                                 BrowsingDataRemover::DATA_TYPE_LOCAL_STORAGE,
545                                 true);
546 
547   EXPECT_EQ(BrowsingDataRemover::DATA_TYPE_LOCAL_STORAGE, GetRemovalMask());
548   EXPECT_EQ(BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB |
549                 BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB,
550             GetOriginTypeMask());
551 
552   // Verify that storage partition was instructed to remove the data correctly.
553   StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData();
554   EXPECT_EQ(removal_data.remove_mask,
555             StoragePartition::REMOVE_DATA_MASK_LOCAL_STORAGE);
556   EXPECT_EQ(removal_data.quota_storage_remove_mask,
557             StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL);
558   EXPECT_EQ(removal_data.remove_begin, GetBeginTime());
559 
560   // Check origin matcher all http origin will match since we specified
561   // both protected and unprotected.
562   EXPECT_TRUE(removal_data.origin_matcher.Run(kTestOrigin, mock_policy()));
563   EXPECT_TRUE(removal_data.origin_matcher.Run(
564       url::Origin::Create(GURL("http://host2.com")), mock_policy()));
565   EXPECT_TRUE(removal_data.origin_matcher.Run(
566       url::Origin::Create(GURL("http://host3.com")), mock_policy()));
567   EXPECT_FALSE(removal_data.origin_matcher.Run(
568       url::Origin::Create(
569           GURL("chrome-extension://abcdefghijklmnopqrstuvwxyz/")),
570       mock_policy()));
571 }
572 
TEST_F(BrowsingDataRemoverImplTest,RemoveLocalStorageForLastWeek)573 TEST_F(BrowsingDataRemoverImplTest, RemoveLocalStorageForLastWeek) {
574   CreateMockPolicy();
575 
576   BlockUntilBrowsingDataRemoved(
577       base::Time::Now() - base::TimeDelta::FromDays(7), base::Time::Max(),
578       BrowsingDataRemover::DATA_TYPE_LOCAL_STORAGE, false);
579 
580   EXPECT_EQ(BrowsingDataRemover::DATA_TYPE_LOCAL_STORAGE, GetRemovalMask());
581   EXPECT_EQ(BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
582             GetOriginTypeMask());
583 
584   // Verify that storage partition was instructed to remove the data correctly.
585   StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData();
586   EXPECT_EQ(removal_data.remove_mask,
587             StoragePartition::REMOVE_DATA_MASK_LOCAL_STORAGE);
588   // Persistent storage won't be deleted.
589   EXPECT_EQ(removal_data.quota_storage_remove_mask,
590             ~StoragePartition::QUOTA_MANAGED_STORAGE_MASK_PERSISTENT);
591   EXPECT_EQ(removal_data.remove_begin, GetBeginTime());
592 
593   // Check origin matcher.
594   EXPECT_TRUE(removal_data.origin_matcher.Run(
595       url::Origin::Create(GURL("http://host1.com")), mock_policy()));
596   EXPECT_TRUE(removal_data.origin_matcher.Run(
597       url::Origin::Create(GURL("http://host2.com")), mock_policy()));
598   EXPECT_TRUE(removal_data.origin_matcher.Run(
599       url::Origin::Create(GURL("http://host3.com")), mock_policy()));
600   EXPECT_FALSE(removal_data.origin_matcher.Run(
601       url::Origin::Create(
602           GURL("chrome-extension://abcdefghijklmnopqrstuvwxyz/")),
603       mock_policy()));
604 }
605 
TEST_F(BrowsingDataRemoverImplTest,RemoveMultipleTypes)606 TEST_F(BrowsingDataRemoverImplTest, RemoveMultipleTypes) {
607   // Downloads should be deleted through the DownloadManager, assure it would
608   // be called.
609   RemoveDownloadsTester downloads_tester(GetBrowserContext());
610   EXPECT_CALL(*downloads_tester.download_manager(),
611               RemoveDownloadsByURLAndTime(_, _, _));
612 
613   int removal_mask = BrowsingDataRemover::DATA_TYPE_DOWNLOADS |
614                      BrowsingDataRemover::DATA_TYPE_COOKIES;
615 
616   BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), removal_mask,
617                                 false);
618 
619   EXPECT_EQ(removal_mask, GetRemovalMask());
620   EXPECT_EQ(BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
621             GetOriginTypeMask());
622 
623   // The cookie would be deleted throught the StorageParition, check if the
624   // partition was requested to remove cookie.
625   StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData();
626   EXPECT_EQ(removal_data.remove_mask,
627             StoragePartition::REMOVE_DATA_MASK_COOKIES);
628   EXPECT_EQ(removal_data.quota_storage_remove_mask,
629             StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL);
630 }
631 
TEST_F(BrowsingDataRemoverImplTest,RemoveQuotaManagedDataForeverBoth)632 TEST_F(BrowsingDataRemoverImplTest, RemoveQuotaManagedDataForeverBoth) {
633   BlockUntilBrowsingDataRemoved(
634       base::Time(), base::Time::Max(),
635       BrowsingDataRemover::DATA_TYPE_FILE_SYSTEMS |
636           BrowsingDataRemover::DATA_TYPE_WEB_SQL |
637           BrowsingDataRemover::DATA_TYPE_APP_CACHE |
638           BrowsingDataRemover::DATA_TYPE_SERVICE_WORKERS |
639           BrowsingDataRemover::DATA_TYPE_CACHE_STORAGE |
640           BrowsingDataRemover::DATA_TYPE_INDEXED_DB,
641       false);
642 
643   EXPECT_EQ(BrowsingDataRemover::DATA_TYPE_FILE_SYSTEMS |
644                 BrowsingDataRemover::DATA_TYPE_WEB_SQL |
645                 BrowsingDataRemover::DATA_TYPE_APP_CACHE |
646                 BrowsingDataRemover::DATA_TYPE_SERVICE_WORKERS |
647                 BrowsingDataRemover::DATA_TYPE_CACHE_STORAGE |
648                 BrowsingDataRemover::DATA_TYPE_INDEXED_DB,
649             GetRemovalMask());
650   EXPECT_EQ(BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
651             GetOriginTypeMask());
652 
653   // Verify storage partition related stuffs.
654   StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData();
655   EXPECT_EQ(removal_data.remove_mask,
656             StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS |
657                 StoragePartition::REMOVE_DATA_MASK_WEBSQL |
658                 StoragePartition::REMOVE_DATA_MASK_APPCACHE |
659                 StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS |
660                 StoragePartition::REMOVE_DATA_MASK_CACHE_STORAGE |
661                 StoragePartition::REMOVE_DATA_MASK_INDEXEDDB);
662   EXPECT_EQ(removal_data.quota_storage_remove_mask,
663             StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL);
664 }
665 
TEST_F(BrowsingDataRemoverImplTest,RemoveQuotaManagedDataForeverOnlyTemporary)666 TEST_F(BrowsingDataRemoverImplTest,
667        RemoveQuotaManagedDataForeverOnlyTemporary) {
668   CreateMockPolicy();
669 
670   BlockUntilBrowsingDataRemoved(
671       base::Time(), base::Time::Max(),
672       BrowsingDataRemover::DATA_TYPE_FILE_SYSTEMS |
673           BrowsingDataRemover::DATA_TYPE_WEB_SQL |
674           BrowsingDataRemover::DATA_TYPE_APP_CACHE |
675           BrowsingDataRemover::DATA_TYPE_SERVICE_WORKERS |
676           BrowsingDataRemover::DATA_TYPE_CACHE_STORAGE |
677           BrowsingDataRemover::DATA_TYPE_INDEXED_DB,
678       false);
679 
680   EXPECT_EQ(BrowsingDataRemover::DATA_TYPE_FILE_SYSTEMS |
681                 BrowsingDataRemover::DATA_TYPE_WEB_SQL |
682                 BrowsingDataRemover::DATA_TYPE_APP_CACHE |
683                 BrowsingDataRemover::DATA_TYPE_SERVICE_WORKERS |
684                 BrowsingDataRemover::DATA_TYPE_CACHE_STORAGE |
685                 BrowsingDataRemover::DATA_TYPE_INDEXED_DB,
686             GetRemovalMask());
687   EXPECT_EQ(BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
688             GetOriginTypeMask());
689 
690   // Verify storage partition related stuffs.
691   StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData();
692 
693   EXPECT_EQ(removal_data.remove_mask,
694             StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS |
695                 StoragePartition::REMOVE_DATA_MASK_WEBSQL |
696                 StoragePartition::REMOVE_DATA_MASK_APPCACHE |
697                 StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS |
698                 StoragePartition::REMOVE_DATA_MASK_CACHE_STORAGE |
699                 StoragePartition::REMOVE_DATA_MASK_INDEXEDDB);
700   EXPECT_EQ(removal_data.quota_storage_remove_mask,
701             StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL);
702 
703   // Check that all related origin data would be removed, that is, origin
704   // matcher would match these origin.
705   EXPECT_TRUE(removal_data.origin_matcher.Run(
706       url::Origin::Create(GURL("http://host1.com")), mock_policy()));
707   EXPECT_TRUE(removal_data.origin_matcher.Run(
708       url::Origin::Create(GURL("http://host2.com")), mock_policy()));
709   EXPECT_TRUE(removal_data.origin_matcher.Run(
710       url::Origin::Create(GURL("http://host3.com")), mock_policy()));
711 }
712 
TEST_F(BrowsingDataRemoverImplTest,RemoveQuotaManagedDataForeverOnlyPersistent)713 TEST_F(BrowsingDataRemoverImplTest,
714        RemoveQuotaManagedDataForeverOnlyPersistent) {
715   CreateMockPolicy();
716 
717   BlockUntilBrowsingDataRemoved(
718       base::Time(), base::Time::Max(),
719       BrowsingDataRemover::DATA_TYPE_FILE_SYSTEMS |
720           BrowsingDataRemover::DATA_TYPE_WEB_SQL |
721           BrowsingDataRemover::DATA_TYPE_APP_CACHE |
722           BrowsingDataRemover::DATA_TYPE_SERVICE_WORKERS |
723           BrowsingDataRemover::DATA_TYPE_CACHE_STORAGE |
724           BrowsingDataRemover::DATA_TYPE_INDEXED_DB,
725       false);
726 
727   EXPECT_EQ(BrowsingDataRemover::DATA_TYPE_FILE_SYSTEMS |
728                 BrowsingDataRemover::DATA_TYPE_WEB_SQL |
729                 BrowsingDataRemover::DATA_TYPE_APP_CACHE |
730                 BrowsingDataRemover::DATA_TYPE_SERVICE_WORKERS |
731                 BrowsingDataRemover::DATA_TYPE_CACHE_STORAGE |
732                 BrowsingDataRemover::DATA_TYPE_INDEXED_DB,
733             GetRemovalMask());
734   EXPECT_EQ(BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
735             GetOriginTypeMask());
736 
737   // Verify storage partition related stuffs.
738   StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData();
739 
740   EXPECT_EQ(removal_data.remove_mask,
741             StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS |
742                 StoragePartition::REMOVE_DATA_MASK_WEBSQL |
743                 StoragePartition::REMOVE_DATA_MASK_APPCACHE |
744                 StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS |
745                 StoragePartition::REMOVE_DATA_MASK_CACHE_STORAGE |
746                 StoragePartition::REMOVE_DATA_MASK_INDEXEDDB);
747   EXPECT_EQ(removal_data.quota_storage_remove_mask,
748             StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL);
749 
750   // Check that all related origin data would be removed, that is, origin
751   // matcher would match these origin.
752   EXPECT_TRUE(removal_data.origin_matcher.Run(
753       url::Origin::Create(GURL("http://host1.com")), mock_policy()));
754   EXPECT_TRUE(removal_data.origin_matcher.Run(
755       url::Origin::Create(GURL("http://host2.com")), mock_policy()));
756   EXPECT_TRUE(removal_data.origin_matcher.Run(
757       url::Origin::Create(GURL("http://host3.com")), mock_policy()));
758 }
759 
TEST_F(BrowsingDataRemoverImplTest,RemoveQuotaManagedDataForeverNeither)760 TEST_F(BrowsingDataRemoverImplTest, RemoveQuotaManagedDataForeverNeither) {
761   CreateMockPolicy();
762 
763   BlockUntilBrowsingDataRemoved(
764       base::Time(), base::Time::Max(),
765       BrowsingDataRemover::DATA_TYPE_FILE_SYSTEMS |
766           BrowsingDataRemover::DATA_TYPE_WEB_SQL |
767           BrowsingDataRemover::DATA_TYPE_APP_CACHE |
768           BrowsingDataRemover::DATA_TYPE_SERVICE_WORKERS |
769           BrowsingDataRemover::DATA_TYPE_CACHE_STORAGE |
770           BrowsingDataRemover::DATA_TYPE_INDEXED_DB,
771       false);
772 
773   EXPECT_EQ(BrowsingDataRemover::DATA_TYPE_FILE_SYSTEMS |
774                 BrowsingDataRemover::DATA_TYPE_WEB_SQL |
775                 BrowsingDataRemover::DATA_TYPE_APP_CACHE |
776                 BrowsingDataRemover::DATA_TYPE_SERVICE_WORKERS |
777                 BrowsingDataRemover::DATA_TYPE_CACHE_STORAGE |
778                 BrowsingDataRemover::DATA_TYPE_INDEXED_DB,
779             GetRemovalMask());
780   EXPECT_EQ(BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
781             GetOriginTypeMask());
782 
783   // Verify storage partition related stuffs.
784   StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData();
785 
786   EXPECT_EQ(removal_data.remove_mask,
787             StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS |
788                 StoragePartition::REMOVE_DATA_MASK_WEBSQL |
789                 StoragePartition::REMOVE_DATA_MASK_APPCACHE |
790                 StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS |
791                 StoragePartition::REMOVE_DATA_MASK_CACHE_STORAGE |
792                 StoragePartition::REMOVE_DATA_MASK_INDEXEDDB);
793   EXPECT_EQ(removal_data.quota_storage_remove_mask,
794             StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL);
795 
796   // Check that all related origin data would be removed, that is, origin
797   // matcher would match these origin.
798   EXPECT_TRUE(removal_data.origin_matcher.Run(
799       url::Origin::Create(GURL("http://host1.com")), mock_policy()));
800   EXPECT_TRUE(removal_data.origin_matcher.Run(
801       url::Origin::Create(GURL("http://host2.com")), mock_policy()));
802   EXPECT_TRUE(removal_data.origin_matcher.Run(
803       url::Origin::Create(GURL("http://host3.com")), mock_policy()));
804 }
805 
TEST_F(BrowsingDataRemoverImplTest,RemoveQuotaManagedDataForeverSpecificOrigin)806 TEST_F(BrowsingDataRemoverImplTest,
807        RemoveQuotaManagedDataForeverSpecificOrigin) {
808   std::unique_ptr<BrowsingDataFilterBuilder> builder(
809       BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::WHITELIST));
810   const GURL kTestUrl("http://host1.com");
811   builder->AddRegisterableDomain(kTestUrl.host());
812   // Remove the test origin.
813   BlockUntilOriginDataRemoved(
814       base::Time(), base::Time::Max(),
815       BrowsingDataRemover::DATA_TYPE_APP_CACHE |
816           BrowsingDataRemover::DATA_TYPE_SERVICE_WORKERS |
817           BrowsingDataRemover::DATA_TYPE_CACHE_STORAGE |
818           BrowsingDataRemover::DATA_TYPE_FILE_SYSTEMS |
819           BrowsingDataRemover::DATA_TYPE_INDEXED_DB |
820           BrowsingDataRemover::DATA_TYPE_WEB_SQL,
821       std::move(builder));
822 
823   EXPECT_EQ(BrowsingDataRemover::DATA_TYPE_APP_CACHE |
824                 BrowsingDataRemover::DATA_TYPE_SERVICE_WORKERS |
825                 BrowsingDataRemover::DATA_TYPE_CACHE_STORAGE |
826                 BrowsingDataRemover::DATA_TYPE_FILE_SYSTEMS |
827                 BrowsingDataRemover::DATA_TYPE_INDEXED_DB |
828                 BrowsingDataRemover::DATA_TYPE_WEB_SQL,
829             GetRemovalMask());
830   EXPECT_EQ(BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
831             GetOriginTypeMask());
832 
833   // Verify storage partition related stuffs.
834   StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData();
835 
836   EXPECT_EQ(removal_data.remove_mask,
837             StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS |
838                 StoragePartition::REMOVE_DATA_MASK_WEBSQL |
839                 StoragePartition::REMOVE_DATA_MASK_APPCACHE |
840                 StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS |
841                 StoragePartition::REMOVE_DATA_MASK_CACHE_STORAGE |
842                 StoragePartition::REMOVE_DATA_MASK_INDEXEDDB);
843   EXPECT_EQ(removal_data.quota_storage_remove_mask,
844             StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL);
845   EXPECT_TRUE(removal_data.origin_matcher.Run(url::Origin::Create(kTestUrl),
846                                               mock_policy()));
847   EXPECT_FALSE(removal_data.origin_matcher.Run(
848       url::Origin::Create(GURL("http://host2.com")), mock_policy()));
849   EXPECT_FALSE(removal_data.origin_matcher.Run(
850       url::Origin::Create(GURL("http://host3.com")), mock_policy()));
851   EXPECT_FALSE(removal_data.origin_matcher.Run(
852       url::Origin::Create(GURL("https://host3.com")), mock_policy()));
853 }
854 
TEST_F(BrowsingDataRemoverImplTest,RemoveQuotaManagedDataForLastHour)855 TEST_F(BrowsingDataRemoverImplTest, RemoveQuotaManagedDataForLastHour) {
856   BlockUntilBrowsingDataRemoved(
857       AnHourAgo(), base::Time::Max(),
858       BrowsingDataRemover::DATA_TYPE_FILE_SYSTEMS |
859           BrowsingDataRemover::DATA_TYPE_WEB_SQL |
860           BrowsingDataRemover::DATA_TYPE_APP_CACHE |
861           BrowsingDataRemover::DATA_TYPE_SERVICE_WORKERS |
862           BrowsingDataRemover::DATA_TYPE_CACHE_STORAGE |
863           BrowsingDataRemover::DATA_TYPE_INDEXED_DB,
864       false);
865 
866   EXPECT_EQ(BrowsingDataRemover::DATA_TYPE_FILE_SYSTEMS |
867                 BrowsingDataRemover::DATA_TYPE_WEB_SQL |
868                 BrowsingDataRemover::DATA_TYPE_APP_CACHE |
869                 BrowsingDataRemover::DATA_TYPE_SERVICE_WORKERS |
870                 BrowsingDataRemover::DATA_TYPE_CACHE_STORAGE |
871                 BrowsingDataRemover::DATA_TYPE_INDEXED_DB,
872             GetRemovalMask());
873   EXPECT_EQ(BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
874             GetOriginTypeMask());
875 
876   // Verify storage partition related stuffs.
877   StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData();
878 
879   EXPECT_EQ(removal_data.remove_mask,
880             StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS |
881                 StoragePartition::REMOVE_DATA_MASK_WEBSQL |
882                 StoragePartition::REMOVE_DATA_MASK_APPCACHE |
883                 StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS |
884                 StoragePartition::REMOVE_DATA_MASK_CACHE_STORAGE |
885                 StoragePartition::REMOVE_DATA_MASK_INDEXEDDB);
886 
887   // Persistent data would be left out since we are not removing from
888   // beginning of time.
889   uint32_t expected_quota_mask =
890       ~StoragePartition::QUOTA_MANAGED_STORAGE_MASK_PERSISTENT;
891   EXPECT_EQ(removal_data.quota_storage_remove_mask, expected_quota_mask);
892   // Check removal begin time.
893   EXPECT_EQ(removal_data.remove_begin, GetBeginTime());
894 }
895 
TEST_F(BrowsingDataRemoverImplTest,RemoveQuotaManagedDataForLastWeek)896 TEST_F(BrowsingDataRemoverImplTest, RemoveQuotaManagedDataForLastWeek) {
897   BlockUntilBrowsingDataRemoved(
898       base::Time::Now() - base::TimeDelta::FromDays(7), base::Time::Max(),
899       BrowsingDataRemover::DATA_TYPE_FILE_SYSTEMS |
900           BrowsingDataRemover::DATA_TYPE_WEB_SQL |
901           BrowsingDataRemover::DATA_TYPE_APP_CACHE |
902           BrowsingDataRemover::DATA_TYPE_SERVICE_WORKERS |
903           BrowsingDataRemover::DATA_TYPE_CACHE_STORAGE |
904           BrowsingDataRemover::DATA_TYPE_INDEXED_DB,
905       false);
906 
907   EXPECT_EQ(BrowsingDataRemover::DATA_TYPE_FILE_SYSTEMS |
908                 BrowsingDataRemover::DATA_TYPE_WEB_SQL |
909                 BrowsingDataRemover::DATA_TYPE_APP_CACHE |
910                 BrowsingDataRemover::DATA_TYPE_SERVICE_WORKERS |
911                 BrowsingDataRemover::DATA_TYPE_CACHE_STORAGE |
912                 BrowsingDataRemover::DATA_TYPE_INDEXED_DB,
913             GetRemovalMask());
914   EXPECT_EQ(BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
915             GetOriginTypeMask());
916 
917   // Verify storage partition related stuffs.
918   StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData();
919 
920   EXPECT_EQ(removal_data.remove_mask,
921             StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS |
922                 StoragePartition::REMOVE_DATA_MASK_WEBSQL |
923                 StoragePartition::REMOVE_DATA_MASK_APPCACHE |
924                 StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS |
925                 StoragePartition::REMOVE_DATA_MASK_CACHE_STORAGE |
926                 StoragePartition::REMOVE_DATA_MASK_INDEXEDDB);
927 
928   // Persistent data would be left out since we are not removing from
929   // beginning of time.
930   uint32_t expected_quota_mask =
931       ~StoragePartition::QUOTA_MANAGED_STORAGE_MASK_PERSISTENT;
932   EXPECT_EQ(removal_data.quota_storage_remove_mask, expected_quota_mask);
933   // Check removal begin time.
934   EXPECT_EQ(removal_data.remove_begin, GetBeginTime());
935 }
936 
TEST_F(BrowsingDataRemoverImplTest,RemoveQuotaManagedUnprotectedOrigins)937 TEST_F(BrowsingDataRemoverImplTest, RemoveQuotaManagedUnprotectedOrigins) {
938   storage::MockSpecialStoragePolicy* policy = CreateMockPolicy();
939   // Protect the test origin.
940   const url::Origin kTestOrigin = url::Origin::Create(GURL("http://host1.com"));
941   policy->AddProtected(kTestOrigin.GetURL());
942 
943   BlockUntilBrowsingDataRemoved(
944       base::Time(), base::Time::Max(),
945       BrowsingDataRemover::DATA_TYPE_FILE_SYSTEMS |
946           BrowsingDataRemover::DATA_TYPE_WEB_SQL |
947           BrowsingDataRemover::DATA_TYPE_APP_CACHE |
948           BrowsingDataRemover::DATA_TYPE_SERVICE_WORKERS |
949           BrowsingDataRemover::DATA_TYPE_CACHE_STORAGE |
950           BrowsingDataRemover::DATA_TYPE_INDEXED_DB,
951       false);
952 
953   EXPECT_EQ(BrowsingDataRemover::DATA_TYPE_FILE_SYSTEMS |
954                 BrowsingDataRemover::DATA_TYPE_WEB_SQL |
955                 BrowsingDataRemover::DATA_TYPE_APP_CACHE |
956                 BrowsingDataRemover::DATA_TYPE_SERVICE_WORKERS |
957                 BrowsingDataRemover::DATA_TYPE_CACHE_STORAGE |
958                 BrowsingDataRemover::DATA_TYPE_INDEXED_DB,
959             GetRemovalMask());
960   EXPECT_EQ(BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
961             GetOriginTypeMask());
962 
963   // Verify storage partition related stuffs.
964   StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData();
965 
966   EXPECT_EQ(removal_data.remove_mask,
967             StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS |
968                 StoragePartition::REMOVE_DATA_MASK_WEBSQL |
969                 StoragePartition::REMOVE_DATA_MASK_APPCACHE |
970                 StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS |
971                 StoragePartition::REMOVE_DATA_MASK_CACHE_STORAGE |
972                 StoragePartition::REMOVE_DATA_MASK_INDEXEDDB);
973   EXPECT_EQ(removal_data.quota_storage_remove_mask,
974             StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL);
975 
976   // Check OriginMatcherFunction.
977   EXPECT_FALSE(removal_data.origin_matcher.Run(kTestOrigin, mock_policy()));
978   EXPECT_TRUE(removal_data.origin_matcher.Run(
979       url::Origin::Create(GURL("http://host2.com")), mock_policy()));
980   EXPECT_TRUE(removal_data.origin_matcher.Run(
981       url::Origin::Create(GURL("http://host3.com")), mock_policy()));
982 }
983 
TEST_F(BrowsingDataRemoverImplTest,RemoveQuotaManagedProtectedSpecificOrigin)984 TEST_F(BrowsingDataRemoverImplTest, RemoveQuotaManagedProtectedSpecificOrigin) {
985   storage::MockSpecialStoragePolicy* policy = CreateMockPolicy();
986   // Protect the test origin.
987   const GURL kTestUrl("http://host1.com");
988   policy->AddProtected(kTestUrl);
989 
990   std::unique_ptr<BrowsingDataFilterBuilder> builder(
991       BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::WHITELIST));
992   builder->AddRegisterableDomain(kTestUrl.host());
993 
994   // Try to remove the test origin. Expect failure.
995   BlockUntilOriginDataRemoved(
996       base::Time(), base::Time::Max(),
997       BrowsingDataRemover::DATA_TYPE_APP_CACHE |
998           BrowsingDataRemover::DATA_TYPE_SERVICE_WORKERS |
999           BrowsingDataRemover::DATA_TYPE_CACHE_STORAGE |
1000           BrowsingDataRemover::DATA_TYPE_FILE_SYSTEMS |
1001           BrowsingDataRemover::DATA_TYPE_INDEXED_DB |
1002           BrowsingDataRemover::DATA_TYPE_WEB_SQL,
1003       std::move(builder));
1004 
1005   EXPECT_EQ(BrowsingDataRemover::DATA_TYPE_APP_CACHE |
1006                 BrowsingDataRemover::DATA_TYPE_SERVICE_WORKERS |
1007                 BrowsingDataRemover::DATA_TYPE_CACHE_STORAGE |
1008                 BrowsingDataRemover::DATA_TYPE_FILE_SYSTEMS |
1009                 BrowsingDataRemover::DATA_TYPE_INDEXED_DB |
1010                 BrowsingDataRemover::DATA_TYPE_WEB_SQL,
1011             GetRemovalMask());
1012   EXPECT_EQ(BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
1013             GetOriginTypeMask());
1014 
1015   // Verify storage partition related stuffs.
1016   StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData();
1017 
1018   EXPECT_EQ(removal_data.remove_mask,
1019             StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS |
1020                 StoragePartition::REMOVE_DATA_MASK_WEBSQL |
1021                 StoragePartition::REMOVE_DATA_MASK_APPCACHE |
1022                 StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS |
1023                 StoragePartition::REMOVE_DATA_MASK_CACHE_STORAGE |
1024                 StoragePartition::REMOVE_DATA_MASK_INDEXEDDB);
1025   EXPECT_EQ(removal_data.quota_storage_remove_mask,
1026             StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL);
1027 
1028   // Check OriginMatcherFunction.
1029   EXPECT_FALSE(removal_data.origin_matcher.Run(url::Origin::Create(kTestUrl),
1030                                                mock_policy()));
1031   // Since we use the matcher function to validate origins now, this should
1032   // return false for the origins we're not trying to clear.
1033   EXPECT_FALSE(removal_data.origin_matcher.Run(
1034       url::Origin::Create(GURL("http://host2.com")), mock_policy()));
1035   EXPECT_FALSE(removal_data.origin_matcher.Run(
1036       url::Origin::Create(GURL("http://host3.com")), mock_policy()));
1037 }
1038 
TEST_F(BrowsingDataRemoverImplTest,RemoveQuotaManagedProtectedOrigins)1039 TEST_F(BrowsingDataRemoverImplTest, RemoveQuotaManagedProtectedOrigins) {
1040   storage::MockSpecialStoragePolicy* policy = CreateMockPolicy();
1041   // Protect the test origin.
1042   const url::Origin kTestOrigin = url::Origin::Create(GURL("http://host1.com"));
1043   policy->AddProtected(kTestOrigin.GetURL());
1044 
1045   // Try to remove the test origin. Expect success.
1046   BlockUntilBrowsingDataRemoved(
1047       base::Time(), base::Time::Max(),
1048       BrowsingDataRemover::DATA_TYPE_APP_CACHE |
1049           BrowsingDataRemover::DATA_TYPE_SERVICE_WORKERS |
1050           BrowsingDataRemover::DATA_TYPE_CACHE_STORAGE |
1051           BrowsingDataRemover::DATA_TYPE_FILE_SYSTEMS |
1052           BrowsingDataRemover::DATA_TYPE_INDEXED_DB |
1053           BrowsingDataRemover::DATA_TYPE_WEB_SQL,
1054       true);
1055 
1056   EXPECT_EQ(BrowsingDataRemover::DATA_TYPE_APP_CACHE |
1057                 BrowsingDataRemover::DATA_TYPE_SERVICE_WORKERS |
1058                 BrowsingDataRemover::DATA_TYPE_CACHE_STORAGE |
1059                 BrowsingDataRemover::DATA_TYPE_FILE_SYSTEMS |
1060                 BrowsingDataRemover::DATA_TYPE_INDEXED_DB |
1061                 BrowsingDataRemover::DATA_TYPE_WEB_SQL,
1062             GetRemovalMask());
1063   EXPECT_EQ(BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB |
1064                 BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
1065             GetOriginTypeMask());
1066 
1067   // Verify storage partition related stuffs.
1068   StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData();
1069 
1070   EXPECT_EQ(removal_data.remove_mask,
1071             StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS |
1072                 StoragePartition::REMOVE_DATA_MASK_WEBSQL |
1073                 StoragePartition::REMOVE_DATA_MASK_APPCACHE |
1074                 StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS |
1075                 StoragePartition::REMOVE_DATA_MASK_CACHE_STORAGE |
1076                 StoragePartition::REMOVE_DATA_MASK_INDEXEDDB);
1077   EXPECT_EQ(removal_data.quota_storage_remove_mask,
1078             StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL);
1079 
1080   // Check OriginMatcherFunction, |kTestOrigin| would match mask since we
1081   // would have 'protected' specified in origin_type_mask.
1082   EXPECT_TRUE(removal_data.origin_matcher.Run(kTestOrigin, mock_policy()));
1083   EXPECT_TRUE(removal_data.origin_matcher.Run(
1084       url::Origin::Create(GURL("http://host2.com")), mock_policy()));
1085   EXPECT_TRUE(removal_data.origin_matcher.Run(
1086       url::Origin::Create(GURL("http://host3.com")), mock_policy()));
1087 }
1088 
TEST_F(BrowsingDataRemoverImplTest,RemoveQuotaManagedIgnoreExtensionsAndDevTools)1089 TEST_F(BrowsingDataRemoverImplTest,
1090        RemoveQuotaManagedIgnoreExtensionsAndDevTools) {
1091   CreateMockPolicy();
1092 
1093   BlockUntilBrowsingDataRemoved(
1094       base::Time(), base::Time::Max(),
1095       BrowsingDataRemover::DATA_TYPE_APP_CACHE |
1096           BrowsingDataRemover::DATA_TYPE_SERVICE_WORKERS |
1097           BrowsingDataRemover::DATA_TYPE_CACHE_STORAGE |
1098           BrowsingDataRemover::DATA_TYPE_FILE_SYSTEMS |
1099           BrowsingDataRemover::DATA_TYPE_INDEXED_DB |
1100           BrowsingDataRemover::DATA_TYPE_WEB_SQL,
1101       false);
1102 
1103   EXPECT_EQ(BrowsingDataRemover::DATA_TYPE_APP_CACHE |
1104                 BrowsingDataRemover::DATA_TYPE_SERVICE_WORKERS |
1105                 BrowsingDataRemover::DATA_TYPE_CACHE_STORAGE |
1106                 BrowsingDataRemover::DATA_TYPE_FILE_SYSTEMS |
1107                 BrowsingDataRemover::DATA_TYPE_INDEXED_DB |
1108                 BrowsingDataRemover::DATA_TYPE_WEB_SQL,
1109             GetRemovalMask());
1110   EXPECT_EQ(BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
1111             GetOriginTypeMask());
1112 
1113   // Verify storage partition related stuffs.
1114   StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData();
1115 
1116   EXPECT_EQ(removal_data.remove_mask,
1117             StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS |
1118                 StoragePartition::REMOVE_DATA_MASK_WEBSQL |
1119                 StoragePartition::REMOVE_DATA_MASK_APPCACHE |
1120                 StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS |
1121                 StoragePartition::REMOVE_DATA_MASK_CACHE_STORAGE |
1122                 StoragePartition::REMOVE_DATA_MASK_INDEXEDDB);
1123   EXPECT_EQ(removal_data.quota_storage_remove_mask,
1124             StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL);
1125 
1126   // Check that extension and devtools data wouldn't be removed, that is,
1127   // origin matcher would not match these origin.
1128   EXPECT_FALSE(removal_data.origin_matcher.Run(
1129       url::Origin::Create(
1130           GURL("chrome-extension://abcdefghijklmnopqrstuvwxyz/")),
1131       mock_policy()));
1132   EXPECT_FALSE(removal_data.origin_matcher.Run(
1133       url::Origin::Create(GURL("devtools://abcdefghijklmnopqrstuvw/")),
1134       mock_policy()));
1135 }
1136 
1137 class InspectableCompletionObserver
1138     : public BrowsingDataRemoverCompletionObserver {
1139  public:
InspectableCompletionObserver(BrowsingDataRemover * remover)1140   explicit InspectableCompletionObserver(BrowsingDataRemover* remover)
1141       : BrowsingDataRemoverCompletionObserver(remover) {}
1142   ~InspectableCompletionObserver() override = default;
1143 
called()1144   bool called() { return called_; }
1145 
1146  protected:
OnBrowsingDataRemoverDone()1147   void OnBrowsingDataRemoverDone() override {
1148     BrowsingDataRemoverCompletionObserver::OnBrowsingDataRemoverDone();
1149     called_ = true;
1150   }
1151 
1152  private:
1153   bool called_ = false;
1154 };
1155 
TEST_F(BrowsingDataRemoverImplTest,CompletionInhibition)1156 TEST_F(BrowsingDataRemoverImplTest, CompletionInhibition) {
1157   BrowsingDataRemoverImpl* remover = static_cast<BrowsingDataRemoverImpl*>(
1158       BrowserContext::GetBrowsingDataRemover(GetBrowserContext()));
1159 
1160   // The |completion_inhibitor| on the stack should prevent removal sessions
1161   // from completing until after ContinueToCompletion() is called.
1162   BrowsingDataRemoverCompletionInhibitor completion_inhibitor(remover);
1163   InspectableCompletionObserver completion_observer(remover);
1164   remover->RemoveAndReply(
1165       base::Time(), base::Time::Max(), BrowsingDataRemover::DATA_TYPE_COOKIES,
1166       BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB, &completion_observer);
1167 
1168   // Process messages until the inhibitor is notified, and then some, to make
1169   // sure we do not complete asynchronously before ContinueToCompletion() is
1170   // called.
1171   completion_inhibitor.BlockUntilNearCompletion();
1172   RunAllTasksUntilIdle();
1173 
1174   // Verify that the removal has not yet been completed and the observer has
1175   // not been called.
1176   EXPECT_TRUE(remover->IsRemovingForTesting());
1177   EXPECT_FALSE(completion_observer.called());
1178 
1179   // Now run the removal process until completion, and verify that observers are
1180   // now notified, and the notifications is sent out.
1181   completion_inhibitor.ContinueToCompletion();
1182   completion_observer.BlockUntilCompletion();
1183 
1184   EXPECT_FALSE(remover->IsRemovingForTesting());
1185   EXPECT_TRUE(completion_observer.called());
1186 }
1187 
TEST_F(BrowsingDataRemoverImplTest,EarlyShutdown)1188 TEST_F(BrowsingDataRemoverImplTest, EarlyShutdown) {
1189   BrowsingDataRemoverImpl* remover = static_cast<BrowsingDataRemoverImpl*>(
1190       BrowserContext::GetBrowsingDataRemover(GetBrowserContext()));
1191   InspectableCompletionObserver completion_observer(remover);
1192   BrowsingDataRemoverCompletionInhibitor completion_inhibitor(remover);
1193   remover->RemoveAndReply(
1194       base::Time(), base::Time::Max(), BrowsingDataRemover::DATA_TYPE_COOKIES,
1195       BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB, &completion_observer);
1196 
1197   completion_inhibitor.BlockUntilNearCompletion();
1198   completion_inhibitor.Reset();
1199 
1200   // Verify that the deletion has not yet been completed and the observer has
1201   // not been called.
1202   EXPECT_TRUE(remover->IsRemovingForTesting());
1203   EXPECT_FALSE(completion_observer.called());
1204 
1205   // Destroying the profile should trigger the notification.
1206   DestroyBrowserContext();
1207 
1208   EXPECT_TRUE(completion_observer.called());
1209 
1210   // Finishing after shutdown shouldn't break anything.
1211   completion_inhibitor.ContinueToCompletion();
1212   completion_observer.BlockUntilCompletion();
1213 }
1214 
TEST_F(BrowsingDataRemoverImplTest,RemoveDownloadsByTimeOnly)1215 TEST_F(BrowsingDataRemoverImplTest, RemoveDownloadsByTimeOnly) {
1216   RemoveDownloadsTester tester(GetBrowserContext());
1217   base::RepeatingCallback<bool(const GURL&)> filter =
1218       BrowsingDataFilterBuilder::BuildNoopFilter();
1219 
1220   EXPECT_CALL(*tester.download_manager(),
1221               RemoveDownloadsByURLAndTime(ProbablySameFilter(filter), _, _));
1222 
1223   BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(),
1224                                 BrowsingDataRemover::DATA_TYPE_DOWNLOADS,
1225                                 false);
1226 }
1227 
TEST_F(BrowsingDataRemoverImplTest,RemoveDownloadsByOrigin)1228 TEST_F(BrowsingDataRemoverImplTest, RemoveDownloadsByOrigin) {
1229   RemoveDownloadsTester tester(GetBrowserContext());
1230   std::unique_ptr<BrowsingDataFilterBuilder> builder(
1231       BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::WHITELIST));
1232   builder->AddRegisterableDomain("host1.com");
1233   base::RepeatingCallback<bool(const GURL&)> filter =
1234       builder->BuildGeneralFilter();
1235 
1236   EXPECT_CALL(*tester.download_manager(),
1237               RemoveDownloadsByURLAndTime(ProbablySameFilter(filter), _, _));
1238 
1239   BlockUntilOriginDataRemoved(base::Time(), base::Time::Max(),
1240                               BrowsingDataRemover::DATA_TYPE_DOWNLOADS,
1241                               std::move(builder));
1242 }
1243 
TEST_F(BrowsingDataRemoverImplTest,RemoveCodeCache)1244 TEST_F(BrowsingDataRemoverImplTest, RemoveCodeCache) {
1245   RemoveDownloadsTester tester(GetBrowserContext());
1246 
1247   BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(),
1248                                 BrowsingDataRemover::DATA_TYPE_CACHE, false);
1249   StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData();
1250   EXPECT_TRUE(removal_data.remove_code_cache);
1251 }
1252 
TEST_F(BrowsingDataRemoverImplTest,RemoveShaderCache)1253 TEST_F(BrowsingDataRemoverImplTest, RemoveShaderCache) {
1254   BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(),
1255                                 BrowsingDataRemover::DATA_TYPE_CACHE, false);
1256   StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData();
1257   EXPECT_EQ(removal_data.remove_mask,
1258             StoragePartition::REMOVE_DATA_MASK_SHADER_CACHE);
1259 }
1260 
1261 class MultipleTasksObserver {
1262  public:
1263   // A simple implementation of BrowsingDataRemover::Observer.
1264   // MultipleTasksObserver will use several instances of Target to test
1265   // that completion callbacks are returned to the correct one.
1266   class Target : public BrowsingDataRemover::Observer {
1267    public:
Target(MultipleTasksObserver * parent,BrowsingDataRemover * remover)1268     Target(MultipleTasksObserver* parent, BrowsingDataRemover* remover)
1269         : parent_(parent), observer_(this) {
1270       observer_.Add(remover);
1271     }
1272     ~Target() override = default;
1273 
OnBrowsingDataRemoverDone()1274     void OnBrowsingDataRemoverDone() override {
1275       parent_->last_called_targets_.push_back(this);
1276     }
1277 
1278    private:
1279     MultipleTasksObserver* parent_;
1280     ScopedObserver<BrowsingDataRemover, BrowsingDataRemover::Observer>
1281         observer_;
1282   };
1283 
MultipleTasksObserver(BrowsingDataRemover * remover)1284   explicit MultipleTasksObserver(BrowsingDataRemover* remover)
1285       : target_a_(this, remover), target_b_(this, remover) {}
1286   ~MultipleTasksObserver() = default;
1287 
ClearLastCalledTarget()1288   void ClearLastCalledTarget() { last_called_targets_.clear(); }
1289 
GetLastCalledTargets()1290   const std::vector<BrowsingDataRemover::Observer*> GetLastCalledTargets() {
1291     return last_called_targets_;
1292   }
1293 
target_a()1294   Target* target_a() { return &target_a_; }
target_b()1295   Target* target_b() { return &target_b_; }
1296 
1297  private:
1298   Target target_a_;
1299   Target target_b_;
1300   std::vector<BrowsingDataRemover::Observer*> last_called_targets_;
1301 };
1302 
TEST_F(BrowsingDataRemoverImplTest,MultipleTasks)1303 TEST_F(BrowsingDataRemoverImplTest, MultipleTasks) {
1304   BrowsingDataRemoverImpl* remover = static_cast<BrowsingDataRemoverImpl*>(
1305       BrowserContext::GetBrowsingDataRemover(GetBrowserContext()));
1306   EXPECT_FALSE(remover->IsRemovingForTesting());
1307 
1308   std::unique_ptr<BrowsingDataFilterBuilder> filter_builder_1(
1309       BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::WHITELIST));
1310   std::unique_ptr<BrowsingDataFilterBuilder> filter_builder_2(
1311       BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::BLACKLIST));
1312   filter_builder_2->AddRegisterableDomain("example.com");
1313 
1314   MultipleTasksObserver observer(remover);
1315   BrowsingDataRemoverCompletionInhibitor completion_inhibitor(remover);
1316 
1317   // Test several tasks with various configuration of masks, filters, and target
1318   // observers.
1319   std::list<BrowsingDataRemoverImpl::RemovalTask> tasks;
1320   tasks.emplace_back(
1321       base::Time(), base::Time::Max(), BrowsingDataRemover::DATA_TYPE_DOWNLOADS,
1322       BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
1323       BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::BLACKLIST),
1324       observer.target_a());
1325   tasks.emplace_back(
1326       base::Time(), base::Time::Max(), BrowsingDataRemover::DATA_TYPE_COOKIES,
1327       BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB,
1328       BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::BLACKLIST),
1329       nullptr);
1330   tasks.emplace_back(
1331       base::Time::Now(), base::Time::Max(),
1332       BrowsingDataRemover::DATA_TYPE_DOWNLOADS,
1333       BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB |
1334           BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB,
1335       BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::BLACKLIST),
1336       observer.target_b());
1337   tasks.emplace_back(base::Time(), base::Time::UnixEpoch(),
1338                      BrowsingDataRemover::DATA_TYPE_WEB_SQL,
1339                      BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
1340                      std::move(filter_builder_1), observer.target_b());
1341 
1342   for (BrowsingDataRemoverImpl::RemovalTask& task : tasks) {
1343     // All tasks can be directly translated to a RemoveInternal() call. Since
1344     // that is a private method, we must call the four public versions of
1345     // Remove.* instead. This also serves as a test that those methods are all
1346     // correctly reduced to RemoveInternal().
1347     if (task.observers.empty() && task.filter_builder->IsEmptyBlacklist()) {
1348       remover->Remove(task.delete_begin, task.delete_end, task.remove_mask,
1349                       task.origin_type_mask);
1350     } else if (task.filter_builder->IsEmptyBlacklist()) {
1351       remover->RemoveAndReply(task.delete_begin, task.delete_end,
1352                               task.remove_mask, task.origin_type_mask,
1353                               task.observers[0]);
1354     } else {
1355       remover->RemoveWithFilterAndReply(task.delete_begin, task.delete_end,
1356                                         task.remove_mask, task.origin_type_mask,
1357                                         std::move(task.filter_builder),
1358                                         task.observers[0]);
1359     }
1360   }
1361 
1362   // Use the inhibitor to stop after every task and check the results.
1363   for (BrowsingDataRemoverImpl::RemovalTask& task : tasks) {
1364     EXPECT_TRUE(remover->IsRemovingForTesting());
1365     observer.ClearLastCalledTarget();
1366 
1367     // Finish the task execution synchronously.
1368     completion_inhibitor.BlockUntilNearCompletion();
1369     completion_inhibitor.ContinueToCompletion();
1370 
1371     // Observers, if any, should have been called by now (since we call
1372     // observers on the same thread).
1373     EXPECT_EQ(task.observers, observer.GetLastCalledTargets());
1374 
1375     // TODO(msramek): If BrowsingDataRemover took ownership of the last used
1376     // filter builder and exposed it, we could also test it here. Make it so.
1377     EXPECT_EQ(task.remove_mask, GetRemovalMask());
1378     EXPECT_EQ(task.origin_type_mask, GetOriginTypeMask());
1379     EXPECT_EQ(task.delete_begin, GetBeginTime());
1380   }
1381 
1382   EXPECT_FALSE(remover->IsRemovingForTesting());
1383 
1384   // Run clean up tasks.
1385   RunAllTasksUntilIdle();
1386 }
1387 
1388 // Scheduling multiple identical deletions should immediately execute the first
1389 // deletion and merge all following deletions.
TEST_F(BrowsingDataRemoverImplTest,MultipleIdenticalTasks)1390 TEST_F(BrowsingDataRemoverImplTest, MultipleIdenticalTasks) {
1391   BrowsingDataRemoverImpl* remover = static_cast<BrowsingDataRemoverImpl*>(
1392       BrowserContext::GetBrowsingDataRemover(GetBrowserContext()));
1393   EXPECT_FALSE(remover->IsRemovingForTesting());
1394 
1395   std::unique_ptr<BrowsingDataFilterBuilder> filter_builder(
1396       BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::WHITELIST));
1397   filter_builder->AddRegisterableDomain("example.com");
1398 
1399   MultipleTasksObserver observer(remover);
1400   BrowsingDataRemoverCompletionInhibitor completion_inhibitor(remover);
1401 
1402   std::list<BrowsingDataRemoverImpl::RemovalTask> tasks;
1403   for (int i = 0; i < 10; i++) {
1404     remover->RemoveWithFilterAndReply(
1405         base::Time(), base::Time::Max(), BrowsingDataRemover::DATA_TYPE_COOKIES,
1406         BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB,
1407         BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::BLACKLIST),
1408         observer.target_a());
1409   }
1410 
1411   EXPECT_TRUE(remover->IsRemovingForTesting());
1412   observer.ClearLastCalledTarget();
1413 
1414   // Finish the task execution synchronously.
1415   completion_inhibitor.BlockUntilNearCompletion();
1416   completion_inhibitor.ContinueToCompletion();
1417 
1418   // Expect the first observer to be called.
1419   EXPECT_EQ(1u, observer.GetLastCalledTargets().size());
1420 
1421   EXPECT_TRUE(remover->IsRemovingForTesting());
1422   observer.ClearLastCalledTarget();
1423 
1424   // Finish the task execution synchronously.
1425   completion_inhibitor.BlockUntilNearCompletion();
1426   completion_inhibitor.ContinueToCompletion();
1427 
1428   // Expect the remaining observer to be called by a batched deletion.
1429   EXPECT_EQ(9u, observer.GetLastCalledTargets().size());
1430 
1431   EXPECT_FALSE(remover->IsRemovingForTesting());
1432 
1433   // Run clean up tasks.
1434   RunAllTasksUntilIdle();
1435 }
1436 
1437 // BrowsingDataRemoverTest.MultipleTasks, tests that the tasks are not mixed up
1438 // and they are executed in a correct order. However, the completion inhibitor
1439 // kept synchronizing the execution in order to verify the parameters.
1440 // This test demonstrates that even running the tasks without inhibition is
1441 // executed correctly and doesn't crash.
TEST_F(BrowsingDataRemoverImplTest,MultipleTasksInQuickSuccession)1442 TEST_F(BrowsingDataRemoverImplTest, MultipleTasksInQuickSuccession) {
1443   BrowsingDataRemoverImpl* remover = static_cast<BrowsingDataRemoverImpl*>(
1444       BrowserContext::GetBrowsingDataRemover(GetBrowserContext()));
1445   EXPECT_FALSE(remover->IsRemovingForTesting());
1446 
1447   int test_removal_masks[] = {
1448       BrowsingDataRemover::DATA_TYPE_COOKIES,
1449       BrowsingDataRemover::DATA_TYPE_LOCAL_STORAGE,
1450       BrowsingDataRemover::DATA_TYPE_COOKIES,
1451       BrowsingDataRemover::DATA_TYPE_COOKIES,
1452       BrowsingDataRemover::DATA_TYPE_COOKIES,
1453       BrowsingDataRemover::DATA_TYPE_DOWNLOADS,
1454       BrowsingDataRemover::DATA_TYPE_DOWNLOADS,
1455       BrowsingDataRemover::DATA_TYPE_DOWNLOADS,
1456       BrowsingDataRemover::DATA_TYPE_COOKIES |
1457           BrowsingDataRemover::DATA_TYPE_DOWNLOADS,
1458       BrowsingDataRemover::DATA_TYPE_COOKIES |
1459           BrowsingDataRemover::DATA_TYPE_DOWNLOADS,
1460       BrowsingDataRemover::DATA_TYPE_COOKIES |
1461           BrowsingDataRemover::DATA_TYPE_DOWNLOADS |
1462           BrowsingDataRemover::DATA_TYPE_LOCAL_STORAGE,
1463       BrowsingDataRemover::DATA_TYPE_LOCAL_STORAGE,
1464       BrowsingDataRemover::DATA_TYPE_LOCAL_STORAGE,
1465   };
1466 
1467   for (int removal_mask : test_removal_masks) {
1468     remover->Remove(base::Time(), base::Time::Max(), removal_mask,
1469                     BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB);
1470   }
1471 
1472   EXPECT_TRUE(remover->IsRemovingForTesting());
1473 
1474   // Add one more deletion and wait for it.
1475   BlockUntilBrowsingDataRemoved(
1476       base::Time(), base::Time::Max(), BrowsingDataRemover::DATA_TYPE_COOKIES,
1477       BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB);
1478 
1479   EXPECT_FALSE(remover->IsRemovingForTesting());
1480 }
1481 
1482 }  // namespace content
1483