blob: ab563cc2dbf5561b3d7d76c068a88e62662b0e82 [file] [log] [blame]
juliatuttle381d77e2017-04-07 18:54:121// 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 "net/reporting/reporting_service.h"
6
7#include <memory>
8#include <string>
9
Sam Burnettf13c06b2019-07-30 15:53:4910#include "base/bind.h"
juliatuttle381d77e2017-04-07 18:54:1211#include "base/memory/ptr_util.h"
Matt Menke055f5c92020-10-22 19:33:2312#include "base/test/scoped_feature_list.h"
juliatuttle381d77e2017-04-07 18:54:1213#include "base/time/tick_clock.h"
14#include "base/values.h"
Matt Menke055f5c92020-10-22 19:33:2315#include "net/base/features.h"
Ian Clelland52035be2021-10-07 16:38:5016#include "net/base/isolation_info.h"
Lily Chenad5dd0802020-03-10 21:58:0917#include "net/base/network_isolation_key.h"
Matt Menke4807a9a2020-11-21 00:14:4118#include "net/base/schemeful_site.h"
Sam Burnettf13c06b2019-07-30 15:53:4919#include "net/reporting/mock_persistent_reporting_store.h"
20#include "net/reporting/reporting_browsing_data_remover.h"
juliatuttle381d77e2017-04-07 18:54:1221#include "net/reporting/reporting_cache.h"
22#include "net/reporting/reporting_context.h"
Lily Chenad5dd0802020-03-10 21:58:0923#include "net/reporting/reporting_endpoint.h"
juliatuttle381d77e2017-04-07 18:54:1224#include "net/reporting/reporting_policy.h"
25#include "net/reporting/reporting_report.h"
26#include "net/reporting/reporting_service.h"
27#include "net/reporting/reporting_test_util.h"
Gabriel Charettec7108742019-08-23 03:31:4028#include "net/test/test_with_task_environment.h"
Sam Burnettf13c06b2019-07-30 15:53:4929#include "testing/gmock/include/gmock/gmock.h"
juliatuttle381d77e2017-04-07 18:54:1230#include "testing/gtest/include/gtest/gtest.h"
Ian Clellande07e64b2021-08-23 16:29:4331#include "third_party/abseil-cpp/absl/types/optional.h"
Matt Menke4807a9a2020-11-21 00:14:4132#include "url/gurl.h"
33#include "url/origin.h"
juliatuttle381d77e2017-04-07 18:54:1234
35namespace net {
36namespace {
37
Sam Burnettf13c06b2019-07-30 15:53:4938using CommandType = MockPersistentReportingStore::Command::Type;
39
40// The tests are parametrized on a boolean value which represents whether to use
41// a MockPersistentReportingStore (if false, no store is used).
42class ReportingServiceTest : public ::testing::TestWithParam<bool>,
Gabriel Charette694c3c332019-08-19 14:53:0543 public WithTaskEnvironment {
juliatuttle381d77e2017-04-07 18:54:1244 protected:
45 const GURL kUrl_ = GURL("https://origin/path");
Sam Burnettf13c06b2019-07-30 15:53:4946 const GURL kUrl2_ = GURL("https://origin2/path");
Daniel Cheng88186bd52017-10-20 08:14:4647 const url::Origin kOrigin_ = url::Origin::Create(kUrl_);
Sam Burnettf13c06b2019-07-30 15:53:4948 const url::Origin kOrigin2_ = url::Origin::Create(kUrl2_);
juliatuttle381d77e2017-04-07 18:54:1249 const GURL kEndpoint_ = GURL("https://endpoint/");
Ian Clelland4c336472021-08-23 22:20:0050 const GURL kEndpoint2_ = GURL("https://endpoint2/");
Douglas Creagerf6cb49f72018-07-19 20:14:5351 const std::string kUserAgent_ = "Mozilla/1.0";
juliatuttle381d77e2017-04-07 18:54:1252 const std::string kGroup_ = "group";
Ian Clelland4c336472021-08-23 22:20:0053 const std::string kGroup2_ = "group2";
juliatuttle381d77e2017-04-07 18:54:1254 const std::string kType_ = "type";
Ian Clellande07e64b2021-08-23 16:29:4355 const absl::optional<base::UnguessableToken> kReportingSource_ =
56 base::UnguessableToken::Create();
Matt Menke4807a9a2020-11-21 00:14:4157 const NetworkIsolationKey kNik_ =
58 NetworkIsolationKey(SchemefulSite(kOrigin_), SchemefulSite(kOrigin_));
59 const NetworkIsolationKey kNik2_ =
60 NetworkIsolationKey(SchemefulSite(kOrigin2_), SchemefulSite(kOrigin2_));
Lily Chenad5dd0802020-03-10 21:58:0961 const ReportingEndpointGroupKey kGroupKey_ =
Matt Menke17b23c42020-10-22 05:14:5762 ReportingEndpointGroupKey(kNik_, kOrigin_, kGroup_);
Lily Chenad5dd0802020-03-10 21:58:0963 const ReportingEndpointGroupKey kGroupKey2_ =
Matt Menke17b23c42020-10-22 05:14:5764 ReportingEndpointGroupKey(kNik2_, kOrigin2_, kGroup_);
Ian Clelland52035be2021-10-07 16:38:5065 const IsolationInfo kIsolationInfo_ =
66 IsolationInfo::Create(IsolationInfo::RequestType::kOther,
67 kOrigin_,
68 kOrigin_,
69 SiteForCookies::FromOrigin(kOrigin_));
juliatuttle381d77e2017-04-07 18:54:1270
Sam Burnettf13c06b2019-07-30 15:53:4971 ReportingServiceTest() {
Matt Menke055f5c92020-10-22 19:33:2372 feature_list_.InitAndEnableFeature(
73 features::kPartitionNelAndReportingByNetworkIsolationKey);
74 Init();
75 }
76
77 // Initializes, or re-initializes, |service_| and its dependencies.
78 void Init() {
Sam Burnettf13c06b2019-07-30 15:53:4979 if (GetParam())
80 store_ = std::make_unique<MockPersistentReportingStore>();
81 else
82 store_ = nullptr;
juliatuttle381d77e2017-04-07 18:54:1283
Sam Burnettf13c06b2019-07-30 15:53:4984 auto test_context = std::make_unique<TestReportingContext>(
85 &clock_, &tick_clock_, ReportingPolicy(), store_.get());
86 context_ = test_context.get();
87
88 service_ = ReportingService::CreateForTesting(std::move(test_context));
89 }
90
91 // If the store exists, simulate finishing loading the store, which should
92 // make the rest of the test run synchronously.
93 void FinishLoading(bool load_success) {
94 if (store_)
95 store_->FinishLoading(load_success);
96 }
97
98 MockPersistentReportingStore* store() { return store_.get(); }
juliatuttle381d77e2017-04-07 18:54:1299 TestReportingContext* context() { return context_; }
100 ReportingService* service() { return service_.get(); }
101
102 private:
Matt Menke055f5c92020-10-22 19:33:23103 base::test::ScopedFeatureList feature_list_;
104
tzik26331742017-12-07 07:28:33105 base::SimpleTestClock clock_;
106 base::SimpleTestTickClock tick_clock_;
107
Sam Burnettf13c06b2019-07-30 15:53:49108 std::unique_ptr<MockPersistentReportingStore> store_;
juliatuttle381d77e2017-04-07 18:54:12109 TestReportingContext* context_;
110 std::unique_ptr<ReportingService> service_;
111};
112
Sam Burnettf13c06b2019-07-30 15:53:49113TEST_P(ReportingServiceTest, QueueReport) {
Ian Clellande07e64b2021-08-23 16:29:43114 service()->QueueReport(kUrl_, kReportingSource_, kNik_, kUserAgent_, kGroup_,
115 kType_, std::make_unique<base::DictionaryValue>(), 0);
Sam Burnettf13c06b2019-07-30 15:53:49116 FinishLoading(true /* load_success */);
juliatuttle381d77e2017-04-07 18:54:12117
118 std::vector<const ReportingReport*> reports;
119 context()->cache()->GetReports(&reports);
120 ASSERT_EQ(1u, reports.size());
121 EXPECT_EQ(kUrl_, reports[0]->url);
Matt Menkedd2ed7a2020-10-22 04:09:20122 EXPECT_EQ(kNik_, reports[0]->network_isolation_key);
Douglas Creagerf6cb49f72018-07-19 20:14:53123 EXPECT_EQ(kUserAgent_, reports[0]->user_agent);
juliatuttle381d77e2017-04-07 18:54:12124 EXPECT_EQ(kGroup_, reports[0]->group);
125 EXPECT_EQ(kType_, reports[0]->type);
126}
127
Sam Burnettf13c06b2019-07-30 15:53:49128TEST_P(ReportingServiceTest, QueueReportSanitizeUrl) {
Lily Chen8fed0dd72019-01-23 17:13:27129 // Same as kUrl_ but with username, password, and fragment.
130 GURL url = GURL("https://username:password@origin/path#fragment");
Ian Clellande07e64b2021-08-23 16:29:43131 service()->QueueReport(url, kReportingSource_, kNik_, kUserAgent_, kGroup_,
132 kType_, std::make_unique<base::DictionaryValue>(), 0);
Sam Burnettf13c06b2019-07-30 15:53:49133 FinishLoading(true /* load_success */);
Lily Chen8fed0dd72019-01-23 17:13:27134
135 std::vector<const ReportingReport*> reports;
136 context()->cache()->GetReports(&reports);
137 ASSERT_EQ(1u, reports.size());
138 EXPECT_EQ(kUrl_, reports[0]->url);
Matt Menkedd2ed7a2020-10-22 04:09:20139 EXPECT_EQ(kNik_, reports[0]->network_isolation_key);
Lily Chen8fed0dd72019-01-23 17:13:27140 EXPECT_EQ(kUserAgent_, reports[0]->user_agent);
141 EXPECT_EQ(kGroup_, reports[0]->group);
142 EXPECT_EQ(kType_, reports[0]->type);
143}
144
Sam Burnettf13c06b2019-07-30 15:53:49145TEST_P(ReportingServiceTest, DontQueueReportInvalidUrl) {
Lily Chen8fed0dd72019-01-23 17:13:27146 GURL url = GURL("https://");
Sam Burnettf13c06b2019-07-30 15:53:49147 // This does not trigger an attempt to load from the store because the url
148 // is immediately rejected as invalid.
Ian Clellande07e64b2021-08-23 16:29:43149 service()->QueueReport(url, kReportingSource_, kNik_, kUserAgent_, kGroup_,
150 kType_, std::make_unique<base::DictionaryValue>(), 0);
Lily Chen8fed0dd72019-01-23 17:13:27151
152 std::vector<const ReportingReport*> reports;
153 context()->cache()->GetReports(&reports);
154 ASSERT_EQ(0u, reports.size());
155}
156
Matt Menke055f5c92020-10-22 19:33:23157TEST_P(ReportingServiceTest, QueueReportNetworkIsolationKeyDisabled) {
158 base::test::ScopedFeatureList feature_list;
159 feature_list.InitAndDisableFeature(
160 features::kPartitionNelAndReportingByNetworkIsolationKey);
161
162 // Re-create the store, so it reads the new feature value.
163 Init();
164
Ian Clellande07e64b2021-08-23 16:29:43165 service()->QueueReport(kUrl_, kReportingSource_, kNik_, kUserAgent_, kGroup_,
166 kType_, std::make_unique<base::DictionaryValue>(), 0);
Matt Menke055f5c92020-10-22 19:33:23167 FinishLoading(true /* load_success */);
168
169 std::vector<const ReportingReport*> reports;
170 context()->cache()->GetReports(&reports);
171 ASSERT_EQ(1u, reports.size());
172
173 // NetworkIsolationKey should be empty, instead of kNik_;
174 EXPECT_EQ(NetworkIsolationKey(), reports[0]->network_isolation_key);
175 EXPECT_NE(kNik_, reports[0]->network_isolation_key);
176
177 EXPECT_EQ(kUrl_, reports[0]->url);
178 EXPECT_EQ(kUserAgent_, reports[0]->user_agent);
179 EXPECT_EQ(kGroup_, reports[0]->group);
180 EXPECT_EQ(kType_, reports[0]->type);
181}
182
Rodney Ding329e4bb2021-03-19 22:21:53183TEST_P(ReportingServiceTest, ProcessReportToHeader) {
184 service()->ProcessReportToHeader(kUrl_, kNik_,
185 "{\"endpoints\":[{\"url\":\"" +
186 kEndpoint_.spec() +
187 "\"}],"
188 "\"group\":\"" +
189 kGroup_ +
190 "\","
191 "\"max_age\":86400}");
Sam Burnettf13c06b2019-07-30 15:53:49192 FinishLoading(true /* load_success */);
juliatuttle381d77e2017-04-07 18:54:12193
Lily Chenefb6fcf2019-04-19 04:17:54194 EXPECT_EQ(1u, context()->cache()->GetEndpointCount());
Matt Menke055f5c92020-10-22 19:33:23195 EXPECT_TRUE(context()->cache()->GetEndpointForTesting(
196 ReportingEndpointGroupKey(kNik_, kOrigin_, kGroup_), kEndpoint_));
juliatuttle381d77e2017-04-07 18:54:12197}
198
Rodney Ding329e4bb2021-03-19 22:21:53199TEST_P(ReportingServiceTest, ProcessReportingEndpointsHeader) {
200 base::test::ScopedFeatureList feature_list;
201 feature_list.InitAndEnableFeature(net::features::kDocumentReporting);
Ian Clelland4563d4d2021-06-02 20:25:50202 auto parsed_header =
203 ParseReportingEndpoints(kGroup_ + "=\"" + kEndpoint_.spec() + "\"");
204 ASSERT_TRUE(parsed_header.has_value());
Ian Clelland52035be2021-10-07 16:38:50205 service()->SetDocumentReportingEndpoints(*kReportingSource_, kOrigin_,
206 kIsolationInfo_, *parsed_header);
Rodney Ding329e4bb2021-03-19 22:21:53207 FinishLoading(true /* load_success */);
208
Ian Clellanda52d5472021-08-23 18:33:53209 // Endpoint should not be part of the persistent store.
210 EXPECT_EQ(0u, context()->cache()->GetEndpointCount());
211 // Endpoint should be associated with the reporting source.
212 EXPECT_TRUE(
213 context()->cache()->GetV1EndpointForTesting(*kReportingSource_, kGroup_));
Rodney Ding329e4bb2021-03-19 22:21:53214}
215
Ian Clelland4c336472021-08-23 22:20:00216TEST_P(ReportingServiceTest, SendReportsAndRemoveSource) {
217 base::test::ScopedFeatureList feature_list;
218 feature_list.InitAndEnableFeature(net::features::kDocumentReporting);
219 auto parsed_header =
220 ParseReportingEndpoints(kGroup_ + "=\"" + kEndpoint_.spec() + "\", " +
221 kGroup2_ + "=\"" + kEndpoint2_.spec() + "\"");
222 ASSERT_TRUE(parsed_header.has_value());
Ian Clelland52035be2021-10-07 16:38:50223 service()->SetDocumentReportingEndpoints(*kReportingSource_, kOrigin_,
224 kIsolationInfo_, *parsed_header);
Ian Clelland4c336472021-08-23 22:20:00225 // This report should be sent immediately, starting the delivery agent timer.
226 service()->QueueReport(kUrl_, kReportingSource_, kNik_, kUserAgent_, kGroup_,
227 kType_, std::make_unique<base::DictionaryValue>(), 0);
228
229 FinishLoading(true /* load_success */);
230
231 std::vector<const ReportingReport*> reports;
232 context()->cache()->GetReports(&reports);
233 ASSERT_EQ(1u, reports.size());
234 EXPECT_EQ(0u, context()->cache()->GetReportCountWithStatusForTesting(
235 ReportingReport::Status::QUEUED));
236
237 // Now simulate the source being destroyed.
238 service()->SendReportsAndRemoveSource(*kReportingSource_);
239
240 // There should be no queued reports, but the previously sent report should
241 // still be pending.
242 EXPECT_EQ(0u, context()->cache()->GetReportCountWithStatusForTesting(
243 ReportingReport::Status::QUEUED));
244 EXPECT_EQ(1u, context()->cache()->GetReportCountWithStatusForTesting(
245 ReportingReport::Status::PENDING));
246 // Source should be marked as expired.
247 ASSERT_TRUE(
248 context()->cache()->GetExpiredSources().contains(*kReportingSource_));
249}
250
251TEST_P(ReportingServiceTest, SendReportsAndRemoveSourceWithPendingReports) {
252 base::test::ScopedFeatureList feature_list;
253 feature_list.InitAndEnableFeature(net::features::kDocumentReporting);
254 auto parsed_header =
255 ParseReportingEndpoints(kGroup_ + "=\"" + kEndpoint_.spec() + "\", " +
256 kGroup2_ + "=\"" + kEndpoint2_.spec() + "\"");
257 ASSERT_TRUE(parsed_header.has_value());
Ian Clelland52035be2021-10-07 16:38:50258 service()->SetDocumentReportingEndpoints(*kReportingSource_, kOrigin_,
259 kIsolationInfo_, *parsed_header);
Ian Clelland4c336472021-08-23 22:20:00260 // This report should be sent immediately, starting the delivery agent timer.
261 service()->QueueReport(kUrl_, kReportingSource_, kNik_, kUserAgent_, kGroup_,
262 kType_, std::make_unique<base::DictionaryValue>(), 0);
263
264 FinishLoading(true /* load_success */);
265
266 std::vector<const ReportingReport*> reports;
267 context()->cache()->GetReports(&reports);
268 ASSERT_EQ(1u, reports.size());
269 EXPECT_EQ(0u, context()->cache()->GetReportCountWithStatusForTesting(
270 ReportingReport::Status::QUEUED));
271 EXPECT_EQ(1u, context()->cache()->GetReportCountWithStatusForTesting(
272 ReportingReport::Status::PENDING));
273
274 // Queue another report, which should remain queued.
275 service()->QueueReport(kUrl_, kReportingSource_, kNik_, kUserAgent_, kGroup_,
276 kType_, std::make_unique<base::DictionaryValue>(), 0);
277 EXPECT_EQ(1u, context()->cache()->GetReportCountWithStatusForTesting(
278 ReportingReport::Status::QUEUED));
279 EXPECT_EQ(1u, context()->cache()->GetReportCountWithStatusForTesting(
280 ReportingReport::Status::PENDING));
281
282 // Now simulate the source being destroyed.
283 service()->SendReportsAndRemoveSource(*kReportingSource_);
284
285 // The report should still be queued, while the source should be marked as
286 // expired. (The original report is still pending.)
287 EXPECT_EQ(1u, context()->cache()->GetReportCountWithStatusForTesting(
288 ReportingReport::Status::QUEUED));
289 EXPECT_EQ(1u, context()->cache()->GetReportCountWithStatusForTesting(
290 ReportingReport::Status::PENDING));
291 ASSERT_TRUE(
292 context()->cache()->GetExpiredSources().contains(kReportingSource_));
293}
294
Rodney Ding329e4bb2021-03-19 22:21:53295TEST_P(ReportingServiceTest, ProcessReportingEndpointsHeaderPathAbsolute) {
296 base::test::ScopedFeatureList feature_list;
297 feature_list.InitAndEnableFeature(net::features::kDocumentReporting);
Ian Clelland4563d4d2021-06-02 20:25:50298 auto parsed_header = ParseReportingEndpoints(kGroup_ + "=\"/path-absolute\"");
299 ASSERT_TRUE(parsed_header.has_value());
Ian Clelland52035be2021-10-07 16:38:50300 service()->SetDocumentReportingEndpoints(*kReportingSource_, kOrigin_,
301 kIsolationInfo_, *parsed_header);
Rodney Dingb8809432020-03-12 22:19:59302 FinishLoading(true /* load_success */);
303
Ian Clellanda52d5472021-08-23 18:33:53304 // Endpoint should not be part of the persistent store.
305 EXPECT_EQ(0u, context()->cache()->GetEndpointCount());
306 // Endpoint should be associated with the reporting source.
307 ReportingEndpoint endpoint =
308 context()->cache()->GetV1EndpointForTesting(*kReportingSource_, kGroup_);
309 EXPECT_TRUE(endpoint);
310 // Endpoint should have the correct path.
311 EXPECT_EQ(kUrl_.Resolve("/path-absolute"), endpoint.info.url);
Rodney Dingb8809432020-03-12 22:19:59312}
313
Rodney Ding329e4bb2021-03-19 22:21:53314TEST_P(ReportingServiceTest, ProcessReportToHeaderPathAbsolute) {
315 service()->ProcessReportToHeader(
316 kUrl_, kNik_,
317 "{\"endpoints\":[{\"url\":\"/path-absolute\"}],"
318 "\"group\":\"" +
319 kGroup_ +
320 "\","
321 "\"max_age\":86400}");
322 FinishLoading(true /* load_success */);
323
324 EXPECT_EQ(1u, context()->cache()->GetEndpointCount());
325}
326
327TEST_P(ReportingServiceTest, ProcessReportToHeader_TooLong) {
Julia Tuttle7d874942018-03-02 01:19:13328 const std::string header_too_long =
329 "{\"endpoints\":[{\"url\":\"" + kEndpoint_.spec() +
330 "\"}],"
331 "\"group\":\"" +
332 kGroup_ +
333 "\","
Douglas Creagerbca64422018-06-18 13:54:42334 "\"max_age\":86400," +
Julia Tuttle7d874942018-03-02 01:19:13335 "\"junk\":\"" + std::string(32 * 1024, 'a') + "\"}";
Sam Burnettf13c06b2019-07-30 15:53:49336 // This does not trigger an attempt to load from the store because the header
337 // is immediately rejected as invalid.
Rodney Ding329e4bb2021-03-19 22:21:53338 service()->ProcessReportToHeader(kUrl_, kNik_, header_too_long);
Julia Tuttle7d874942018-03-02 01:19:13339
Lily Chenefb6fcf2019-04-19 04:17:54340 EXPECT_EQ(0u, context()->cache()->GetEndpointCount());
Julia Tuttle7d874942018-03-02 01:19:13341}
342
Rodney Ding329e4bb2021-03-19 22:21:53343TEST_P(ReportingServiceTest, ProcessReportToHeader_TooDeep) {
Julia Tuttle7d874942018-03-02 01:19:13344 const std::string header_too_deep = "{\"endpoints\":[{\"url\":\"" +
345 kEndpoint_.spec() +
346 "\"}],"
347 "\"group\":\"" +
348 kGroup_ +
349 "\","
Douglas Creagerbca64422018-06-18 13:54:42350 "\"max_age\":86400," +
Julia Tuttle7d874942018-03-02 01:19:13351 "\"junk\":[[[[[[[[[[]]]]]]]]]]}";
Sam Burnettf13c06b2019-07-30 15:53:49352 // This does not trigger an attempt to load from the store because the header
353 // is immediately rejected as invalid.
Rodney Ding329e4bb2021-03-19 22:21:53354 service()->ProcessReportToHeader(kUrl_, kNik_, header_too_deep);
Julia Tuttle7d874942018-03-02 01:19:13355
Lily Chenefb6fcf2019-04-19 04:17:54356 EXPECT_EQ(0u, context()->cache()->GetEndpointCount());
Julia Tuttle7d874942018-03-02 01:19:13357}
358
Rodney Ding329e4bb2021-03-19 22:21:53359TEST_P(ReportingServiceTest, ProcessReportToHeaderNetworkIsolationKeyDisabled) {
Matt Menke055f5c92020-10-22 19:33:23360 base::test::ScopedFeatureList feature_list;
361 feature_list.InitAndDisableFeature(
362 features::kPartitionNelAndReportingByNetworkIsolationKey);
363
364 // Re-create the store, so it reads the new feature value.
365 Init();
366
Rodney Ding329e4bb2021-03-19 22:21:53367 service()->ProcessReportToHeader(kUrl_, kNik_,
368 "{\"endpoints\":[{\"url\":\"" +
369 kEndpoint_.spec() +
370 "\"}],"
371 "\"group\":\"" +
372 kGroup_ +
373 "\","
374 "\"max_age\":86400}");
Matt Menke055f5c92020-10-22 19:33:23375 FinishLoading(true /* load_success */);
376
377 EXPECT_EQ(1u, context()->cache()->GetEndpointCount());
378 EXPECT_FALSE(context()->cache()->GetEndpointForTesting(
379 ReportingEndpointGroupKey(kNik_, kOrigin_, kGroup_), kEndpoint_));
380 EXPECT_TRUE(context()->cache()->GetEndpointForTesting(
381 ReportingEndpointGroupKey(NetworkIsolationKey(), kOrigin_, kGroup_),
382 kEndpoint_));
383}
384
Sam Burnettf13c06b2019-07-30 15:53:49385TEST_P(ReportingServiceTest, WriteToStore) {
386 if (!store())
387 return;
388
389 MockPersistentReportingStore::CommandList expected_commands;
390
391 // This first call to any public method triggers a load. The load will block
392 // until we call FinishLoading.
Rodney Ding329e4bb2021-03-19 22:21:53393 service()->ProcessReportToHeader(kUrl_, kNik_,
394 "{\"endpoints\":[{\"url\":\"" +
395 kEndpoint_.spec() +
396 "\"}],"
397 "\"group\":\"" +
398 kGroup_ +
399 "\","
400 "\"max_age\":86400}");
Sam Burnettf13c06b2019-07-30 15:53:49401 expected_commands.emplace_back(CommandType::LOAD_REPORTING_CLIENTS);
402 EXPECT_THAT(store()->GetAllCommands(),
403 testing::UnorderedElementsAreArray(expected_commands));
404
405 // Unblock the load. The will let the remaining calls to the service complete
406 // without blocking.
407 FinishLoading(true /* load_success */);
Lily Chenad5dd0802020-03-10 21:58:09408 expected_commands.emplace_back(CommandType::ADD_REPORTING_ENDPOINT,
409 kGroupKey_, kEndpoint_);
410 expected_commands.emplace_back(CommandType::ADD_REPORTING_ENDPOINT_GROUP,
411 kGroupKey_);
Sam Burnettf13c06b2019-07-30 15:53:49412 EXPECT_THAT(store()->GetAllCommands(),
413 testing::UnorderedElementsAreArray(expected_commands));
414
Rodney Ding329e4bb2021-03-19 22:21:53415 service()->ProcessReportToHeader(kUrl2_, kNik2_,
416 "{\"endpoints\":[{\"url\":\"" +
417 kEndpoint_.spec() +
418 "\"}],"
419 "\"group\":\"" +
420 kGroup_ +
421 "\","
422 "\"max_age\":86400}");
Lily Chenad5dd0802020-03-10 21:58:09423 expected_commands.emplace_back(CommandType::ADD_REPORTING_ENDPOINT,
424 kGroupKey2_, kEndpoint_);
425 expected_commands.emplace_back(CommandType::ADD_REPORTING_ENDPOINT_GROUP,
426 kGroupKey2_);
Sam Burnettf13c06b2019-07-30 15:53:49427 EXPECT_THAT(store()->GetAllCommands(),
428 testing::UnorderedElementsAreArray(expected_commands));
429
Ian Clellande07e64b2021-08-23 16:29:43430 service()->QueueReport(kUrl_, kReportingSource_, kNik_, kUserAgent_, kGroup_,
431 kType_, std::make_unique<base::DictionaryValue>(), 0);
Sam Burnettf13c06b2019-07-30 15:53:49432 expected_commands.emplace_back(
Lily Chenad5dd0802020-03-10 21:58:09433 CommandType::UPDATE_REPORTING_ENDPOINT_GROUP_ACCESS_TIME, kGroupKey_);
Sam Burnettf13c06b2019-07-30 15:53:49434 EXPECT_THAT(store()->GetAllCommands(),
435 testing::UnorderedElementsAreArray(expected_commands));
436
437 service()->RemoveBrowsingData(ReportingBrowsingDataRemover::DATA_TYPE_CLIENTS,
438 base::BindRepeating([](const GURL& url) {
439 return url.host() == "origin";
440 }));
Lily Chenad5dd0802020-03-10 21:58:09441 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT,
442 kGroupKey_, kEndpoint_);
443 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT_GROUP,
444 kGroupKey_);
Sam Burnettf13c06b2019-07-30 15:53:49445 expected_commands.emplace_back(CommandType::FLUSH);
446 EXPECT_THAT(store()->GetAllCommands(),
447 testing::UnorderedElementsAreArray(expected_commands));
448
449 service()->RemoveAllBrowsingData(
450 ReportingBrowsingDataRemover::DATA_TYPE_CLIENTS);
Lily Chenad5dd0802020-03-10 21:58:09451 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT,
452 kGroupKey2_, kEndpoint_);
453 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT_GROUP,
454 kGroupKey2_);
Sam Burnettf13c06b2019-07-30 15:53:49455 expected_commands.emplace_back(CommandType::FLUSH);
456 EXPECT_THAT(store()->GetAllCommands(),
457 testing::UnorderedElementsAreArray(expected_commands));
458}
459
460TEST_P(ReportingServiceTest, WaitUntilLoadFinishesBeforeWritingToStore) {
461 if (!store())
462 return;
463
464 MockPersistentReportingStore::CommandList expected_commands;
465
466 // This first call to any public method triggers a load. The load will block
467 // until we call FinishLoading.
Rodney Ding329e4bb2021-03-19 22:21:53468 service()->ProcessReportToHeader(kUrl_, kNik_,
469 "{\"endpoints\":[{\"url\":\"" +
470 kEndpoint_.spec() +
471 "\"}],"
472 "\"group\":\"" +
473 kGroup_ +
474 "\","
475 "\"max_age\":86400}");
Sam Burnettf13c06b2019-07-30 15:53:49476 expected_commands.emplace_back(CommandType::LOAD_REPORTING_CLIENTS);
477 EXPECT_THAT(store()->GetAllCommands(),
478 testing::UnorderedElementsAreArray(expected_commands));
479
Rodney Ding329e4bb2021-03-19 22:21:53480 service()->ProcessReportToHeader(kUrl2_, kNik2_,
481 "{\"endpoints\":[{\"url\":\"" +
482 kEndpoint_.spec() +
483 "\"}],"
484 "\"group\":\"" +
485 kGroup_ +
486 "\","
487 "\"max_age\":86400}");
Sam Burnettf13c06b2019-07-30 15:53:49488 EXPECT_THAT(store()->GetAllCommands(),
489 testing::UnorderedElementsAreArray(expected_commands));
490
Ian Clellande07e64b2021-08-23 16:29:43491 service()->QueueReport(kUrl_, kReportingSource_, kNik_, kUserAgent_, kGroup_,
492 kType_, std::make_unique<base::DictionaryValue>(), 0);
Sam Burnettf13c06b2019-07-30 15:53:49493 EXPECT_THAT(store()->GetAllCommands(),
494 testing::UnorderedElementsAreArray(expected_commands));
495
496 service()->RemoveBrowsingData(ReportingBrowsingDataRemover::DATA_TYPE_CLIENTS,
497 base::BindRepeating([](const GURL& url) {
498 return url.host() == "origin";
499 }));
500 EXPECT_THAT(store()->GetAllCommands(),
501 testing::UnorderedElementsAreArray(expected_commands));
502
503 service()->RemoveAllBrowsingData(
504 ReportingBrowsingDataRemover::DATA_TYPE_CLIENTS);
505 EXPECT_THAT(store()->GetAllCommands(),
506 testing::UnorderedElementsAreArray(expected_commands));
507
508 // Unblock the load. The will let the remaining calls to the service complete
509 // without blocking.
510 FinishLoading(true /* load_success */);
Lily Chenad5dd0802020-03-10 21:58:09511 expected_commands.emplace_back(CommandType::ADD_REPORTING_ENDPOINT,
512 kGroupKey_, kEndpoint_);
513 expected_commands.emplace_back(CommandType::ADD_REPORTING_ENDPOINT,
514 kGroupKey2_, kEndpoint_);
515 expected_commands.emplace_back(CommandType::ADD_REPORTING_ENDPOINT_GROUP,
516 kGroupKey_);
517 expected_commands.emplace_back(CommandType::ADD_REPORTING_ENDPOINT_GROUP,
518 kGroupKey2_);
Sam Burnettf13c06b2019-07-30 15:53:49519 expected_commands.emplace_back(
Lily Chenad5dd0802020-03-10 21:58:09520 CommandType::UPDATE_REPORTING_ENDPOINT_GROUP_ACCESS_TIME, kGroupKey_);
521 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT,
522 kGroupKey_, kEndpoint_);
523 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT_GROUP,
524 kGroupKey_);
Sam Burnettf13c06b2019-07-30 15:53:49525 expected_commands.emplace_back(CommandType::FLUSH);
Lily Chenad5dd0802020-03-10 21:58:09526 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT,
527 kGroupKey2_, kEndpoint_);
528 expected_commands.emplace_back(CommandType::DELETE_REPORTING_ENDPOINT_GROUP,
529 kGroupKey2_);
Sam Burnettf13c06b2019-07-30 15:53:49530 expected_commands.emplace_back(CommandType::FLUSH);
531 EXPECT_THAT(store()->GetAllCommands(),
532 testing::UnorderedElementsAreArray(expected_commands));
533}
534
535INSTANTIATE_TEST_SUITE_P(ReportingServiceStoreTest,
536 ReportingServiceTest,
537 ::testing::Bool());
juliatuttle381d77e2017-04-07 18:54:12538} // namespace
539} // namespace net