WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit bfbabfa

Browse files
committed
Handle average_daily_users of 0 in UsageTier threshold-based rules (#23805)
If a UsageTier includes 0 as the lower bound (or has no lower bound) we still want the ratings/abuse reports thresholds to make sense, so we fall back to 1.
1 parent d4ef59b commit bfbabfa

File tree

4 files changed

+43
-5
lines changed

4 files changed

+43
-5
lines changed

src/olympia/abuse/tests/test_tasks.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ def _high_abuse_reports_setup(field):
4848
# something. The ones missing a lower, upper, or abuse report threshold
4949
# don't do anything for this test.
5050
UsageTier.objects.create(name='Not a tier with usage values')
51+
UsageTier.objects.create(
52+
name='D tier (no lower threshold)',
53+
upper_adu_threshold=100,
54+
**{field: 200},
55+
)
5156
UsageTier.objects.create(
5257
name='C tier (no abuse threshold)',
5358
lower_adu_threshold=100,
@@ -73,7 +78,15 @@ def _high_abuse_reports_setup(field):
7378
)
7479

7580
not_flagged = [
76-
# Belongs to C tier, which doesn't have a growth threshold set.
81+
# Belongs to D tier, below threshold since it has 0 reports/users.
82+
addon_factory(name='D tier empty addon', average_daily_users=0),
83+
# Belongs to D tier, below threshold since it has 1 report and 0 users.
84+
addon_factory_with_abuse_reports(
85+
name='D tier addon below threshold',
86+
average_daily_users=0,
87+
abuse_reports_count=1,
88+
),
89+
# Belongs to C tier, which doesn't have an abuse report threshold set.
7790
addon_factory_with_abuse_reports(
7891
name='C tier addon', average_daily_users=100, abuse_reports_count=2
7992
),
@@ -150,6 +163,11 @@ def _high_abuse_reports_setup(field):
150163
)
151164

152165
flagged = [
166+
addon_factory_with_abuse_reports(
167+
name='D tier addon with reports',
168+
average_daily_users=0,
169+
abuse_reports_count=2,
170+
),
153171
addon_factory_with_abuse_reports(
154172
name='B tier', average_daily_users=200, abuse_reports_count=2
155173
),
@@ -231,6 +249,7 @@ def test_flag_high_abuse_reports_addons_according_to_review_tier():
231249
datetime(2023, 6, 30, 11, 0),
232250
datetime(2023, 7, 3, 11, 0),
233251
datetime(2023, 7, 4, 11, 0),
252+
datetime(2023, 7, 5, 11, 0),
234253
]
235254

236255

src/olympia/ratings/tasks.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ def flag_high_rating_addons_according_to_review_tier():
173173
flagging_tier_filters = Q()
174174
for usage_tier in flagging_tiers:
175175
flagging_tier_filters |= usage_tier.get_rating_threshold_q_object(block=False)
176+
176177
if flagging_tier_filters:
177178
NeedsHumanReview.set_on_addons_latest_signed_versions(
178179
addons_qs.filter(flagging_tier_filters),

src/olympia/ratings/tests/test_tasks.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,11 @@ def _high_ratings_setup(threshold_field):
129129
# something. The ones missing a lower, upper, or rating threshold
130130
# don't do anything for this test.
131131
UsageTier.objects.create(name='Not a tier with usage values')
132+
UsageTier.objects.create(
133+
name='D tier (no lower threshold)',
134+
upper_adu_threshold=100,
135+
**{threshold_field: 200},
136+
)
132137
UsageTier.objects.create(
133138
name='C tier (no rating threshold)',
134139
lower_adu_threshold=100,
@@ -154,7 +159,13 @@ def _high_ratings_setup(threshold_field):
154159
)
155160

156161
not_flagged = [
157-
# Belongs to C tier, which doesn't have a growth threshold set.
162+
# Belongs to D tier, below threshold since it has 0 ratings/users.
163+
addon_factory(name='D tier empty addon', average_daily_users=0),
164+
# Belongs to D tier, below threshold since it has 1 rating and 0 users.
165+
addon_factory_with_ratings(
166+
name='D tier addon below threshold', average_daily_users=0, ratings_count=1
167+
),
168+
# Belongs to C tier, which doesn't have a ratings threshold set.
158169
addon_factory_with_ratings(
159170
name='C tier addon', average_daily_users=100, ratings_count=2
160171
),
@@ -199,6 +210,9 @@ def _high_ratings_setup(threshold_field):
199210
]
200211

201212
flagged = [
213+
addon_factory_with_ratings(
214+
name='D tier addon with ratings', average_daily_users=0, ratings_count=2
215+
),
202216
addon_factory_with_ratings(
203217
name='B tier', average_daily_users=200, ratings_count=2
204218
),
@@ -280,6 +294,7 @@ def test_flag_high_rating_addons_according_to_review_tier():
280294
datetime(2023, 6, 30, 11, 0),
281295
datetime(2023, 7, 3, 11, 0),
282296
datetime(2023, 7, 4, 11, 0),
297+
datetime(2023, 7, 5, 11, 0),
283298
]
284299

285300

src/olympia/reviewers/models.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
from django.conf import settings
55
from django.core.cache import cache
66
from django.db import models
7-
from django.db.models import Avg, Count, F, OuterRef, Q
7+
from django.db.models import Avg, Count, OuterRef, Q
8+
from django.db.models.functions import Greatest
89
from django.dispatch import receiver
910
from django.template import loader
1011
from django.urls import reverse
@@ -876,7 +877,9 @@ def get_abuse_threshold_q_object(self, *, block=False):
876877
else self.abuse_reports_ratio_threshold_before_blocking
877878
) or 0
878879
return Q(
879-
abuse_reports_count__gte=F('average_daily_users') * threshold / 100,
880+
abuse_reports_count__gte=Greatest('average_daily_users', 1)
881+
* threshold
882+
/ 100,
880883
**self.get_tier_boundaries(),
881884
)
882885

@@ -912,7 +915,7 @@ def get_rating_threshold_q_object(self, *, block=False):
912915
else self.ratings_ratio_threshold_before_blocking
913916
) or 0
914917
return Q(
915-
ratings_count__gte=F('average_daily_users') * threshold / 100,
918+
ratings_count__gte=Greatest('average_daily_users', 1) * threshold / 100,
916919
**self.get_tier_boundaries(),
917920
)
918921

0 commit comments

Comments
 (0)