Skip to content

Commit 006942b

Browse files
committed
more model changes...
1 parent d34708b commit 006942b

File tree

13 files changed

+321
-138
lines changed

13 files changed

+321
-138
lines changed

src/olympia/abuse/actions.py

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -699,14 +699,7 @@ def should_hold_action(self):
699699
def process_action(self, release_hold=False):
700700
if self.target.status not in (amo.STATUS_DISABLED, amo.STATUS_REJECTED):
701701
self.target.update(status=amo.STATUS_REJECTED)
702-
AddonApprovalsCounter.objects.update_or_create(
703-
addon=self.target,
704-
defaults={
705-
'last_content_review_status': (
706-
AddonApprovalsCounter.CONTENT_REVIEW_STATUSES.FAIL
707-
)
708-
},
709-
)
702+
AddonApprovalsCounter.reject_content_for_addon(self.target)
710703
return self.log_action(amo.LOG.REJECT_LISTING_CONTENT)
711704

712705
def hold_action(self):
@@ -890,16 +883,8 @@ def process_action(self, release_hold=False):
890883
and target.status == amo.STATUS_REJECTED
891884
):
892885
target_versions = target_versions.none()
893-
AddonApprovalsCounter.objects.update_or_create(
894-
addon=target,
895-
defaults={
896-
'last_content_review': datetime.now(),
897-
'last_content_review_status': (
898-
AddonApprovalsCounter.CONTENT_REVIEW_STATUSES.PASS
899-
),
900-
},
901-
)
902-
# Call the function to correct it the status
886+
AddonApprovalsCounter.approve_content_for_addon(target)
887+
# Call update function to correct ihe status
903888
target.update_status()
904889
activity_log_action = amo.LOG.APPROVE_REJECTED_LISTING_CONTENT
905890

@@ -973,15 +958,7 @@ def get_owners(self):
973958

974959
def process_action(self, release_hold=False):
975960
if isinstance(self.target, Addon):
976-
AddonApprovalsCounter.objects.update_or_create(
977-
addon=self.target,
978-
defaults={
979-
'last_content_review': datetime.now(),
980-
'last_content_review_status': (
981-
AddonApprovalsCounter.CONTENT_REVIEW_STATUSES.PASS
982-
),
983-
},
984-
)
961+
AddonApprovalsCounter.approve_content_for_addon(self.target)
985962
if self.status == amo.STATUS_REJECTED:
986963
self.decision.metadata['previous_status'] = self.status
987964
self.decision.save(update_fields=['metadata'])

src/olympia/abuse/tests/test_actions.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -787,7 +787,7 @@ def _test_reporter_content_approved_action_taken(self):
787787

788788
counter = AddonApprovalsCounter.objects.get(addon=self.addon)
789789
assert (
790-
counter.last_content_review_status
790+
counter.content_review_status
791791
== AddonApprovalsCounter.CONTENT_REVIEW_STATUSES.PASS
792792
)
793793
self.assertCloseToNow(counter.last_content_review)
@@ -802,7 +802,7 @@ def _test_reporter_content_approved_action_taken(self):
802802
def test_content_approve_rejected_listing_content(self):
803803
AddonApprovalsCounter.objects.create(
804804
addon=self.addon,
805-
last_content_review_status=AddonApprovalsCounter.CONTENT_REVIEW_STATUSES.REQUESTED,
805+
content_review_status=AddonApprovalsCounter.CONTENT_REVIEW_STATUSES.REQUESTED,
806806
)
807807
self.addon.update(status=amo.STATUS_REJECTED)
808808
action = DECISION_ACTIONS.AMO_APPROVE
@@ -833,7 +833,7 @@ def test_content_approve_rejected_listing_content(self):
833833

834834
counter = AddonApprovalsCounter.objects.get(addon=self.addon)
835835
assert (
836-
counter.last_content_review_status
836+
counter.content_review_status
837837
== AddonApprovalsCounter.CONTENT_REVIEW_STATUSES.PASS
838838
)
839839
self.assertCloseToNow(counter.last_content_review)
@@ -1173,7 +1173,7 @@ def _test_approve_appeal_or_override_but_listing_rejected(self, ContentActionCla
11731173
def test_approve_appeal_success_but_listing_rejected(self):
11741174
AddonApprovalsCounter.objects.create(
11751175
addon=self.addon,
1176-
last_content_review_status=AddonApprovalsCounter.CONTENT_REVIEW_STATUSES.FAIL,
1176+
content_review_status=AddonApprovalsCounter.CONTENT_REVIEW_STATUSES.FAIL,
11771177
)
11781178
self.past_negative_decision.update(appeal_job=self.cinder_job)
11791179
self._test_approve_appeal_or_override_but_listing_rejected(
@@ -1185,7 +1185,7 @@ def test_approve_appeal_success_but_listing_rejected(self):
11851185
def test_approve_override_success_but_listing_rejected(self):
11861186
AddonApprovalsCounter.objects.create(
11871187
addon=self.addon,
1188-
last_content_review_status=AddonApprovalsCounter.CONTENT_REVIEW_STATUSES.FAIL,
1188+
content_review_status=AddonApprovalsCounter.CONTENT_REVIEW_STATUSES.FAIL,
11891189
)
11901190
self.decision.update(override_of=self.past_negative_decision)
11911191
self._test_approve_appeal_or_override_but_listing_rejected(
@@ -1315,7 +1315,7 @@ def test_approve_appeal_success_but_listing_rejected(self):
13151315
self.addon.update(status=amo.STATUS_REJECTED)
13161316
AddonApprovalsCounter.objects.create(
13171317
addon=self.addon,
1318-
last_content_review_status=AddonApprovalsCounter.CONTENT_REVIEW_STATUSES.FAIL,
1318+
content_review_status=AddonApprovalsCounter.CONTENT_REVIEW_STATUSES.FAIL,
13191319
)
13201320
self.past_negative_decision.update(appeal_job=self.cinder_job)
13211321
self._test_approve_appeal_or_override(ContentActionTargetAppealApprove)
@@ -1326,7 +1326,7 @@ def test_approve_override_success_but_listing_rejected(self):
13261326
self.addon.update(status=amo.STATUS_REJECTED)
13271327
AddonApprovalsCounter.objects.create(
13281328
addon=self.addon,
1329-
last_content_review_status=AddonApprovalsCounter.CONTENT_REVIEW_STATUSES.FAIL,
1329+
content_review_status=AddonApprovalsCounter.CONTENT_REVIEW_STATUSES.FAIL,
13301330
)
13311331
self.decision.update(override_of=self.past_negative_decision)
13321332
self._test_approve_appeal_or_override(ContentActionOverrideApprove)

src/olympia/addons/migrations/0059_add_addonapprovalscounter_last_content_review_status.py renamed to src/olympia/addons/migrations/0059_add_addonapprovalscounter_content_review_status.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class Migration(migrations.Migration):
1212
operations = [
1313
migrations.AddField(
1414
model_name='addonapprovalscounter',
15-
name='last_content_review_status',
16-
field=models.SmallIntegerField(choices=[(0, 'Unreviewed'), (1, 'Pass'), (2, 'Fail'), (3, 'New review requested')], db_index=True, null=True),
15+
name='content_review_status',
16+
field=models.SmallIntegerField(choices=[(0, 'Unreviewed'), (1, 'Pending, accepted content changed'), (2, 'Pass'), (3, 'Fail'), (4, 'Pending, New review requested')], db_index=True, null=True),
1717
),
1818
]
Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,37 @@
11
# Generated by Django 4.2.28 on 2026-02-05 11:42
22

3-
from django.db import migrations
3+
from django.db import models, migrations
44

55

6-
def backfill_last_content_review_status(apps, schema_editor):
6+
def backfill_content_review_status(apps, schema_editor):
77
AddonApprovalsCounter = apps.get_model('addons', 'AddonApprovalsCounter')
8-
for counter in AddonApprovalsCounter.objects.filter(last_content_review_status__isnull=True):
8+
for counter in AddonApprovalsCounter.objects.filter(content_review_status__isnull=True):
99
# if we have a last_content_review date then we know it passed, and hasn't changed since
1010
if counter.last_content_review is not None:
11-
counter.last_content_review_status = 1 # CONTENT_REVIEW_STATUSES.PASS
11+
counter.content_review_status = 2 # CONTENT_REVIEW_STATUSES.PASS
12+
# If last_content_review_pass is False we know it failed.
13+
elif counter.last_content_review_pass is False:
14+
counter.content_review_status = 3 # CONTENT_REVIEW_STATUSES.FAIL
1215
# Otherwise we don't know for sure
1316
# - might never have been reviewed (e.g. no listed versions).
1417
# - might have been reviewed and failed.
1518
# - might have been reviewed but then the content changed.
16-
# If last_content_review_pass is False we know it failed though.
17-
elif counter.last_content_review_pass is False:
18-
counter.last_content_review_status = 2 # CONTENT_REVIEW_STATUSES.FAIL
1919
else:
20-
# don't need to save if there wasn't an update.
21-
continue
22-
counter.save(update_fields=['last_content_review_status'])
20+
counter.content_review_status = 0 # CONTENT_REVIEW_STATUSES.UNREVIEWED
21+
counter.save(update_fields=['content_review_status'])
2322

2423

2524
class Migration(migrations.Migration):
2625

2726
dependencies = [
28-
('addons', '0059_add_addonapprovalscounter_last_content_review_status'),
27+
('addons', '0059_add_addonapprovalscounter_content_review_status'),
2928
]
3029

3130
operations = [
32-
migrations.RunPython(backfill_last_content_review_status, reverse_code=migrations.RunPython.noop),
31+
migrations.RunPython(backfill_content_review_status, reverse_code=migrations.RunPython.noop),
32+
migrations.AlterField(
33+
model_name='addonapprovalscounter',
34+
name='content_review_status',
35+
field=models.SmallIntegerField(choices=[(0, 'Unreviewed'), (1, 'Pending, accepted content changed'), (2, 'Pass'), (3, 'Fail'), (4, 'Pending, New review requested')], db_index=True, default=0),
36+
),
3337
]

src/olympia/addons/models.py

Lines changed: 58 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -398,12 +398,14 @@ def get_content_review_queue(self, admin_reviewer=False):
398398
.valid()
399399
.filter(
400400
_current_version__reviewerflags__pending_rejection__isnull=True,
401-
addonapprovalscounter__last_content_review=None,
402401
# Only content review extensions and dictionaries. See
403402
# https://github.com/mozilla/addons-server/issues/11796 &
404403
# https://github.com/mozilla/addons-server/issues/12065
405404
type__in=(amo.ADDON_EXTENSION, amo.ADDON_DICT),
406405
)
406+
.exclude(
407+
addonapprovalscounter__content_review_status__in=AddonApprovalsCounter.CONTENT_REVIEW_STATUSES.COMPLETE
408+
)
407409
.order_by('created')
408410
)
409411
return qs
@@ -1300,7 +1302,7 @@ def update_status(self, ignore_version=None):
13001302
force_update = False
13011303
if AddonApprovalsCounter.objects.filter(
13021304
addon=self,
1303-
last_content_review_status__in=AddonApprovalsCounter.CONTENT_REVIEW_STATUSES.REJECTED,
1305+
content_review_status__in=AddonApprovalsCounter.CONTENT_REVIEW_STATUSES.REJECTED,
13041306
).exists():
13051307
# If the content review failed, the status should stay as rejected
13061308
correct_status = amo.STATUS_REJECTED
@@ -2410,27 +2412,30 @@ class AddonApprovalsCounter(ModelBase):
24102412
add-on
24112413
- last_content_review, the date of the last time a human fully reviewed the
24122414
add-on content (not code).
2413-
- last_content_review_status, the status of the last content review.
2415+
- content_review_status, the status of the last content review.
24142416
"""
24152417

24162418
class CONTENT_REVIEW_STATUSES(EnumChoices):
2417-
AWAITING = 0, 'Content awaiting review'
2418-
PASS = 1, 'Pass'
2419-
FAIL = 2, 'Fail'
2420-
REQUESTED = 3, 'New review requested'
2421-
2422-
__empty__ = 'Unknwon' # i.e. null
2419+
UNREVIEWED = 0, 'Unreviewed'
2420+
CHANGED = 1, 'Pending, accepted content changed'
2421+
PASS = 2, 'Pass'
2422+
FAIL = 3, 'Fail'
2423+
REQUESTED = 4, 'Pending, New review requested'
24232424

24242425
CONTENT_REVIEW_STATUSES.add_subset('REJECTED', ('FAIL', 'REQUESTED'))
2426+
CONTENT_REVIEW_STATUSES.add_subset(
2427+
'PENDING', ('UNREVIEWED', 'CHANGED', 'REQUESTED')
2428+
)
2429+
CONTENT_REVIEW_STATUSES.add_subset('COMPLETE', ('PASS', 'FAIL'))
24252430

24262431
addon = models.OneToOneField(Addon, primary_key=True, on_delete=models.CASCADE)
24272432
counter = models.PositiveIntegerField(default=0)
24282433
last_human_review = models.DateTimeField(null=True)
24292434
last_content_review = models.DateTimeField(null=True, db_index=True)
2430-
last_content_review_status = models.SmallIntegerField(
2435+
content_review_status = models.SmallIntegerField(
24312436
choices=CONTENT_REVIEW_STATUSES.choices,
2432-
null=True,
24332437
db_index=True,
2438+
default=CONTENT_REVIEW_STATUSES.UNREVIEWED,
24342439
)
24352440

24362441
def __str__(self):
@@ -2449,6 +2454,7 @@ def increment_for_addon(cls, addon):
24492454
'counter': 1,
24502455
'last_human_review': now,
24512456
'last_content_review': now,
2457+
'content_review_status': cls.CONTENT_REVIEW_STATUSES.PASS,
24522458
}
24532459
# TODO: rewrite this using update_or_create when we're on django5.2
24542460
# - it supports seperate create and update defaults.
@@ -2469,29 +2475,67 @@ def reset_for_addon(cls, addon):
24692475
@classmethod
24702476
def approve_content_for_addon(cls, addon):
24712477
"""
2472-
Set last_content_review and last_content_review_status to
2478+
Set last_content_review and content_review_status to
24732479
CONTENT_REVIEW_STATUSES.PASS for this addon.
24742480
"""
24752481
obj, _ = cls.objects.update_or_create(
24762482
addon=addon,
24772483
defaults={
24782484
'last_content_review': datetime.now(),
2479-
'last_content_review_status': (
2485+
'content_review_status': (
24802486
AddonApprovalsCounter.CONTENT_REVIEW_STATUSES.PASS
24812487
),
24822488
},
24832489
)
24842490
return obj
24852491

2492+
@classmethod
2493+
def reject_content_for_addon(cls, addon):
2494+
"""
2495+
Set content_review_status to CONTENT_REVIEW_STATUSES.FAIL for this
2496+
addon.
2497+
"""
2498+
obj, _ = cls.objects.update_or_create(
2499+
addon=addon,
2500+
defaults={
2501+
'last_content_review': None,
2502+
'content_review_status': (
2503+
AddonApprovalsCounter.CONTENT_REVIEW_STATUSES.FAIL
2504+
),
2505+
},
2506+
)
2507+
return obj
2508+
24862509
@classmethod
24872510
def reset_content_for_addon(cls, addon):
24882511
"""
24892512
Reset the last_content_review date for this addon so it triggers
24902513
another review.
24912514
"""
2492-
obj, _ = cls.objects.update_or_create(
2515+
obj, created = cls.objects.update_or_create(
24932516
addon=addon, defaults={'last_content_review': None}
24942517
)
2518+
if (
2519+
not created
2520+
and obj.content_review_status == cls.CONTENT_REVIEW_STATUSES.PASS
2521+
):
2522+
obj.update(content_review_status=cls.CONTENT_REVIEW_STATUSES.CHANGED)
2523+
assert obj.last_content_review is None
2524+
return obj
2525+
2526+
@classmethod
2527+
def request_new_content_review_for_addon(cls, addon):
2528+
"""
2529+
Set content_review_status to CONTENT_REVIEW_STATUSES.REQUESTED for this addon.
2530+
"""
2531+
obj, _ = cls.objects.update_or_create(
2532+
addon=addon,
2533+
defaults={
2534+
'content_review_status': (
2535+
AddonApprovalsCounter.CONTENT_REVIEW_STATUSES.REQUESTED
2536+
),
2537+
},
2538+
)
24952539
return obj
24962540

24972541

0 commit comments

Comments
 (0)