| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/safe_browsing/permission_reporter.h" | 5 #include "chrome/browser/safe_browsing/permission_reporter.h" |
| 6 | 6 |
| 7 #include "base/feature_list.h" | 7 #include "base/feature_list.h" |
| 8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
| 9 #include "base/metrics/field_trial.h" | 9 #include "base/metrics/field_trial.h" |
| 10 #include "base/test/simple_test_clock.h" | 10 #include "base/test/simple_test_clock.h" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 const int kMaximumReportsPerOriginPerPermissionPerMinute = 5; | 30 const int kMaximumReportsPerOriginPerPermissionPerMinute = 5; |
| 31 | 31 |
| 32 const char kDummyOriginOne[] = "http://example.test/"; | 32 const char kDummyOriginOne[] = "http://example.test/"; |
| 33 const char kDummyOriginTwo[] = "http://example2.test/"; | 33 const char kDummyOriginTwo[] = "http://example2.test/"; |
| 34 const PermissionType kDummyPermissionOne = PermissionType::GEOLOCATION; | 34 const PermissionType kDummyPermissionOne = PermissionType::GEOLOCATION; |
| 35 const PermissionType kDummyPermissionTwo = PermissionType::NOTIFICATIONS; | 35 const PermissionType kDummyPermissionTwo = PermissionType::NOTIFICATIONS; |
| 36 const PermissionAction kDummyAction = GRANTED; | 36 const PermissionAction kDummyAction = GRANTED; |
| 37 const PermissionSourceUI kDummySourceUI = PermissionSourceUI::PROMPT; | 37 const PermissionSourceUI kDummySourceUI = PermissionSourceUI::PROMPT; |
| 38 const PermissionRequestGestureType kDummyGestureType = | 38 const PermissionRequestGestureType kDummyGestureType = |
| 39 PermissionRequestGestureType::GESTURE; | 39 PermissionRequestGestureType::GESTURE; |
| 40 const PermissionPersistDecision kDummyPersistDecision = |
| 41 PermissionPersistDecision::PERSISTED; |
| 40 const int kDummyNumPriorDismissals = 10; | 42 const int kDummyNumPriorDismissals = 10; |
| 41 const int kDummyNumPriorIgnores = 12; | 43 const int kDummyNumPriorIgnores = 12; |
| 42 | 44 |
| 43 const char kDummyTrialOne[] = "trial one"; | 45 const char kDummyTrialOne[] = "trial one"; |
| 44 const char kDummyGroupOne[] = "group one"; | 46 const char kDummyGroupOne[] = "group one"; |
| 45 const char kDummyTrialTwo[] = "trial two"; | 47 const char kDummyTrialTwo[] = "trial two"; |
| 46 const char kDummyGroupTwo[] = "group two"; | 48 const char kDummyGroupTwo[] = "group two"; |
| 47 | 49 |
| 48 const char kFeatureOnByDefaultName[] = "OnByDefault"; | 50 const char kFeatureOnByDefaultName[] = "OnByDefault"; |
| 49 struct base::Feature kFeatureOnByDefault { | 51 struct base::Feature kFeatureOnByDefault { |
| 50 kFeatureOnByDefaultName, base::FEATURE_ENABLED_BY_DEFAULT | 52 kFeatureOnByDefaultName, base::FEATURE_ENABLED_BY_DEFAULT |
| 51 }; | 53 }; |
| 52 | 54 |
| 53 const char kFeatureOffByDefaultName[] = "OffByDefault"; | 55 const char kFeatureOffByDefaultName[] = "OffByDefault"; |
| 54 struct base::Feature kFeatureOffByDefault { | 56 struct base::Feature kFeatureOffByDefault { |
| 55 kFeatureOffByDefaultName, base::FEATURE_DISABLED_BY_DEFAULT | 57 kFeatureOffByDefaultName, base::FEATURE_DISABLED_BY_DEFAULT |
| 56 }; | 58 }; |
| 57 | 59 |
| 60 PermissionReportInfo BuildDummyReportInfo(const char* requesting_origin, |
| 61 PermissionType permission) { |
| 62 PermissionReportInfo info(GURL(requesting_origin), permission, kDummyAction, |
| 63 kDummySourceUI, kDummyGestureType, kDummyPersistDecision, |
| 64 kDummyNumPriorDismissals, kDummyNumPriorIgnores); |
| 65 |
| 66 return info; |
| 67 } |
| 68 |
| 69 PermissionReportInfo BuildDummyReportInfo() { |
| 70 return BuildDummyReportInfo(kDummyOriginOne, kDummyPermissionOne); |
| 71 } |
| 72 |
| 58 } // namespace | 73 } // namespace |
| 59 | 74 |
| 60 class PermissionReporterTest : public ::testing::Test { | 75 class PermissionReporterTest : public ::testing::Test { |
| 61 protected: | 76 protected: |
| 62 void SetUp() override { | 77 void SetUp() override { |
| 63 mock_report_sender_ = new MockPermissionReportSender; | 78 mock_report_sender_ = new MockPermissionReportSender; |
| 64 clock_ = new base::SimpleTestClock; | 79 clock_ = new base::SimpleTestClock; |
| 65 permission_reporter_.reset(new PermissionReporter( | 80 permission_reporter_.reset(new PermissionReporter( |
| 66 base::WrapUnique(mock_report_sender_), base::WrapUnique(clock_))); | 81 base::WrapUnique(mock_report_sender_), base::WrapUnique(clock_))); |
| 67 } | 82 } |
| 68 | 83 |
| 69 // Owned by |permission_reporter_|. | 84 // Owned by |permission_reporter_|. |
| 70 MockPermissionReportSender* mock_report_sender_; | 85 MockPermissionReportSender* mock_report_sender_; |
| 71 | 86 |
| 72 // Owned by |permission_reporter_|. | 87 // Owned by |permission_reporter_|. |
| 73 base::SimpleTestClock* clock_; | 88 base::SimpleTestClock* clock_; |
| 74 | 89 |
| 75 std::unique_ptr<PermissionReporter> permission_reporter_; | 90 std::unique_ptr<PermissionReporter> permission_reporter_; |
| 76 }; | 91 }; |
| 77 | 92 |
| 78 // Test that PermissionReporter::SendReport sends a serialized report string to | 93 // Test that PermissionReporter::SendReport sends a serialized report string to |
| 79 // SafeBrowsing CSD servers. | 94 // SafeBrowsing CSD servers. |
| 80 TEST_F(PermissionReporterTest, SendReport) { | 95 TEST_F(PermissionReporterTest, SendReport) { |
| 81 permission_reporter_->SendReport(GURL(kDummyOriginOne), kDummyPermissionOne, | 96 permission_reporter_->SendReport(BuildDummyReportInfo()); |
| 82 kDummyAction, kDummySourceUI, | |
| 83 kDummyGestureType, kDummyNumPriorDismissals, | |
| 84 kDummyNumPriorIgnores); | |
| 85 | 97 |
| 86 PermissionReport permission_report; | 98 PermissionReport permission_report; |
| 87 ASSERT_TRUE( | 99 ASSERT_TRUE( |
| 88 permission_report.ParseFromString(mock_report_sender_->latest_report())); | 100 permission_report.ParseFromString(mock_report_sender_->latest_report())); |
| 89 EXPECT_EQ(PermissionReport::GEOLOCATION, permission_report.permission()); | 101 EXPECT_EQ(PermissionReport::GEOLOCATION, permission_report.permission()); |
| 90 EXPECT_EQ(PermissionReport::GRANTED, permission_report.action()); | 102 EXPECT_EQ(PermissionReport::GRANTED, permission_report.action()); |
| 91 EXPECT_EQ(PermissionReport::PROMPT, permission_report.source_ui()); | 103 EXPECT_EQ(PermissionReport::PROMPT, permission_report.source_ui()); |
| 92 EXPECT_EQ(PermissionReport::GESTURE, permission_report.gesture()); | 104 EXPECT_EQ(PermissionReport::GESTURE, permission_report.gesture()); |
| 105 EXPECT_EQ(PermissionReport::PERSISTED, permission_report.persisted()); |
| 93 EXPECT_EQ(kDummyOriginOne, permission_report.origin()); | 106 EXPECT_EQ(kDummyOriginOne, permission_report.origin()); |
| 94 EXPECT_EQ(kDummyNumPriorDismissals, | 107 EXPECT_EQ(kDummyNumPriorDismissals, |
| 95 permission_report.num_prior_dismissals()); | 108 permission_report.num_prior_dismissals()); |
| 96 EXPECT_EQ(kDummyNumPriorIgnores, permission_report.num_prior_ignores()); | 109 EXPECT_EQ(kDummyNumPriorIgnores, permission_report.num_prior_ignores()); |
| 97 #if defined(OS_ANDROID) | 110 #if defined(OS_ANDROID) |
| 98 EXPECT_EQ(PermissionReport::ANDROID_PLATFORM, | 111 EXPECT_EQ(PermissionReport::ANDROID_PLATFORM, |
| 99 permission_report.platform_type()); | 112 permission_report.platform_type()); |
| 100 #elif defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_CHROMEOS) || \ | 113 #elif defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_CHROMEOS) || \ |
| 101 defined(OS_LINUX) | 114 defined(OS_LINUX) |
| 102 EXPECT_EQ(PermissionReport::DESKTOP_PLATFORM, | 115 EXPECT_EQ(PermissionReport::DESKTOP_PLATFORM, |
| (...skipping 28 matching lines...) Expand all Loading... |
| 131 base::FeatureList::ClearInstanceForTesting(); | 144 base::FeatureList::ClearInstanceForTesting(); |
| 132 base::FeatureList::SetInstance(std::move(feature_list)); | 145 base::FeatureList::SetInstance(std::move(feature_list)); |
| 133 | 146 |
| 134 // This is necessary to activate both field trials. | 147 // This is necessary to activate both field trials. |
| 135 base::FeatureList::IsEnabled(kFeatureOnByDefault); | 148 base::FeatureList::IsEnabled(kFeatureOnByDefault); |
| 136 base::FeatureList::IsEnabled(kFeatureOffByDefault); | 149 base::FeatureList::IsEnabled(kFeatureOffByDefault); |
| 137 | 150 |
| 138 EXPECT_TRUE(base::FieldTrialList::IsTrialActive(trial_one->trial_name())); | 151 EXPECT_TRUE(base::FieldTrialList::IsTrialActive(trial_one->trial_name())); |
| 139 EXPECT_TRUE(base::FieldTrialList::IsTrialActive(trial_two->trial_name())); | 152 EXPECT_TRUE(base::FieldTrialList::IsTrialActive(trial_two->trial_name())); |
| 140 | 153 |
| 141 permission_reporter_->SendReport(GURL(kDummyOriginOne), kDummyPermissionOne, | 154 permission_reporter_->SendReport(BuildDummyReportInfo()); |
| 142 kDummyAction, kDummySourceUI, | |
| 143 kDummyGestureType, kDummyNumPriorDismissals, | |
| 144 kDummyNumPriorIgnores); | |
| 145 | 155 |
| 146 PermissionReport permission_report; | 156 PermissionReport permission_report; |
| 147 ASSERT_TRUE( | 157 ASSERT_TRUE( |
| 148 permission_report.ParseFromString(mock_report_sender_->latest_report())); | 158 permission_report.ParseFromString(mock_report_sender_->latest_report())); |
| 149 | 159 |
| 150 variations::ActiveGroupId field_trial_one = | 160 variations::ActiveGroupId field_trial_one = |
| 151 variations::MakeActiveGroupId(kDummyTrialOne, kDummyGroupOne); | 161 variations::MakeActiveGroupId(kDummyTrialOne, kDummyGroupOne); |
| 152 variations::ActiveGroupId field_trial_two = | 162 variations::ActiveGroupId field_trial_two = |
| 153 variations::MakeActiveGroupId(kDummyTrialTwo, kDummyGroupTwo); | 163 variations::MakeActiveGroupId(kDummyTrialTwo, kDummyGroupTwo); |
| 154 ActiveGroupIdSet expected_group_ids = {field_trial_one, field_trial_two}; | 164 ActiveGroupIdSet expected_group_ids = {field_trial_one, field_trial_two}; |
| 155 | 165 |
| 156 EXPECT_EQ(2, permission_report.field_trials().size()); | 166 EXPECT_EQ(2, permission_report.field_trials().size()); |
| 157 for (auto field_trial : permission_report.field_trials()) { | 167 for (auto field_trial : permission_report.field_trials()) { |
| 158 variations::ActiveGroupId group_id = {field_trial.name_id(), | 168 variations::ActiveGroupId group_id = {field_trial.name_id(), |
| 159 field_trial.group_id()}; | 169 field_trial.group_id()}; |
| 160 EXPECT_EQ(1U, expected_group_ids.erase(group_id)); | 170 EXPECT_EQ(1U, expected_group_ids.erase(group_id)); |
| 161 } | 171 } |
| 162 EXPECT_EQ(0U, expected_group_ids.size()); | 172 EXPECT_EQ(0U, expected_group_ids.size()); |
| 163 } | 173 } |
| 164 | 174 |
| 165 // Test that PermissionReporter::IsReportThresholdExceeded returns false only | 175 // Test that PermissionReporter::IsReportThresholdExceeded returns false only |
| 166 // when the number of reports sent in the last one minute per origin per | 176 // when the number of reports sent in the last one minute per origin per |
| 167 // permission is under a threshold. | 177 // permission is under a threshold. |
| 168 TEST_F(PermissionReporterTest, IsReportThresholdExceeded) { | 178 TEST_F(PermissionReporterTest, IsReportThresholdExceeded) { |
| 169 EXPECT_EQ(0, mock_report_sender_->GetAndResetNumberOfReportsSent()); | 179 EXPECT_EQ(0, mock_report_sender_->GetAndResetNumberOfReportsSent()); |
| 170 | 180 |
| 171 int reports_to_send = kMaximumReportsPerOriginPerPermissionPerMinute; | 181 int reports_to_send = kMaximumReportsPerOriginPerPermissionPerMinute; |
| 172 while (reports_to_send--) | 182 while (reports_to_send--) |
| 173 permission_reporter_->SendReport(GURL(kDummyOriginOne), kDummyPermissionOne, | 183 permission_reporter_->SendReport(BuildDummyReportInfo()); |
| 174 kDummyAction, kDummySourceUI, kDummyGestureType, | |
| 175 kDummyNumPriorDismissals, kDummyNumPriorIgnores); | |
| 176 EXPECT_EQ(5, mock_report_sender_->GetAndResetNumberOfReportsSent()); | 184 EXPECT_EQ(5, mock_report_sender_->GetAndResetNumberOfReportsSent()); |
| 177 | 185 |
| 178 permission_reporter_->SendReport(GURL(kDummyOriginOne), kDummyPermissionOne, | 186 permission_reporter_->SendReport(BuildDummyReportInfo()); |
| 179 kDummyAction, kDummySourceUI, kDummyGestureType, | |
| 180 kDummyNumPriorDismissals, kDummyNumPriorIgnores); | |
| 181 EXPECT_EQ(0, mock_report_sender_->GetAndResetNumberOfReportsSent()); | 187 EXPECT_EQ(0, mock_report_sender_->GetAndResetNumberOfReportsSent()); |
| 182 | 188 |
| 183 permission_reporter_->SendReport(GURL(kDummyOriginOne), kDummyPermissionTwo, | 189 permission_reporter_->SendReport( |
| 184 kDummyAction, kDummySourceUI, kDummyGestureType, | 190 BuildDummyReportInfo(kDummyOriginOne, kDummyPermissionTwo)); |
| 185 kDummyNumPriorDismissals, kDummyNumPriorIgnores); | |
| 186 EXPECT_EQ(1, mock_report_sender_->GetAndResetNumberOfReportsSent()); | 191 EXPECT_EQ(1, mock_report_sender_->GetAndResetNumberOfReportsSent()); |
| 187 | 192 |
| 188 permission_reporter_->SendReport(GURL(kDummyOriginTwo), kDummyPermissionOne, | 193 permission_reporter_->SendReport( |
| 189 kDummyAction, kDummySourceUI, kDummyGestureType, | 194 BuildDummyReportInfo(kDummyOriginTwo, kDummyPermissionOne)); |
| 190 kDummyNumPriorDismissals, kDummyNumPriorIgnores); | |
| 191 EXPECT_EQ(1, mock_report_sender_->GetAndResetNumberOfReportsSent()); | 195 EXPECT_EQ(1, mock_report_sender_->GetAndResetNumberOfReportsSent()); |
| 192 | 196 |
| 193 clock_->Advance(base::TimeDelta::FromMinutes(1)); | 197 clock_->Advance(base::TimeDelta::FromMinutes(1)); |
| 194 permission_reporter_->SendReport(GURL(kDummyOriginOne), kDummyPermissionOne, | 198 permission_reporter_->SendReport(BuildDummyReportInfo()); |
| 195 kDummyAction, kDummySourceUI, kDummyGestureType, | |
| 196 kDummyNumPriorDismissals, kDummyNumPriorIgnores); | |
| 197 EXPECT_EQ(0, mock_report_sender_->GetAndResetNumberOfReportsSent()); | |
| 198 | 199 |
| 199 clock_->Advance(base::TimeDelta::FromMicroseconds(1)); | 200 clock_->Advance(base::TimeDelta::FromMicroseconds(1)); |
| 200 permission_reporter_->SendReport(GURL(kDummyOriginOne), kDummyPermissionOne, | 201 permission_reporter_->SendReport(BuildDummyReportInfo()); |
| 201 kDummyAction, kDummySourceUI, kDummyGestureType, | |
| 202 kDummyNumPriorDismissals, kDummyNumPriorIgnores); | |
| 203 EXPECT_EQ(1, mock_report_sender_->GetAndResetNumberOfReportsSent()); | 202 EXPECT_EQ(1, mock_report_sender_->GetAndResetNumberOfReportsSent()); |
| 204 | 203 |
| 205 clock_->Advance(base::TimeDelta::FromMinutes(1)); | 204 clock_->Advance(base::TimeDelta::FromMinutes(1)); |
| 206 reports_to_send = 12; | 205 reports_to_send = 12; |
| 207 while (reports_to_send--) { | 206 while (reports_to_send--) { |
| 208 clock_->Advance(base::TimeDelta::FromSeconds(5)); | 207 clock_->Advance(base::TimeDelta::FromSeconds(5)); |
| 209 permission_reporter_->SendReport(GURL(kDummyOriginOne), kDummyPermissionOne, | 208 permission_reporter_->SendReport(BuildDummyReportInfo()); |
| 210 kDummyAction, kDummySourceUI, kDummyGestureType, | |
| 211 kDummyNumPriorDismissals, kDummyNumPriorIgnores); | |
| 212 } | 209 } |
| 213 EXPECT_EQ(kMaximumReportsPerOriginPerPermissionPerMinute, | 210 EXPECT_EQ(kMaximumReportsPerOriginPerPermissionPerMinute, |
| 214 mock_report_sender_->GetAndResetNumberOfReportsSent()); | 211 mock_report_sender_->GetAndResetNumberOfReportsSent()); |
| 215 } | 212 } |
| 216 | 213 |
| 217 } // namespace safe_browsing | 214 } // namespace safe_browsing |
| OLD | NEW |