implement admin reviewer unreject versions action (#19728)
* implement admin reviewer unreject versions action * don't subscribe the reviewer to the review * move status setting code to Addon model
This commit is contained in:
Родитель
48667c56f2
Коммит
3fcfd57396
|
@ -1235,6 +1235,22 @@ class Addon(OnChangeMixin, ModelBase):
|
||||||
|
|
||||||
self.update_version(ignore=ignore_version)
|
self.update_version(ignore=ignore_version)
|
||||||
|
|
||||||
|
def update_nominated_status(self, user):
|
||||||
|
# Update the addon status to nominated if there are versions awaiting review
|
||||||
|
if (
|
||||||
|
self.status == amo.STATUS_NULL
|
||||||
|
and self.versions.filter(
|
||||||
|
file__status=amo.STATUS_AWAITING_REVIEW, channel=amo.CHANNEL_LISTED
|
||||||
|
).exists()
|
||||||
|
):
|
||||||
|
log.info(
|
||||||
|
'Changing add-on status [%s]: %s => %s (%s).'
|
||||||
|
% (self.id, self.status, amo.STATUS_NOMINATED, 'unrejecting versions')
|
||||||
|
)
|
||||||
|
self.update(status=amo.STATUS_NOMINATED)
|
||||||
|
activity.log_create(amo.LOG.CHANGE_STATUS, self, self.status, user=user)
|
||||||
|
self.update_version()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def attach_related_versions(addons, addon_dict=None):
|
def attach_related_versions(addons, addon_dict=None):
|
||||||
if addon_dict is None:
|
if addon_dict is None:
|
||||||
|
|
|
@ -2104,6 +2104,29 @@ class TestUpdateStatus(TestCase):
|
||||||
amo.STATUS_NULL
|
amo.STATUS_NULL
|
||||||
) # No listed versions so now NULL
|
) # No listed versions so now NULL
|
||||||
|
|
||||||
|
def test_update_nominated_status(self):
|
||||||
|
addon = addon_factory(
|
||||||
|
status=amo.STATUS_NULL, file_kw={'status': amo.STATUS_DISABLED}
|
||||||
|
)
|
||||||
|
first_version = addon.versions.last()
|
||||||
|
version_factory(addon=addon, file_kw={'status': amo.STATUS_APPROVED})
|
||||||
|
user = user_factory()
|
||||||
|
# if add-on has no files that are AWAITING_REVIEW, the status shouldn't change
|
||||||
|
addon.update_nominated_status(user)
|
||||||
|
assert addon.reload().status == amo.STATUS_NULL
|
||||||
|
|
||||||
|
addon.update(status=amo.STATUS_DISABLED)
|
||||||
|
first_version.file.update(status=amo.STATUS_AWAITING_REVIEW)
|
||||||
|
# and neither should the status change if the addon status isn't NULL
|
||||||
|
addon.update_nominated_status(user)
|
||||||
|
addon.refresh_from_db() # this clears the fk relations too
|
||||||
|
assert addon.status == amo.STATUS_DISABLED
|
||||||
|
|
||||||
|
addon.update(status=amo.STATUS_NULL)
|
||||||
|
# success case - has version that is awaiting review and incomplete addon status
|
||||||
|
addon.update_nominated_status(user)
|
||||||
|
assert addon.reload().status == amo.STATUS_NOMINATED
|
||||||
|
|
||||||
|
|
||||||
class TestGetVersion(TestCase):
|
class TestGetVersion(TestCase):
|
||||||
fixtures = [
|
fixtures = [
|
||||||
|
|
|
@ -844,6 +844,17 @@ class RESTRICTED(_LOG):
|
||||||
format = _('{user} restricted.')
|
format = _('{user} restricted.')
|
||||||
|
|
||||||
|
|
||||||
|
class UNREJECT_VERSION(_LOG):
|
||||||
|
# takes add-on, version
|
||||||
|
id = 171
|
||||||
|
action_class = 'reject'
|
||||||
|
format = _('{addon} {version} unrejected.')
|
||||||
|
short = _('Unrejected')
|
||||||
|
keep = True
|
||||||
|
review_queue = True
|
||||||
|
reviewer_review_action = True
|
||||||
|
|
||||||
|
|
||||||
LOGS = [x for x in vars().values() if isclass(x) and issubclass(x, _LOG) and x != _LOG]
|
LOGS = [x for x in vars().values() if isclass(x) and issubclass(x, _LOG) and x != _LOG]
|
||||||
# Make sure there's no duplicate IDs.
|
# Make sure there's no duplicate IDs.
|
||||||
assert len(LOGS) == len({log.id for log in LOGS})
|
assert len(LOGS) == len({log.id for log in LOGS})
|
||||||
|
|
|
@ -112,11 +112,28 @@ class VersionsChoiceWidget(forms.SelectMultiple):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
actions_filters = {
|
actions_filters = {
|
||||||
amo.STATUS_APPROVED: ('confirm_multiple_versions', 'block_multiple_versions'),
|
amo.CHANNEL_UNLISTED: {
|
||||||
amo.STATUS_AWAITING_REVIEW: (
|
amo.STATUS_APPROVED: (
|
||||||
'reject_multiple_versions',
|
'block_multiple_versions',
|
||||||
'approve_multiple_versions',
|
'confirm_multiple_versions',
|
||||||
),
|
),
|
||||||
|
amo.STATUS_AWAITING_REVIEW: (
|
||||||
|
'approve_multiple_versions',
|
||||||
|
'reject_multiple_versions',
|
||||||
|
),
|
||||||
|
amo.STATUS_DISABLED: ('unreject_multiple_versions',),
|
||||||
|
},
|
||||||
|
amo.CHANNEL_LISTED: {
|
||||||
|
amo.STATUS_APPROVED: (
|
||||||
|
'block_multiple_versions',
|
||||||
|
'reject_multiple_versions',
|
||||||
|
),
|
||||||
|
amo.STATUS_AWAITING_REVIEW: (
|
||||||
|
'approve_multiple_versions',
|
||||||
|
'reject_multiple_versions',
|
||||||
|
),
|
||||||
|
amo.STATUS_DISABLED: ('unreject_multiple_versions',),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
def create_option(self, *args, **kwargs):
|
def create_option(self, *args, **kwargs):
|
||||||
|
@ -126,13 +143,12 @@ class VersionsChoiceWidget(forms.SelectMultiple):
|
||||||
obj = option['label']
|
obj = option['label']
|
||||||
status = obj.file.status if obj.file else None
|
status = obj.file.status if obj.file else None
|
||||||
versions_actions = getattr(self, 'versions_actions', None)
|
versions_actions = getattr(self, 'versions_actions', None)
|
||||||
if versions_actions and obj.channel == amo.CHANNEL_UNLISTED:
|
if versions_actions:
|
||||||
# For unlisted, some actions should only apply to approved/pending
|
# Add our special `data-toggle` class and the right `data-value` depending
|
||||||
# versions, so we add our special `data-toggle` class and the
|
# on status.
|
||||||
# right `data-value` depending on status.
|
|
||||||
option['attrs']['class'] = 'data-toggle'
|
option['attrs']['class'] = 'data-toggle'
|
||||||
option['attrs']['data-value'] = '|'.join(
|
option['attrs']['data-value'] = '|'.join(
|
||||||
self.actions_filters.get(status, ()) + ('',)
|
self.actions_filters[obj.channel].get(status, ()) + ('',)
|
||||||
)
|
)
|
||||||
# Just in case, let's now force the label to be a string (it would be
|
# Just in case, let's now force the label to be a string (it would be
|
||||||
# converted anyway, but it's probably safer that way).
|
# converted anyway, but it's probably safer that way).
|
||||||
|
@ -218,7 +234,7 @@ class ReviewForm(forms.Form):
|
||||||
if action:
|
if action:
|
||||||
if not action.get('comments', True):
|
if not action.get('comments', True):
|
||||||
self.fields['comments'].required = False
|
self.fields['comments'].required = False
|
||||||
if action.get('versions', False):
|
if action.get('multiple_versions', False):
|
||||||
self.fields['versions'].required = True
|
self.fields['versions'].required = True
|
||||||
if not action.get('requires_reasons', False):
|
if not action.get('requires_reasons', False):
|
||||||
self.fields['reasons'].required = False
|
self.fields['reasons'].required = False
|
||||||
|
@ -255,18 +271,19 @@ class ReviewForm(forms.Form):
|
||||||
# if the relevant actions are available, otherwise we don't really care
|
# if the relevant actions are available, otherwise we don't really care
|
||||||
# about this field.
|
# about this field.
|
||||||
versions_actions = [
|
versions_actions = [
|
||||||
k for k in self.helper.actions if self.helper.actions[k].get('versions')
|
k
|
||||||
|
for k in self.helper.actions
|
||||||
|
if self.helper.actions[k].get('multiple_versions')
|
||||||
]
|
]
|
||||||
if versions_actions:
|
if versions_actions:
|
||||||
if self.helper.version:
|
if self.helper.version:
|
||||||
channel = self.helper.version.channel
|
channel = self.helper.version.channel
|
||||||
else:
|
else:
|
||||||
channel = amo.CHANNEL_LISTED
|
channel = amo.CHANNEL_LISTED
|
||||||
statuses = (amo.STATUS_APPROVED, amo.STATUS_AWAITING_REVIEW)
|
|
||||||
self.fields['versions'].widget.versions_actions = versions_actions
|
self.fields['versions'].widget.versions_actions = versions_actions
|
||||||
self.fields['versions'].queryset = (
|
self.fields['versions'].queryset = (
|
||||||
self.helper.addon.versions(manager='unfiltered_for_relations')
|
self.helper.addon.versions(manager='unfiltered_for_relations')
|
||||||
.filter(channel=channel, file__status__in=statuses)
|
.filter(channel=channel)
|
||||||
.no_transforms()
|
.no_transforms()
|
||||||
.select_related('file')
|
.select_related('file')
|
||||||
.select_related('autoapprovalsummary')
|
.select_related('autoapprovalsummary')
|
||||||
|
|
|
@ -61,6 +61,16 @@ class TestReviewForm(TestCase):
|
||||||
)
|
)
|
||||||
assert list(actions.keys()) == ['reply', 'super', 'comment']
|
assert list(actions.keys()) == ['reply', 'super', 'comment']
|
||||||
|
|
||||||
|
# If an admin reviewer we also show unreject_multiple_versions
|
||||||
|
self.grant_permission(self.request.user, 'Reviews:Admin')
|
||||||
|
actions = self.get_form().helper.get_actions()
|
||||||
|
assert list(actions.keys()) == [
|
||||||
|
'unreject_multiple_versions',
|
||||||
|
'reply',
|
||||||
|
'super',
|
||||||
|
'comment',
|
||||||
|
]
|
||||||
|
|
||||||
def test_actions_addon_status_deleted(self):
|
def test_actions_addon_status_deleted(self):
|
||||||
# If the add-on is deleted we only show reply, comment and
|
# If the add-on is deleted we only show reply, comment and
|
||||||
# super review.
|
# super review.
|
||||||
|
@ -84,7 +94,18 @@ class TestReviewForm(TestCase):
|
||||||
'comment',
|
'comment',
|
||||||
]
|
]
|
||||||
|
|
||||||
# The add-on is already disabled so we don't show
|
# If an admin reviewer we also show unreject_multiple_versions
|
||||||
|
self.grant_permission(self.request.user, 'Reviews:Admin')
|
||||||
|
actions = self.get_form().helper.get_actions()
|
||||||
|
assert list(actions.keys()) == [
|
||||||
|
'reject_multiple_versions',
|
||||||
|
'unreject_multiple_versions',
|
||||||
|
'reply',
|
||||||
|
'super',
|
||||||
|
'comment',
|
||||||
|
]
|
||||||
|
|
||||||
|
# The add-on is already disabled so we don't show unreject_multiple_versions or
|
||||||
# reject_multiple_versions, but reply/super/comment are still present.
|
# reject_multiple_versions, but reply/super/comment are still present.
|
||||||
actions = self.set_statuses_and_get_actions(
|
actions = self.set_statuses_and_get_actions(
|
||||||
addon_status=amo.STATUS_DISABLED, file_status=amo.STATUS_DISABLED
|
addon_status=amo.STATUS_DISABLED, file_status=amo.STATUS_DISABLED
|
||||||
|
@ -266,14 +287,24 @@ class TestReviewForm(TestCase):
|
||||||
assert form.fields['versions'].required is False
|
assert form.fields['versions'].required is False
|
||||||
assert list(form.fields['versions'].queryset) == [self.addon.current_version]
|
assert list(form.fields['versions'].queryset) == [self.addon.current_version]
|
||||||
|
|
||||||
def test_versions_queryset_contains_pending_files_for_listed(self):
|
def test_versions_queryset_contains_pending_files_for_listed(
|
||||||
|
self, select_data_value='reject_multiple_versions|'
|
||||||
|
):
|
||||||
|
# We hide some of the versions using JavaScript + some data attributes on each
|
||||||
|
# <option>.
|
||||||
|
# The queryset should contain both pending, rejected, and approved versions.
|
||||||
self.grant_permission(self.request.user, 'Addons:Review')
|
self.grant_permission(self.request.user, 'Addons:Review')
|
||||||
addon_factory() # Extra add-on, shouldn't be included.
|
addon_factory() # Extra add-on, shouldn't be included.
|
||||||
version_factory(
|
pending_version = version_factory(
|
||||||
addon=self.addon,
|
addon=self.addon,
|
||||||
channel=amo.CHANNEL_LISTED,
|
channel=amo.CHANNEL_LISTED,
|
||||||
file_kw={'status': amo.STATUS_AWAITING_REVIEW},
|
file_kw={'status': amo.STATUS_AWAITING_REVIEW},
|
||||||
)
|
)
|
||||||
|
rejected_version = version_factory(
|
||||||
|
addon=self.addon,
|
||||||
|
channel=amo.CHANNEL_LISTED,
|
||||||
|
file_kw={'status': amo.STATUS_DISABLED},
|
||||||
|
)
|
||||||
# auto-approve everything (including self.addon.current_version)
|
# auto-approve everything (including self.addon.current_version)
|
||||||
for version in Version.unfiltered.all():
|
for version in Version.unfiltered.all():
|
||||||
AutoApprovalSummary.objects.create(
|
AutoApprovalSummary.objects.create(
|
||||||
|
@ -285,35 +316,71 @@ class TestReviewForm(TestCase):
|
||||||
assert list(form.fields['versions'].queryset) == list(
|
assert list(form.fields['versions'].queryset) == list(
|
||||||
self.addon.versions.all().order_by('pk')
|
self.addon.versions.all().order_by('pk')
|
||||||
)
|
)
|
||||||
assert form.fields['versions'].queryset.count() == 2
|
assert form.fields['versions'].queryset.count() == 3
|
||||||
|
|
||||||
content = str(form['versions'])
|
content = str(form['versions'])
|
||||||
doc = pq(content)
|
doc = pq(content)
|
||||||
|
|
||||||
# <select> should have 'data-toggle' class and data-value attribute to
|
# <select> should have 'data-toggle' class and data-value attribute to
|
||||||
# show/hide it depending on action in JavaScript.
|
# show/hide it depending on action in JavaScript.
|
||||||
select = doc('select')[0]
|
select = doc('select')[0]
|
||||||
select.attrib.get('class') == 'data-toggle'
|
select.attrib.get('class') == 'data-toggle'
|
||||||
assert select.attrib.get('data-value') == 'reject_multiple_versions|'
|
assert select.attrib.get('data-value') == select_data_value
|
||||||
|
|
||||||
# <option>s shouldn't, because for listed review they will all be
|
# <option>s should as well, and the value depends on which version:
|
||||||
# shown. They should still have a value attribute however.
|
# the approved one and the pending one should have different values.
|
||||||
options = doc('option')
|
assert len(doc('option')) == 3
|
||||||
assert len(options) == 2
|
option1 = doc('option[value="%s"]' % self.version.pk)[0]
|
||||||
for option in options:
|
assert option1.attrib.get('class') == 'data-toggle'
|
||||||
assert option.attrib.get('class') is None
|
assert option1.attrib.get('data-value') == (
|
||||||
assert option.attrib.get('data-value') is None
|
# That version is approved.
|
||||||
assert option.attrib.get('value')
|
'block_multiple_versions|reject_multiple_versions|'
|
||||||
|
)
|
||||||
|
assert option1.attrib.get('value') == str(self.version.pk)
|
||||||
|
|
||||||
def test_versions_queryset_contains_pending_files_for_unlisted(self):
|
option2 = doc('option[value="%s"]' % pending_version.pk)[0]
|
||||||
# We also return pending versions for unlisted, but hide some of the
|
assert option2.attrib.get('class') == 'data-toggle'
|
||||||
# versions using JavaScript + some data attributes on each <option>.
|
assert option2.attrib.get('data-value') == (
|
||||||
# The queryset should contain both pending and approved versions.
|
# That version is pending.
|
||||||
|
'approve_multiple_versions|reject_multiple_versions|'
|
||||||
|
)
|
||||||
|
assert option2.attrib.get('value') == str(pending_version.pk)
|
||||||
|
|
||||||
|
option3 = doc('option[value="%s"]' % rejected_version.pk)[0]
|
||||||
|
assert option3.attrib.get('class') == 'data-toggle'
|
||||||
|
assert option3.attrib.get('data-value') == (
|
||||||
|
# That version is rejected.
|
||||||
|
'unreject_multiple_versions|'
|
||||||
|
)
|
||||||
|
assert option3.attrib.get('value') == str(rejected_version.pk)
|
||||||
|
|
||||||
|
def test_versions_queryset_contains_pending_files_for_listed_admin_reviewer(self):
|
||||||
|
self.grant_permission(self.request.user, 'Reviews:Admin')
|
||||||
|
self.test_versions_queryset_contains_pending_files_for_listed(
|
||||||
|
select_data_value='reject_multiple_versions|unreject_multiple_versions|'
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_versions_queryset_contains_pending_files_for_unlisted(
|
||||||
|
self,
|
||||||
|
select_data_value=(
|
||||||
|
'approve_multiple_versions|reject_multiple_versions|'
|
||||||
|
'block_multiple_versions|confirm_multiple_versions|'
|
||||||
|
),
|
||||||
|
):
|
||||||
|
# We hide some of the versions using JavaScript + some data attributes on each
|
||||||
|
# <option>.
|
||||||
|
# The queryset should contain both pending, rejected, and approved versions.
|
||||||
addon_factory() # Extra add-on, shouldn't be included.
|
addon_factory() # Extra add-on, shouldn't be included.
|
||||||
pending_version = version_factory(
|
pending_version = version_factory(
|
||||||
addon=self.addon,
|
addon=self.addon,
|
||||||
channel=amo.CHANNEL_UNLISTED,
|
channel=amo.CHANNEL_UNLISTED,
|
||||||
file_kw={'status': amo.STATUS_AWAITING_REVIEW},
|
file_kw={'status': amo.STATUS_AWAITING_REVIEW},
|
||||||
)
|
)
|
||||||
|
rejected_version = version_factory(
|
||||||
|
addon=self.addon,
|
||||||
|
channel=amo.CHANNEL_UNLISTED,
|
||||||
|
file_kw={'status': amo.STATUS_DISABLED},
|
||||||
|
)
|
||||||
self.version.update(channel=amo.CHANNEL_UNLISTED)
|
self.version.update(channel=amo.CHANNEL_UNLISTED)
|
||||||
# auto-approve everything
|
# auto-approve everything
|
||||||
for version in Version.unfiltered.all():
|
for version in Version.unfiltered.all():
|
||||||
|
@ -334,27 +401,25 @@ class TestReviewForm(TestCase):
|
||||||
assert list(form.fields['versions'].queryset) == list(
|
assert list(form.fields['versions'].queryset) == list(
|
||||||
self.addon.versions.all().order_by('pk')
|
self.addon.versions.all().order_by('pk')
|
||||||
)
|
)
|
||||||
assert form.fields['versions'].queryset.count() == 2
|
assert form.fields['versions'].queryset.count() == 3
|
||||||
|
|
||||||
content = str(form['versions'])
|
content = str(form['versions'])
|
||||||
doc = pq(content)
|
doc = pq(content)
|
||||||
|
|
||||||
# <select> should have 'data-toggle' class and data-value attribute to
|
# <select> should have 'data-toggle' class and data-value attribute to
|
||||||
# show/hide it depending on action in JavaScript.
|
# show/hide it depending on action in JavaScript.
|
||||||
select = doc('select')[0]
|
select = doc('select')[0]
|
||||||
select.attrib.get('class') == 'data-toggle'
|
select.attrib.get('class') == 'data-toggle'
|
||||||
assert select.attrib.get('data-value') == (
|
assert select.attrib.get('data-value') == select_data_value
|
||||||
'approve_multiple_versions|reject_multiple_versions|'
|
|
||||||
'block_multiple_versions|confirm_multiple_versions|'
|
|
||||||
)
|
|
||||||
|
|
||||||
# <option>s should as well, and the value depends on which version:
|
# <option>s should as well, and the value depends on which version:
|
||||||
# the approved one and the pending one should have different values.
|
# the approved one and the pending one should have different values.
|
||||||
assert len(doc('option')) == 2
|
assert len(doc('option')) == 3
|
||||||
option1 = doc('option[value="%s"]' % self.version.pk)[0]
|
option1 = doc('option[value="%s"]' % self.version.pk)[0]
|
||||||
assert option1.attrib.get('class') == 'data-toggle'
|
assert option1.attrib.get('class') == 'data-toggle'
|
||||||
assert option1.attrib.get('data-value') == (
|
assert option1.attrib.get('data-value') == (
|
||||||
# That version is approved.
|
# That version is approved.
|
||||||
'confirm_multiple_versions|block_multiple_versions|'
|
'block_multiple_versions|confirm_multiple_versions|'
|
||||||
)
|
)
|
||||||
assert option1.attrib.get('value') == str(self.version.pk)
|
assert option1.attrib.get('value') == str(self.version.pk)
|
||||||
|
|
||||||
|
@ -362,10 +427,28 @@ class TestReviewForm(TestCase):
|
||||||
assert option2.attrib.get('class') == 'data-toggle'
|
assert option2.attrib.get('class') == 'data-toggle'
|
||||||
assert option2.attrib.get('data-value') == (
|
assert option2.attrib.get('data-value') == (
|
||||||
# That version is pending.
|
# That version is pending.
|
||||||
'reject_multiple_versions|approve_multiple_versions|'
|
'approve_multiple_versions|reject_multiple_versions|'
|
||||||
)
|
)
|
||||||
assert option2.attrib.get('value') == str(pending_version.pk)
|
assert option2.attrib.get('value') == str(pending_version.pk)
|
||||||
|
|
||||||
|
option3 = doc('option[value="%s"]' % rejected_version.pk)[0]
|
||||||
|
assert option3.attrib.get('class') == 'data-toggle'
|
||||||
|
assert option3.attrib.get('data-value') == (
|
||||||
|
# That version is rejected.
|
||||||
|
'unreject_multiple_versions|'
|
||||||
|
)
|
||||||
|
assert option3.attrib.get('value') == str(rejected_version.pk)
|
||||||
|
|
||||||
|
def test_versions_queryset_contains_pending_files_for_unlisted_admin_reviewer(self):
|
||||||
|
self.grant_permission(self.request.user, 'Reviews:Admin')
|
||||||
|
self.test_versions_queryset_contains_pending_files_for_unlisted(
|
||||||
|
select_data_value=(
|
||||||
|
'approve_multiple_versions|reject_multiple_versions|'
|
||||||
|
'unreject_multiple_versions|block_multiple_versions|'
|
||||||
|
'confirm_multiple_versions|'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
def test_versions_required(self):
|
def test_versions_required(self):
|
||||||
# auto-approve everything (including self.addon.current_version)
|
# auto-approve everything (including self.addon.current_version)
|
||||||
for version in Version.unfiltered.all():
|
for version in Version.unfiltered.all():
|
||||||
|
|
|
@ -73,9 +73,9 @@ class TestReviewHelperBase(TestCase):
|
||||||
|
|
||||||
self.user = UserProfile.objects.get(pk=10482)
|
self.user = UserProfile.objects.get(pk=10482)
|
||||||
self.addon = Addon.objects.get(pk=3615)
|
self.addon = Addon.objects.get(pk=3615)
|
||||||
self.version = self.addon.versions.all()[0]
|
self.review_version = self.addon.versions.all()[0]
|
||||||
self.helper = self.get_helper()
|
self.helper = self.get_helper()
|
||||||
self.file = self.version.file
|
self.file = self.review_version.file
|
||||||
|
|
||||||
self.create_paths()
|
self.create_paths()
|
||||||
|
|
||||||
|
@ -110,7 +110,8 @@ class TestReviewHelperBase(TestCase):
|
||||||
self.file.update(status=file_status)
|
self.file.update(status=file_status)
|
||||||
if channel == amo.CHANNEL_UNLISTED:
|
if channel == amo.CHANNEL_UNLISTED:
|
||||||
self.make_addon_unlisted(self.addon)
|
self.make_addon_unlisted(self.addon)
|
||||||
self.version.reload()
|
if self.review_version:
|
||||||
|
self.review_version.reload()
|
||||||
self.file.reload()
|
self.file.reload()
|
||||||
self.helper = self.get_helper(
|
self.helper = self.get_helper(
|
||||||
content_review=content_review, human_review=human_review
|
content_review=content_review, human_review=human_review
|
||||||
|
@ -129,7 +130,7 @@ class TestReviewHelperBase(TestCase):
|
||||||
def get_helper(self, content_review=False, human_review=True):
|
def get_helper(self, content_review=False, human_review=True):
|
||||||
return ReviewHelper(
|
return ReviewHelper(
|
||||||
addon=self.addon,
|
addon=self.addon,
|
||||||
version=self.version,
|
version=self.review_version,
|
||||||
user=self.user,
|
user=self.user,
|
||||||
human_review=human_review,
|
human_review=human_review,
|
||||||
content_review=content_review,
|
content_review=content_review,
|
||||||
|
@ -173,7 +174,7 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
def test_review_files(self):
|
def test_review_files(self):
|
||||||
version_factory(
|
version_factory(
|
||||||
addon=self.addon,
|
addon=self.addon,
|
||||||
created=self.version.created - timedelta(days=1),
|
created=self.review_version.created - timedelta(days=1),
|
||||||
file_kw={'status': amo.STATUS_APPROVED},
|
file_kw={'status': amo.STATUS_APPROVED},
|
||||||
)
|
)
|
||||||
for status in REVIEW_FILES_STATUSES:
|
for status in REVIEW_FILES_STATUSES:
|
||||||
|
@ -396,7 +397,7 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
"""Deleted addons and addons with no versions in that channel have no
|
"""Deleted addons and addons with no versions in that channel have no
|
||||||
version set."""
|
version set."""
|
||||||
expected = []
|
expected = []
|
||||||
self.version = None
|
self.review_version = None
|
||||||
assert (
|
assert (
|
||||||
list(
|
list(
|
||||||
self.get_review_actions(
|
self.get_review_actions(
|
||||||
|
@ -556,6 +557,7 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
'public',
|
'public',
|
||||||
'reject',
|
'reject',
|
||||||
'reject_multiple_versions',
|
'reject_multiple_versions',
|
||||||
|
'unreject_multiple_versions',
|
||||||
'reply',
|
'reply',
|
||||||
'super',
|
'super',
|
||||||
'comment',
|
'comment',
|
||||||
|
@ -573,7 +575,7 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
def test_actions_unlisted(self):
|
def test_actions_unlisted(self):
|
||||||
# Just regular review permissions don't let you do much on an unlisted
|
# Just regular review permissions don't let you do much on an unlisted
|
||||||
# review page.
|
# review page.
|
||||||
self.version.update(channel=amo.CHANNEL_UNLISTED)
|
self.review_version.update(channel=amo.CHANNEL_UNLISTED)
|
||||||
self.grant_permission(self.user, 'Addons:Review')
|
self.grant_permission(self.user, 'Addons:Review')
|
||||||
expected = ['reply', 'super', 'comment']
|
expected = ['reply', 'super', 'comment']
|
||||||
assert (
|
assert (
|
||||||
|
@ -653,7 +655,7 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
)
|
)
|
||||||
|
|
||||||
# it's okay if the version is outside the blocked range though
|
# it's okay if the version is outside the blocked range though
|
||||||
block.update(min_version=self.version.version + '.1')
|
block.update(min_version=self.review_version.version + '.1')
|
||||||
expected = [
|
expected = [
|
||||||
'public',
|
'public',
|
||||||
'reject',
|
'reject',
|
||||||
|
@ -672,7 +674,7 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
version=self.addon.current_version, verdict=amo.AUTO_APPROVED
|
version=self.addon.current_version, verdict=amo.AUTO_APPROVED
|
||||||
)
|
)
|
||||||
version_review_flags_factory(
|
version_review_flags_factory(
|
||||||
version=self.version, pending_rejection=datetime.now()
|
version=self.review_version, pending_rejection=datetime.now()
|
||||||
)
|
)
|
||||||
expected = ['reply', 'super', 'comment']
|
expected = ['reply', 'super', 'comment']
|
||||||
assert (
|
assert (
|
||||||
|
@ -693,8 +695,8 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
'super',
|
'super',
|
||||||
'comment',
|
'comment',
|
||||||
]
|
]
|
||||||
self.version = version_factory(addon=self.addon)
|
self.review_version = version_factory(addon=self.addon)
|
||||||
self.file = self.version.file
|
self.file = self.review_version.file
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
list(
|
list(
|
||||||
|
@ -715,11 +717,12 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
version=self.addon.current_version, verdict=amo.AUTO_APPROVED
|
version=self.addon.current_version, verdict=amo.AUTO_APPROVED
|
||||||
)
|
)
|
||||||
version_review_flags_factory(
|
version_review_flags_factory(
|
||||||
version=self.version, pending_rejection=datetime.now()
|
version=self.review_version, pending_rejection=datetime.now()
|
||||||
)
|
)
|
||||||
expected = [
|
expected = [
|
||||||
'confirm_auto_approved',
|
'confirm_auto_approved',
|
||||||
'reject_multiple_versions',
|
'reject_multiple_versions',
|
||||||
|
'unreject_multiple_versions',
|
||||||
'reply',
|
'reply',
|
||||||
'super',
|
'super',
|
||||||
'comment',
|
'comment',
|
||||||
|
@ -743,12 +746,13 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
'reject',
|
'reject',
|
||||||
'confirm_auto_approved',
|
'confirm_auto_approved',
|
||||||
'reject_multiple_versions',
|
'reject_multiple_versions',
|
||||||
|
'unreject_multiple_versions',
|
||||||
'reply',
|
'reply',
|
||||||
'super',
|
'super',
|
||||||
'comment',
|
'comment',
|
||||||
]
|
]
|
||||||
self.version = version_factory(addon=self.addon)
|
self.review_version = version_factory(addon=self.addon)
|
||||||
self.file = self.version.file
|
self.file = self.review_version.file
|
||||||
assert (
|
assert (
|
||||||
list(
|
list(
|
||||||
self.get_review_actions(
|
self.get_review_actions(
|
||||||
|
@ -789,9 +793,9 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
|
|
||||||
def test_set_file(self):
|
def test_set_file(self):
|
||||||
self.file.update(datestatuschanged=yesterday)
|
self.file.update(datestatuschanged=yesterday)
|
||||||
self.helper.handler.set_file(amo.STATUS_APPROVED, self.version.file)
|
self.helper.handler.set_file(amo.STATUS_APPROVED, self.review_version.file)
|
||||||
|
|
||||||
self.file = self.version.file
|
self.file = self.review_version.file
|
||||||
assert self.file.status == amo.STATUS_APPROVED
|
assert self.file.status == amo.STATUS_APPROVED
|
||||||
assert self.file.datestatuschanged.date() > yesterday.date()
|
assert self.file.datestatuschanged.date() > yesterday.date()
|
||||||
|
|
||||||
|
@ -835,8 +839,8 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
self.helper.set_data(self.get_data())
|
self.helper.set_data(self.get_data())
|
||||||
base_fragment = 'To respond, please reply to this email or visit'
|
base_fragment = 'To respond, please reply to this email or visit'
|
||||||
user = self.addon.listed_authors[0]
|
user = self.addon.listed_authors[0]
|
||||||
ActivityLogToken.objects.create(version=self.version, user=user)
|
ActivityLogToken.objects.create(version=self.review_version, user=user)
|
||||||
uuid = self.version.token.get(user=user).uuid.hex
|
uuid = self.review_version.token.get(user=user).uuid.hex
|
||||||
reply_email = f'reviewreply+{uuid}@{settings.INBOUND_EMAIL_DOMAIN}'
|
reply_email = f'reviewreply+{uuid}@{settings.INBOUND_EMAIL_DOMAIN}'
|
||||||
|
|
||||||
templates = (
|
templates = (
|
||||||
|
@ -951,7 +955,7 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
status = amo.STATUS_NOMINATED
|
status = amo.STATUS_NOMINATED
|
||||||
self.setup_data(status)
|
self.setup_data(status)
|
||||||
AutoApprovalSummary.objects.create(
|
AutoApprovalSummary.objects.create(
|
||||||
version=self.version, verdict=amo.AUTO_APPROVED, weight=101
|
version=self.review_version, verdict=amo.AUTO_APPROVED, weight=101
|
||||||
)
|
)
|
||||||
|
|
||||||
# Make sure we have no public files
|
# Make sure we have no public files
|
||||||
|
@ -985,31 +989,31 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
|
|
||||||
def test_nomination_to_public_need_human_review(self):
|
def test_nomination_to_public_need_human_review(self):
|
||||||
self.setup_data(amo.STATUS_NOMINATED)
|
self.setup_data(amo.STATUS_NOMINATED)
|
||||||
self.version.update(needs_human_review=True)
|
self.review_version.update(needs_human_review=True)
|
||||||
self.helper.handler.approve_latest_version()
|
self.helper.handler.approve_latest_version()
|
||||||
self.addon.reload()
|
self.addon.reload()
|
||||||
self.version.reload()
|
self.review_version.reload()
|
||||||
self.file.reload()
|
self.file.reload()
|
||||||
assert self.addon.status == amo.STATUS_APPROVED
|
assert self.addon.status == amo.STATUS_APPROVED
|
||||||
assert self.file.status == amo.STATUS_APPROVED
|
assert self.file.status == amo.STATUS_APPROVED
|
||||||
assert not self.version.needs_human_review
|
assert not self.review_version.needs_human_review
|
||||||
|
|
||||||
def test_nomination_to_public_need_human_review_not_human(self):
|
def test_nomination_to_public_need_human_review_not_human(self):
|
||||||
self.setup_data(amo.STATUS_NOMINATED, human_review=False)
|
self.setup_data(amo.STATUS_NOMINATED, human_review=False)
|
||||||
self.version.update(needs_human_review=True)
|
self.review_version.update(needs_human_review=True)
|
||||||
self.helper.handler.approve_latest_version()
|
self.helper.handler.approve_latest_version()
|
||||||
self.addon.reload()
|
self.addon.reload()
|
||||||
self.version.reload()
|
self.review_version.reload()
|
||||||
self.file.reload()
|
self.file.reload()
|
||||||
assert self.addon.status == amo.STATUS_APPROVED
|
assert self.addon.status == amo.STATUS_APPROVED
|
||||||
assert self.file.status == amo.STATUS_APPROVED
|
assert self.file.status == amo.STATUS_APPROVED
|
||||||
assert self.version.needs_human_review
|
assert self.review_version.needs_human_review
|
||||||
|
|
||||||
def test_unlisted_approve_latest_version_need_human_review(self):
|
def test_unlisted_approve_latest_version_need_human_review(self):
|
||||||
self.setup_data(amo.STATUS_NULL, channel=amo.CHANNEL_UNLISTED)
|
self.setup_data(amo.STATUS_NULL, channel=amo.CHANNEL_UNLISTED)
|
||||||
self.version.update(needs_human_review=True)
|
self.review_version.update(needs_human_review=True)
|
||||||
flags = version_review_flags_factory(
|
flags = version_review_flags_factory(
|
||||||
version=self.version,
|
version=self.review_version,
|
||||||
needs_human_review_by_mad=True,
|
needs_human_review_by_mad=True,
|
||||||
)
|
)
|
||||||
AddonReviewerFlags.objects.create(
|
AddonReviewerFlags.objects.create(
|
||||||
|
@ -1017,13 +1021,13 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
)
|
)
|
||||||
self.helper.handler.approve_latest_version()
|
self.helper.handler.approve_latest_version()
|
||||||
self.addon.reload()
|
self.addon.reload()
|
||||||
self.version.reload()
|
self.review_version.reload()
|
||||||
self.file.reload()
|
self.file.reload()
|
||||||
flags.reload()
|
flags.reload()
|
||||||
addon_flags = self.addon.reviewerflags.reload()
|
addon_flags = self.addon.reviewerflags.reload()
|
||||||
assert self.addon.status == amo.STATUS_NULL
|
assert self.addon.status == amo.STATUS_NULL
|
||||||
assert self.file.status == amo.STATUS_APPROVED
|
assert self.file.status == amo.STATUS_APPROVED
|
||||||
assert not self.version.needs_human_review
|
assert not self.review_version.needs_human_review
|
||||||
assert not flags.needs_human_review_by_mad
|
assert not flags.needs_human_review_by_mad
|
||||||
assert not addon_flags.auto_approval_disabled_until_next_approval_unlisted
|
assert not addon_flags.auto_approval_disabled_until_next_approval_unlisted
|
||||||
|
|
||||||
|
@ -1031,22 +1035,22 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
self.setup_data(
|
self.setup_data(
|
||||||
amo.STATUS_NULL, channel=amo.CHANNEL_UNLISTED, human_review=False
|
amo.STATUS_NULL, channel=amo.CHANNEL_UNLISTED, human_review=False
|
||||||
)
|
)
|
||||||
self.version.update(needs_human_review=True)
|
self.review_version.update(needs_human_review=True)
|
||||||
flags = version_review_flags_factory(
|
flags = version_review_flags_factory(
|
||||||
version=self.version, needs_human_review_by_mad=True
|
version=self.review_version, needs_human_review_by_mad=True
|
||||||
)
|
)
|
||||||
AddonReviewerFlags.objects.create(
|
AddonReviewerFlags.objects.create(
|
||||||
addon=self.addon, auto_approval_disabled_until_next_approval_unlisted=True
|
addon=self.addon, auto_approval_disabled_until_next_approval_unlisted=True
|
||||||
)
|
)
|
||||||
self.helper.handler.approve_latest_version()
|
self.helper.handler.approve_latest_version()
|
||||||
self.addon.reload()
|
self.addon.reload()
|
||||||
self.version.reload()
|
self.review_version.reload()
|
||||||
self.file.reload()
|
self.file.reload()
|
||||||
flags.reload()
|
flags.reload()
|
||||||
addon_flags = self.addon.reviewerflags.reload()
|
addon_flags = self.addon.reviewerflags.reload()
|
||||||
assert self.addon.status == amo.STATUS_NULL
|
assert self.addon.status == amo.STATUS_NULL
|
||||||
assert self.file.status == amo.STATUS_APPROVED
|
assert self.file.status == amo.STATUS_APPROVED
|
||||||
assert self.version.needs_human_review
|
assert self.review_version.needs_human_review
|
||||||
assert flags.needs_human_review_by_mad
|
assert flags.needs_human_review_by_mad
|
||||||
|
|
||||||
# Not changed this this is not a human approval.
|
# Not changed this this is not a human approval.
|
||||||
|
@ -1075,7 +1079,8 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
self.sign_file_mock.reset()
|
self.sign_file_mock.reset()
|
||||||
self.setup_data(amo.STATUS_NOMINATED)
|
self.setup_data(amo.STATUS_NOMINATED)
|
||||||
AutoApprovalSummary.objects.update_or_create(
|
AutoApprovalSummary.objects.update_or_create(
|
||||||
version=self.version, defaults={'verdict': amo.AUTO_APPROVED, 'weight': 101}
|
version=self.review_version,
|
||||||
|
defaults={'verdict': amo.AUTO_APPROVED, 'weight': 101},
|
||||||
)
|
)
|
||||||
|
|
||||||
self.helper.handler.approve_latest_version()
|
self.helper.handler.approve_latest_version()
|
||||||
|
@ -1102,7 +1107,7 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
def test_old_nomination_to_public_bonus_score(self):
|
def test_old_nomination_to_public_bonus_score(self):
|
||||||
self.sign_file_mock.reset()
|
self.sign_file_mock.reset()
|
||||||
self.setup_data(amo.STATUS_NOMINATED, type=amo.ADDON_STATICTHEME)
|
self.setup_data(amo.STATUS_NOMINATED, type=amo.ADDON_STATICTHEME)
|
||||||
self.version.update(nomination=self.days_ago(9))
|
self.review_version.update(nomination=self.days_ago(9))
|
||||||
|
|
||||||
self.helper.handler.approve_latest_version()
|
self.helper.handler.approve_latest_version()
|
||||||
|
|
||||||
|
@ -1160,7 +1165,7 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
def test_public_addon_with_version_awaiting_review_to_public(self):
|
def test_public_addon_with_version_awaiting_review_to_public(self):
|
||||||
self.sign_file_mock.reset()
|
self.sign_file_mock.reset()
|
||||||
self.addon.current_version.update(created=self.days_ago(1))
|
self.addon.current_version.update(created=self.days_ago(1))
|
||||||
self.version = version_factory(
|
self.review_version = version_factory(
|
||||||
addon=self.addon,
|
addon=self.addon,
|
||||||
channel=amo.CHANNEL_LISTED,
|
channel=amo.CHANNEL_LISTED,
|
||||||
version='3.0.42',
|
version='3.0.42',
|
||||||
|
@ -1170,10 +1175,10 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
self.preamble = 'Mozilla Add-ons: Delicious Bookmarks 3.0.42'
|
self.preamble = 'Mozilla Add-ons: Delicious Bookmarks 3.0.42'
|
||||||
self.file = self.version.file
|
self.file = self.review_version.file
|
||||||
self.setup_data(amo.STATUS_APPROVED)
|
self.setup_data(amo.STATUS_APPROVED)
|
||||||
AutoApprovalSummary.objects.create(
|
AutoApprovalSummary.objects.create(
|
||||||
version=self.version, verdict=amo.AUTO_APPROVED, weight=101
|
version=self.review_version, verdict=amo.AUTO_APPROVED, weight=101
|
||||||
)
|
)
|
||||||
self.create_paths()
|
self.create_paths()
|
||||||
AddonApprovalsCounter.objects.create(
|
AddonApprovalsCounter.objects.create(
|
||||||
|
@ -1217,13 +1222,13 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
def test_public_addon_with_version_need_human_review_to_public(self):
|
def test_public_addon_with_version_need_human_review_to_public(self):
|
||||||
self.old_version = self.addon.current_version
|
self.old_version = self.addon.current_version
|
||||||
self.old_version.update(created=self.days_ago(1), needs_human_review=True)
|
self.old_version.update(created=self.days_ago(1), needs_human_review=True)
|
||||||
self.version = version_factory(
|
self.review_version = version_factory(
|
||||||
addon=self.addon,
|
addon=self.addon,
|
||||||
channel=amo.CHANNEL_LISTED,
|
channel=amo.CHANNEL_LISTED,
|
||||||
version='3.0.42',
|
version='3.0.42',
|
||||||
file_kw={'status': amo.STATUS_AWAITING_REVIEW},
|
file_kw={'status': amo.STATUS_AWAITING_REVIEW},
|
||||||
)
|
)
|
||||||
self.file = self.version.file
|
self.file = self.review_version.file
|
||||||
self.setup_data(amo.STATUS_APPROVED)
|
self.setup_data(amo.STATUS_APPROVED)
|
||||||
|
|
||||||
self.helper.handler.approve_latest_version()
|
self.helper.handler.approve_latest_version()
|
||||||
|
@ -1239,13 +1244,13 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
AddonReviewerFlags.objects.create(
|
AddonReviewerFlags.objects.create(
|
||||||
addon=self.addon, auto_approval_disabled_until_next_approval=True
|
addon=self.addon, auto_approval_disabled_until_next_approval=True
|
||||||
)
|
)
|
||||||
self.version = version_factory(
|
self.review_version = version_factory(
|
||||||
addon=self.addon,
|
addon=self.addon,
|
||||||
channel=amo.CHANNEL_LISTED,
|
channel=amo.CHANNEL_LISTED,
|
||||||
version='3.0.42',
|
version='3.0.42',
|
||||||
file_kw={'status': amo.STATUS_AWAITING_REVIEW},
|
file_kw={'status': amo.STATUS_AWAITING_REVIEW},
|
||||||
)
|
)
|
||||||
self.file = self.version.file
|
self.file = self.review_version.file
|
||||||
self.setup_data(amo.STATUS_APPROVED)
|
self.setup_data(amo.STATUS_APPROVED)
|
||||||
|
|
||||||
self.helper.handler.approve_latest_version()
|
self.helper.handler.approve_latest_version()
|
||||||
|
@ -1260,7 +1265,7 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
def test_public_addon_with_version_awaiting_review_to_sandbox(self):
|
def test_public_addon_with_version_awaiting_review_to_sandbox(self):
|
||||||
self.sign_file_mock.reset()
|
self.sign_file_mock.reset()
|
||||||
self.addon.current_version.update(created=self.days_ago(1))
|
self.addon.current_version.update(created=self.days_ago(1))
|
||||||
self.version = version_factory(
|
self.review_version = version_factory(
|
||||||
addon=self.addon,
|
addon=self.addon,
|
||||||
channel=amo.CHANNEL_LISTED,
|
channel=amo.CHANNEL_LISTED,
|
||||||
version='3.0.42',
|
version='3.0.42',
|
||||||
|
@ -1270,10 +1275,10 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
self.preamble = 'Mozilla Add-ons: Delicious Bookmarks 3.0.42'
|
self.preamble = 'Mozilla Add-ons: Delicious Bookmarks 3.0.42'
|
||||||
self.file = self.version.file
|
self.file = self.review_version.file
|
||||||
self.setup_data(amo.STATUS_APPROVED)
|
self.setup_data(amo.STATUS_APPROVED)
|
||||||
AutoApprovalSummary.objects.create(
|
AutoApprovalSummary.objects.create(
|
||||||
version=self.version, verdict=amo.AUTO_APPROVED, weight=101
|
version=self.review_version, verdict=amo.AUTO_APPROVED, weight=101
|
||||||
)
|
)
|
||||||
AddonApprovalsCounter.objects.create(addon=self.addon, counter=1)
|
AddonApprovalsCounter.objects.create(addon=self.addon, counter=1)
|
||||||
|
|
||||||
|
@ -1308,14 +1313,14 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
def test_public_addon_with_version_need_human_review_to_sandbox(self):
|
def test_public_addon_with_version_need_human_review_to_sandbox(self):
|
||||||
self.old_version = self.addon.current_version
|
self.old_version = self.addon.current_version
|
||||||
self.old_version.update(created=self.days_ago(1), needs_human_review=True)
|
self.old_version.update(created=self.days_ago(1), needs_human_review=True)
|
||||||
self.version = version_factory(
|
self.review_version = version_factory(
|
||||||
addon=self.addon,
|
addon=self.addon,
|
||||||
channel=amo.CHANNEL_LISTED,
|
channel=amo.CHANNEL_LISTED,
|
||||||
version='3.0.42',
|
version='3.0.42',
|
||||||
needs_human_review=True,
|
needs_human_review=True,
|
||||||
file_kw={'status': amo.STATUS_AWAITING_REVIEW},
|
file_kw={'status': amo.STATUS_AWAITING_REVIEW},
|
||||||
)
|
)
|
||||||
self.file = self.version.file
|
self.file = self.review_version.file
|
||||||
self.setup_data(amo.STATUS_APPROVED)
|
self.setup_data(amo.STATUS_APPROVED)
|
||||||
|
|
||||||
self.helper.handler.reject_latest_version()
|
self.helper.handler.reject_latest_version()
|
||||||
|
@ -1332,14 +1337,14 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
self.addon.current_version.reload()
|
self.addon.current_version.reload()
|
||||||
assert self.addon.current_version.needs_human_review
|
assert self.addon.current_version.needs_human_review
|
||||||
|
|
||||||
self.version.reload()
|
self.review_version.reload()
|
||||||
assert not self.version.needs_human_review
|
assert not self.review_version.needs_human_review
|
||||||
|
|
||||||
def test_public_addon_confirm_auto_approval(self):
|
def test_public_addon_confirm_auto_approval(self):
|
||||||
self.grant_permission(self.user, 'Addons:Review')
|
self.grant_permission(self.user, 'Addons:Review')
|
||||||
self.setup_data(amo.STATUS_APPROVED, file_status=amo.STATUS_APPROVED)
|
self.setup_data(amo.STATUS_APPROVED, file_status=amo.STATUS_APPROVED)
|
||||||
summary = AutoApprovalSummary.objects.create(
|
summary = AutoApprovalSummary.objects.create(
|
||||||
version=self.version, verdict=amo.AUTO_APPROVED, weight=151
|
version=self.review_version, verdict=amo.AUTO_APPROVED, weight=151
|
||||||
)
|
)
|
||||||
assert summary.confirmed is None
|
assert summary.confirmed is None
|
||||||
self.create_paths()
|
self.create_paths()
|
||||||
|
@ -1362,7 +1367,7 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
.filter(action=amo.LOG.CONFIRM_AUTO_APPROVED.id)
|
.filter(action=amo.LOG.CONFIRM_AUTO_APPROVED.id)
|
||||||
.get()
|
.get()
|
||||||
)
|
)
|
||||||
assert activity.arguments == [self.addon, self.version]
|
assert activity.arguments == [self.addon, self.review_version]
|
||||||
assert activity.details['comments'] == ''
|
assert activity.details['comments'] == ''
|
||||||
|
|
||||||
# Check points awarded.
|
# Check points awarded.
|
||||||
|
@ -1371,16 +1376,16 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
def test_public_with_unreviewed_version_addon_confirm_auto_approval(self):
|
def test_public_with_unreviewed_version_addon_confirm_auto_approval(self):
|
||||||
self.grant_permission(self.user, 'Addons:Review')
|
self.grant_permission(self.user, 'Addons:Review')
|
||||||
self.setup_data(amo.STATUS_APPROVED, file_status=amo.STATUS_APPROVED)
|
self.setup_data(amo.STATUS_APPROVED, file_status=amo.STATUS_APPROVED)
|
||||||
self.current_version = self.version
|
self.current_version = self.review_version
|
||||||
summary = AutoApprovalSummary.objects.create(
|
summary = AutoApprovalSummary.objects.create(
|
||||||
version=self.version, verdict=amo.AUTO_APPROVED, weight=152
|
version=self.review_version, verdict=amo.AUTO_APPROVED, weight=152
|
||||||
)
|
)
|
||||||
self.version = version_factory(
|
self.review_version = version_factory(
|
||||||
addon=self.addon,
|
addon=self.addon,
|
||||||
version='3.0',
|
version='3.0',
|
||||||
file_kw={'status': amo.STATUS_AWAITING_REVIEW},
|
file_kw={'status': amo.STATUS_AWAITING_REVIEW},
|
||||||
)
|
)
|
||||||
self.file = self.version.file
|
self.file = self.review_version.file
|
||||||
self.helper = self.get_helper() # To make it pick up the new version.
|
self.helper = self.get_helper() # To make it pick up the new version.
|
||||||
self.helper.set_data(self.get_data())
|
self.helper.set_data(self.get_data())
|
||||||
|
|
||||||
|
@ -1410,14 +1415,14 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
def test_public_with_disabled_version_addon_confirm_auto_approval(self):
|
def test_public_with_disabled_version_addon_confirm_auto_approval(self):
|
||||||
self.grant_permission(self.user, 'Addons:Review')
|
self.grant_permission(self.user, 'Addons:Review')
|
||||||
self.setup_data(amo.STATUS_APPROVED, file_status=amo.STATUS_APPROVED)
|
self.setup_data(amo.STATUS_APPROVED, file_status=amo.STATUS_APPROVED)
|
||||||
self.current_version = self.version
|
self.current_version = self.review_version
|
||||||
summary = AutoApprovalSummary.objects.create(
|
summary = AutoApprovalSummary.objects.create(
|
||||||
version=self.version, verdict=amo.AUTO_APPROVED, weight=153
|
version=self.review_version, verdict=amo.AUTO_APPROVED, weight=153
|
||||||
)
|
)
|
||||||
self.version = version_factory(
|
self.review_version = version_factory(
|
||||||
addon=self.addon, version='3.0', file_kw={'status': amo.STATUS_DISABLED}
|
addon=self.addon, version='3.0', file_kw={'status': amo.STATUS_DISABLED}
|
||||||
)
|
)
|
||||||
self.file = self.version.file
|
self.file = self.review_version.file
|
||||||
self.helper = self.get_helper() # To make it pick up the new version.
|
self.helper = self.get_helper() # To make it pick up the new version.
|
||||||
self.helper.set_data(self.get_data())
|
self.helper.set_data(self.get_data())
|
||||||
|
|
||||||
|
@ -1448,12 +1453,12 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
self.grant_permission(self.user, 'Addons:Review')
|
self.grant_permission(self.user, 'Addons:Review')
|
||||||
self.grant_permission(self.user, 'Reviews:Admin')
|
self.grant_permission(self.user, 'Reviews:Admin')
|
||||||
self.setup_data(amo.STATUS_APPROVED, file_status=amo.STATUS_APPROVED)
|
self.setup_data(amo.STATUS_APPROVED, file_status=amo.STATUS_APPROVED)
|
||||||
self.version = version_factory(
|
self.review_version = version_factory(
|
||||||
addon=self.addon, version='3.0', file_kw={'status': amo.STATUS_APPROVED}
|
addon=self.addon, version='3.0', file_kw={'status': amo.STATUS_APPROVED}
|
||||||
)
|
)
|
||||||
self.file = self.version.file
|
self.file = self.review_version.file
|
||||||
summary = AutoApprovalSummary.objects.create(
|
summary = AutoApprovalSummary.objects.create(
|
||||||
version=self.version, verdict=amo.AUTO_APPROVED, weight=153
|
version=self.review_version, verdict=amo.AUTO_APPROVED, weight=153
|
||||||
)
|
)
|
||||||
|
|
||||||
for version in self.addon.versions.all():
|
for version in self.addon.versions.all():
|
||||||
|
@ -1483,7 +1488,7 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
.filter(action=amo.LOG.CONFIRM_AUTO_APPROVED.id)
|
.filter(action=amo.LOG.CONFIRM_AUTO_APPROVED.id)
|
||||||
.get()
|
.get()
|
||||||
)
|
)
|
||||||
assert activity.arguments == [self.addon, self.version]
|
assert activity.arguments == [self.addon, self.review_version]
|
||||||
assert activity.details['comments'] == ''
|
assert activity.details['comments'] == ''
|
||||||
|
|
||||||
# None of the versions should be pending rejection anymore.
|
# None of the versions should be pending rejection anymore.
|
||||||
|
@ -1523,9 +1528,9 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
def test_confirm_multiple_versions_with_version_scanner_flags(self):
|
def test_confirm_multiple_versions_with_version_scanner_flags(self):
|
||||||
self.grant_permission(self.user, 'Addons:ReviewUnlisted')
|
self.grant_permission(self.user, 'Addons:ReviewUnlisted')
|
||||||
self.setup_data(amo.STATUS_APPROVED, file_status=amo.STATUS_APPROVED)
|
self.setup_data(amo.STATUS_APPROVED, file_status=amo.STATUS_APPROVED)
|
||||||
self.version.update(channel=amo.CHANNEL_UNLISTED)
|
self.review_version.update(channel=amo.CHANNEL_UNLISTED)
|
||||||
flags = version_review_flags_factory(
|
flags = version_review_flags_factory(
|
||||||
version=self.version,
|
version=self.review_version,
|
||||||
needs_human_review_by_mad=True,
|
needs_human_review_by_mad=True,
|
||||||
)
|
)
|
||||||
assert flags.needs_human_review_by_mad
|
assert flags.needs_human_review_by_mad
|
||||||
|
@ -1565,14 +1570,14 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
needs_human_review=True,
|
needs_human_review=True,
|
||||||
created=self.days_ago(6),
|
created=self.days_ago(6),
|
||||||
)
|
)
|
||||||
self.version = version_factory(
|
self.review_version = version_factory(
|
||||||
addon=self.addon,
|
addon=self.addon,
|
||||||
version='5.0',
|
version='5.0',
|
||||||
channel=amo.CHANNEL_UNLISTED,
|
channel=amo.CHANNEL_UNLISTED,
|
||||||
needs_human_review=True,
|
needs_human_review=True,
|
||||||
created=self.days_ago(5),
|
created=self.days_ago(5),
|
||||||
)
|
)
|
||||||
self.file = self.version.file
|
self.file = self.review_version.file
|
||||||
self.helper = self.get_helper() # To make it pick up the new version.
|
self.helper = self.get_helper() # To make it pick up the new version.
|
||||||
data = self.get_data().copy()
|
data = self.get_data().copy()
|
||||||
data['versions'] = self.addon.versions.filter(
|
data['versions'] = self.addon.versions.filter(
|
||||||
|
@ -1589,8 +1594,8 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
summary.reload()
|
summary.reload()
|
||||||
assert summary.confirmed is True
|
assert summary.confirmed is True
|
||||||
|
|
||||||
self.version.reload()
|
self.review_version.reload()
|
||||||
assert self.version.needs_human_review # Untouched.
|
assert self.review_version.needs_human_review # Untouched.
|
||||||
|
|
||||||
second_unlisted.reload()
|
second_unlisted.reload()
|
||||||
assert not second_unlisted.needs_human_review # Cleared.
|
assert not second_unlisted.needs_human_review # Cleared.
|
||||||
|
@ -1627,7 +1632,8 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
message = mail.outbox[0]
|
message = mail.outbox[0]
|
||||||
assert message.subject == ('%s signed and ready to download' % self.preamble)
|
assert message.subject == ('%s signed and ready to download' % self.preamble)
|
||||||
assert (
|
assert (
|
||||||
'%s is now signed and ready for you to download' % self.version.version
|
'%s is now signed and ready for you to download'
|
||||||
|
% self.review_version.version
|
||||||
in message.body
|
in message.body
|
||||||
)
|
)
|
||||||
assert 'You received this email because' not in message.body
|
assert 'You received this email because' not in message.body
|
||||||
|
@ -1781,16 +1787,16 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
assert self.addon.needs_admin_code_review
|
assert self.addon.needs_admin_code_review
|
||||||
|
|
||||||
def test_nominated_review_time_set_version_approve_latest_version(self):
|
def test_nominated_review_time_set_version_approve_latest_version(self):
|
||||||
self.version.update(reviewed=None)
|
self.review_version.update(reviewed=None)
|
||||||
self.setup_data(amo.STATUS_NOMINATED)
|
self.setup_data(amo.STATUS_NOMINATED)
|
||||||
self.helper.handler.approve_latest_version()
|
self.helper.handler.approve_latest_version()
|
||||||
assert self.version.reload().reviewed
|
assert self.review_version.reload().reviewed
|
||||||
|
|
||||||
def test_nominated_review_time_set_version_reject_latest_version(self):
|
def test_nominated_review_time_set_version_reject_latest_version(self):
|
||||||
self.version.update(reviewed=None)
|
self.review_version.update(reviewed=None)
|
||||||
self.setup_data(amo.STATUS_NOMINATED)
|
self.setup_data(amo.STATUS_NOMINATED)
|
||||||
self.helper.handler.reject_latest_version()
|
self.helper.handler.reject_latest_version()
|
||||||
assert self.version.reload().reviewed
|
assert self.review_version.reload().reviewed
|
||||||
|
|
||||||
def test_nominated_review_time_set_file_approve_latest_version(self):
|
def test_nominated_review_time_set_file_approve_latest_version(self):
|
||||||
self.file.update(reviewed=None)
|
self.file.update(reviewed=None)
|
||||||
|
@ -1806,7 +1812,7 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
|
|
||||||
def test_review_unlisted_while_a_listed_version_is_awaiting_review(self):
|
def test_review_unlisted_while_a_listed_version_is_awaiting_review(self):
|
||||||
self.make_addon_unlisted(self.addon)
|
self.make_addon_unlisted(self.addon)
|
||||||
self.version.reload()
|
self.review_version.reload()
|
||||||
version_factory(
|
version_factory(
|
||||||
addon=self.addon,
|
addon=self.addon,
|
||||||
channel=amo.CHANNEL_LISTED,
|
channel=amo.CHANNEL_LISTED,
|
||||||
|
@ -1816,10 +1822,10 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
assert self.get_helper()
|
assert self.get_helper()
|
||||||
|
|
||||||
def test_reject_multiple_versions(self):
|
def test_reject_multiple_versions(self):
|
||||||
old_version = self.version
|
old_version = self.review_version
|
||||||
self.version = version_factory(addon=self.addon, version='3.0')
|
self.review_version = version_factory(addon=self.addon, version='3.0')
|
||||||
AutoApprovalSummary.objects.create(
|
AutoApprovalSummary.objects.create(
|
||||||
version=self.version, verdict=amo.AUTO_APPROVED, weight=101
|
version=self.review_version, verdict=amo.AUTO_APPROVED, weight=101
|
||||||
)
|
)
|
||||||
self.setup_data(amo.STATUS_APPROVED, file_status=amo.STATUS_APPROVED)
|
self.setup_data(amo.STATUS_APPROVED, file_status=amo.STATUS_APPROVED)
|
||||||
|
|
||||||
|
@ -1838,7 +1844,7 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
self.file.reload()
|
self.file.reload()
|
||||||
assert self.addon.status == amo.STATUS_NULL
|
assert self.addon.status == amo.STATUS_NULL
|
||||||
assert self.addon.current_version is None
|
assert self.addon.current_version is None
|
||||||
assert list(self.addon.versions.all()) == [self.version, old_version]
|
assert list(self.addon.versions.all()) == [self.review_version, old_version]
|
||||||
assert self.file.status == amo.STATUS_DISABLED
|
assert self.file.status == amo.STATUS_DISABLED
|
||||||
|
|
||||||
# The versions are not pending rejection.
|
# The versions are not pending rejection.
|
||||||
|
@ -1878,14 +1884,14 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
# The reviewer should have been automatically subscribed to new listed
|
# The reviewer should have been automatically subscribed to new listed
|
||||||
# versions.
|
# versions.
|
||||||
assert ReviewerSubscription.objects.filter(
|
assert ReviewerSubscription.objects.filter(
|
||||||
addon=self.addon, user=self.user, channel=self.version.channel
|
addon=self.addon, user=self.user, channel=self.review_version.channel
|
||||||
).exists()
|
).exists()
|
||||||
|
|
||||||
def test_reject_multiple_versions_with_delay(self):
|
def test_reject_multiple_versions_with_delay(self):
|
||||||
old_version = self.version
|
old_version = self.review_version
|
||||||
self.version = version_factory(addon=self.addon, version='3.0')
|
self.review_version = version_factory(addon=self.addon, version='3.0')
|
||||||
AutoApprovalSummary.objects.create(
|
AutoApprovalSummary.objects.create(
|
||||||
version=self.version, verdict=amo.AUTO_APPROVED, weight=101
|
version=self.review_version, verdict=amo.AUTO_APPROVED, weight=101
|
||||||
)
|
)
|
||||||
self.setup_data(amo.STATUS_APPROVED, file_status=amo.STATUS_APPROVED)
|
self.setup_data(amo.STATUS_APPROVED, file_status=amo.STATUS_APPROVED)
|
||||||
|
|
||||||
|
@ -1912,8 +1918,8 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
self.addon.reload()
|
self.addon.reload()
|
||||||
self.file.reload()
|
self.file.reload()
|
||||||
assert self.addon.status == amo.STATUS_APPROVED
|
assert self.addon.status == amo.STATUS_APPROVED
|
||||||
assert self.addon.current_version == self.version
|
assert self.addon.current_version == self.review_version
|
||||||
assert list(self.addon.versions.all()) == [self.version, old_version]
|
assert list(self.addon.versions.all()) == [self.review_version, old_version]
|
||||||
assert self.file.status == amo.STATUS_APPROVED
|
assert self.file.status == amo.STATUS_APPROVED
|
||||||
|
|
||||||
# The versions are now pending rejection.
|
# The versions are now pending rejection.
|
||||||
|
@ -1958,16 +1964,16 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
# The reviewer should have been automatically subscribed to new listed
|
# The reviewer should have been automatically subscribed to new listed
|
||||||
# versions.
|
# versions.
|
||||||
assert ReviewerSubscription.objects.filter(
|
assert ReviewerSubscription.objects.filter(
|
||||||
addon=self.addon, user=self.user, channel=self.version.channel
|
addon=self.addon, user=self.user, channel=self.review_version.channel
|
||||||
).exists()
|
).exists()
|
||||||
|
|
||||||
def test_reject_multiple_versions_except_latest(self):
|
def test_reject_multiple_versions_except_latest(self):
|
||||||
old_version = self.version
|
old_version = self.review_version
|
||||||
extra_version = version_factory(addon=self.addon, version='3.1')
|
extra_version = version_factory(addon=self.addon, version='3.1')
|
||||||
# Add yet another version we don't want to reject.
|
# Add yet another version we don't want to reject.
|
||||||
self.version = version_factory(addon=self.addon, version='42.0')
|
self.review_version = version_factory(addon=self.addon, version='42.0')
|
||||||
AutoApprovalSummary.objects.create(
|
AutoApprovalSummary.objects.create(
|
||||||
version=self.version, verdict=amo.AUTO_APPROVED, weight=91
|
version=self.review_version, verdict=amo.AUTO_APPROVED, weight=91
|
||||||
)
|
)
|
||||||
self.setup_data(amo.STATUS_APPROVED, file_status=amo.STATUS_APPROVED)
|
self.setup_data(amo.STATUS_APPROVED, file_status=amo.STATUS_APPROVED)
|
||||||
|
|
||||||
|
@ -1978,7 +1984,7 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
assert self.addon.current_version.is_public()
|
assert self.addon.current_version.is_public()
|
||||||
|
|
||||||
data = self.get_data().copy()
|
data = self.get_data().copy()
|
||||||
data['versions'] = self.addon.versions.all().exclude(pk=self.version.pk)
|
data['versions'] = self.addon.versions.all().exclude(pk=self.review_version.pk)
|
||||||
self.helper.set_data(data)
|
self.helper.set_data(data)
|
||||||
self.helper.handler.reject_multiple_versions()
|
self.helper.handler.reject_multiple_versions()
|
||||||
|
|
||||||
|
@ -1986,9 +1992,9 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
self.file.reload()
|
self.file.reload()
|
||||||
# latest_version is still public so the add-on is still public.
|
# latest_version is still public so the add-on is still public.
|
||||||
assert self.addon.status == amo.STATUS_APPROVED
|
assert self.addon.status == amo.STATUS_APPROVED
|
||||||
assert self.addon.current_version == self.version
|
assert self.addon.current_version == self.review_version
|
||||||
assert list(self.addon.versions.all().order_by('-pk')) == [
|
assert list(self.addon.versions.all().order_by('-pk')) == [
|
||||||
self.version,
|
self.review_version,
|
||||||
extra_version,
|
extra_version,
|
||||||
old_version,
|
old_version,
|
||||||
]
|
]
|
||||||
|
@ -2001,7 +2007,7 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
'Mozilla Add-ons: Versions disabled for Delicious Bookmarks'
|
'Mozilla Add-ons: Versions disabled for Delicious Bookmarks'
|
||||||
)
|
)
|
||||||
assert 'Version(s) affected and disabled:\n3.1, 2.1.072' in message.body
|
assert 'Version(s) affected and disabled:\n3.1, 2.1.072' in message.body
|
||||||
log_token = ActivityLogToken.objects.filter(version=self.version).get()
|
log_token = ActivityLogToken.objects.filter(version=self.review_version).get()
|
||||||
assert log_token.uuid.hex in message.reply_to[0]
|
assert log_token.uuid.hex in message.reply_to[0]
|
||||||
|
|
||||||
assert self.check_log_count(amo.LOG.REJECT_VERSION.id) == 2
|
assert self.check_log_count(amo.LOG.REJECT_VERSION.id) == 2
|
||||||
|
@ -2011,9 +2017,9 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
self._check_score(amo.REVIEWED_EXTENSION_MEDIUM_RISK)
|
self._check_score(amo.REVIEWED_EXTENSION_MEDIUM_RISK)
|
||||||
|
|
||||||
def test_reject_multiple_versions_need_human_review(self):
|
def test_reject_multiple_versions_need_human_review(self):
|
||||||
old_version = self.version
|
old_version = self.review_version
|
||||||
old_version.update(needs_human_review=True)
|
old_version.update(needs_human_review=True)
|
||||||
self.version = version_factory(
|
self.review_version = version_factory(
|
||||||
addon=self.addon, version='3.0', needs_human_review=True
|
addon=self.addon, version='3.0', needs_human_review=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -2026,7 +2032,7 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
self.file.reload()
|
self.file.reload()
|
||||||
assert self.addon.status == amo.STATUS_NULL
|
assert self.addon.status == amo.STATUS_NULL
|
||||||
assert self.addon.current_version is None
|
assert self.addon.current_version is None
|
||||||
assert list(self.addon.versions.all()) == [self.version, old_version]
|
assert list(self.addon.versions.all()) == [self.review_version, old_version]
|
||||||
# We rejected all versions so there aren't any left that need human
|
# We rejected all versions so there aren't any left that need human
|
||||||
# review.
|
# review.
|
||||||
assert not self.addon.versions.filter(needs_human_review=True).exists()
|
assert not self.addon.versions.filter(needs_human_review=True).exists()
|
||||||
|
@ -2034,8 +2040,8 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
|
|
||||||
def test_reject_multiple_versions_content_review(self):
|
def test_reject_multiple_versions_content_review(self):
|
||||||
self.grant_permission(self.user, 'Addons:ContentReview')
|
self.grant_permission(self.user, 'Addons:ContentReview')
|
||||||
old_version = self.version
|
old_version = self.review_version
|
||||||
self.version = version_factory(addon=self.addon, version='3.0')
|
self.review_version = version_factory(addon=self.addon, version='3.0')
|
||||||
self.setup_data(
|
self.setup_data(
|
||||||
amo.STATUS_APPROVED, file_status=amo.STATUS_APPROVED, content_review=True
|
amo.STATUS_APPROVED, file_status=amo.STATUS_APPROVED, content_review=True
|
||||||
)
|
)
|
||||||
|
@ -2055,7 +2061,7 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
self.file.reload()
|
self.file.reload()
|
||||||
assert self.addon.status == amo.STATUS_NULL
|
assert self.addon.status == amo.STATUS_NULL
|
||||||
assert self.addon.current_version is None
|
assert self.addon.current_version is None
|
||||||
assert list(self.addon.versions.all()) == [self.version, old_version]
|
assert list(self.addon.versions.all()) == [self.review_version, old_version]
|
||||||
assert self.file.status == amo.STATUS_DISABLED
|
assert self.file.status == amo.STATUS_DISABLED
|
||||||
|
|
||||||
assert len(mail.outbox) == 1
|
assert len(mail.outbox) == 1
|
||||||
|
@ -2077,8 +2083,8 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
|
|
||||||
def test_reject_multiple_versions_content_review_with_delay(self):
|
def test_reject_multiple_versions_content_review_with_delay(self):
|
||||||
self.grant_permission(self.user, 'Addons:ContentReview')
|
self.grant_permission(self.user, 'Addons:ContentReview')
|
||||||
old_version = self.version
|
old_version = self.review_version
|
||||||
self.version = version_factory(addon=self.addon, version='3.0')
|
self.review_version = version_factory(addon=self.addon, version='3.0')
|
||||||
self.setup_data(
|
self.setup_data(
|
||||||
amo.STATUS_APPROVED, file_status=amo.STATUS_APPROVED, content_review=True
|
amo.STATUS_APPROVED, file_status=amo.STATUS_APPROVED, content_review=True
|
||||||
)
|
)
|
||||||
|
@ -2086,7 +2092,7 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
# Pre-subscribe the user to new listed versions of this add-on, it
|
# Pre-subscribe the user to new listed versions of this add-on, it
|
||||||
# shouldn't matter.
|
# shouldn't matter.
|
||||||
ReviewerSubscription.objects.create(
|
ReviewerSubscription.objects.create(
|
||||||
addon=self.addon, user=self.user, channel=self.version.channel
|
addon=self.addon, user=self.user, channel=self.review_version.channel
|
||||||
)
|
)
|
||||||
|
|
||||||
in_the_future = datetime.now() + timedelta(days=14)
|
in_the_future = datetime.now() + timedelta(days=14)
|
||||||
|
@ -2112,8 +2118,8 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
self.addon.reload()
|
self.addon.reload()
|
||||||
self.file.reload()
|
self.file.reload()
|
||||||
assert self.addon.status == amo.STATUS_APPROVED
|
assert self.addon.status == amo.STATUS_APPROVED
|
||||||
assert self.addon.current_version == self.version
|
assert self.addon.current_version == self.review_version
|
||||||
assert list(self.addon.versions.all()) == [self.version, old_version]
|
assert list(self.addon.versions.all()) == [self.review_version, old_version]
|
||||||
assert self.file.status == amo.STATUS_APPROVED
|
assert self.file.status == amo.STATUS_APPROVED
|
||||||
|
|
||||||
# The versions are now pending rejection.
|
# The versions are now pending rejection.
|
||||||
|
@ -2148,13 +2154,109 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
# The reviewer was already subscribed to new listed versions for this
|
# The reviewer was already subscribed to new listed versions for this
|
||||||
# addon, nothing has changed.
|
# addon, nothing has changed.
|
||||||
assert ReviewerSubscription.objects.filter(
|
assert ReviewerSubscription.objects.filter(
|
||||||
addon=self.addon, user=self.user, channel=self.version.channel
|
addon=self.addon, user=self.user, channel=self.review_version.channel
|
||||||
).exists()
|
).exists()
|
||||||
|
|
||||||
|
def test_unreject_multiple_versions_approved_addon(self):
|
||||||
|
first_version = self.review_version
|
||||||
|
self.review_version = version_factory(
|
||||||
|
addon=self.addon, version='3.0', file_kw={'status': amo.STATUS_DISABLED}
|
||||||
|
)
|
||||||
|
self.file = self.review_version.file
|
||||||
|
|
||||||
|
# Safeguards.
|
||||||
|
assert isinstance(self.helper.handler, ReviewFiles)
|
||||||
|
assert self.addon.status == amo.STATUS_APPROVED
|
||||||
|
assert first_version.file.status == amo.STATUS_APPROVED
|
||||||
|
assert self.file.status == amo.STATUS_DISABLED
|
||||||
|
assert self.addon.current_version.is_public()
|
||||||
|
assert self.addon.current_version == first_version
|
||||||
|
|
||||||
|
data = self.get_data().copy()
|
||||||
|
data['versions'] = [self.review_version]
|
||||||
|
self.helper.set_data(data)
|
||||||
|
self.helper.handler.unreject_multiple_versions()
|
||||||
|
|
||||||
|
self.addon.reload()
|
||||||
|
self.file.reload()
|
||||||
|
assert self.addon.status == amo.STATUS_APPROVED
|
||||||
|
assert self.addon.current_version == first_version
|
||||||
|
assert list(self.addon.versions.all()) == [self.review_version, first_version]
|
||||||
|
assert self.file.status == amo.STATUS_AWAITING_REVIEW
|
||||||
|
|
||||||
|
assert len(mail.outbox) == 0
|
||||||
|
|
||||||
|
assert self.check_log_count(amo.LOG.UNREJECT_VERSION.id) == 1
|
||||||
|
|
||||||
|
def test_unreject_multiple_versions_with_unlisted(self):
|
||||||
|
old_version = self.review_version
|
||||||
|
self.review_version = version_factory(addon=self.addon, version='3.0')
|
||||||
|
self.file = self.review_version.file
|
||||||
|
self.setup_data(
|
||||||
|
amo.STATUS_NULL,
|
||||||
|
file_status=amo.STATUS_DISABLED,
|
||||||
|
channel=amo.CHANNEL_UNLISTED,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Safeguards.
|
||||||
|
assert isinstance(self.helper.handler, ReviewUnlisted)
|
||||||
|
assert self.addon.status == amo.STATUS_NULL
|
||||||
|
assert old_version.file.status == amo.STATUS_APPROVED
|
||||||
|
assert self.file.status == amo.STATUS_DISABLED
|
||||||
|
assert self.addon.current_version is None
|
||||||
|
|
||||||
|
data = self.get_data().copy()
|
||||||
|
data['versions'] = [self.review_version]
|
||||||
|
self.helper.set_data(data)
|
||||||
|
self.helper.handler.unreject_multiple_versions()
|
||||||
|
|
||||||
|
self.addon.reload()
|
||||||
|
self.file.reload()
|
||||||
|
assert self.addon.status == amo.STATUS_NULL
|
||||||
|
assert self.addon.current_version is None
|
||||||
|
assert list(self.addon.versions.all()) == [self.review_version, old_version]
|
||||||
|
assert self.file.status == amo.STATUS_AWAITING_REVIEW
|
||||||
|
|
||||||
|
assert len(mail.outbox) == 0
|
||||||
|
|
||||||
|
assert self.check_log_count(amo.LOG.UNREJECT_VERSION.id) == 1
|
||||||
|
|
||||||
|
def test_unreject_multiple_versions_incomplete_addon(self):
|
||||||
|
old_version = self.review_version
|
||||||
|
old_version.file.update(status=amo.STATUS_DISABLED)
|
||||||
|
self.review_version = version_factory(
|
||||||
|
addon=self.addon, version='3.0', file_kw={'status': amo.STATUS_DISABLED}
|
||||||
|
)
|
||||||
|
self.file = self.review_version.file
|
||||||
|
self.setup_data(amo.STATUS_NULL, file_status=amo.STATUS_DISABLED)
|
||||||
|
|
||||||
|
# Safeguards.
|
||||||
|
assert isinstance(self.helper.handler, ReviewFiles)
|
||||||
|
assert self.addon.status == amo.STATUS_NULL
|
||||||
|
assert old_version.file.status == amo.STATUS_DISABLED
|
||||||
|
assert self.file.status == amo.STATUS_DISABLED
|
||||||
|
assert self.addon.current_version is None
|
||||||
|
|
||||||
|
data = self.get_data().copy()
|
||||||
|
data['versions'] = [self.review_version]
|
||||||
|
self.helper.set_data(data)
|
||||||
|
self.helper.handler.unreject_multiple_versions()
|
||||||
|
|
||||||
|
self.addon.reload()
|
||||||
|
self.file.reload()
|
||||||
|
assert self.addon.status == amo.STATUS_NOMINATED
|
||||||
|
assert self.addon.current_version == self.review_version
|
||||||
|
assert list(self.addon.versions.all()) == [self.review_version, old_version]
|
||||||
|
assert self.file.status == amo.STATUS_AWAITING_REVIEW
|
||||||
|
|
||||||
|
assert len(mail.outbox) == 0
|
||||||
|
|
||||||
|
assert self.check_log_count(amo.LOG.UNREJECT_VERSION.id) == 1
|
||||||
|
|
||||||
def test_approve_multiple_versions_unlisted(self):
|
def test_approve_multiple_versions_unlisted(self):
|
||||||
old_version = self.version
|
old_version = self.review_version
|
||||||
self.make_addon_unlisted(self.addon)
|
self.make_addon_unlisted(self.addon)
|
||||||
self.version = version_factory(
|
self.review_version = version_factory(
|
||||||
addon=self.addon,
|
addon=self.addon,
|
||||||
version='3.0',
|
version='3.0',
|
||||||
channel=amo.CHANNEL_UNLISTED,
|
channel=amo.CHANNEL_UNLISTED,
|
||||||
|
@ -2181,7 +2283,7 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
self.file.reload()
|
self.file.reload()
|
||||||
assert self.addon.status == amo.STATUS_NULL
|
assert self.addon.status == amo.STATUS_NULL
|
||||||
assert self.addon.current_version is None
|
assert self.addon.current_version is None
|
||||||
assert list(self.addon.versions.all()) == [self.version, old_version]
|
assert list(self.addon.versions.all()) == [self.review_version, old_version]
|
||||||
assert self.file.status == amo.STATUS_APPROVED
|
assert self.file.status == amo.STATUS_APPROVED
|
||||||
|
|
||||||
# unlisted auto approvals should be enabled again
|
# unlisted auto approvals should be enabled again
|
||||||
|
@ -2212,16 +2314,16 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
assert logs[0].created == logs[1].created
|
assert logs[0].created == logs[1].created
|
||||||
|
|
||||||
def test_reject_multiple_versions_unlisted(self):
|
def test_reject_multiple_versions_unlisted(self):
|
||||||
old_version = self.version
|
old_version = self.review_version
|
||||||
self.make_addon_unlisted(self.addon)
|
self.make_addon_unlisted(self.addon)
|
||||||
self.version = version_factory(
|
self.review_version = version_factory(
|
||||||
addon=self.addon,
|
addon=self.addon,
|
||||||
version='3.0',
|
version='3.0',
|
||||||
channel=amo.CHANNEL_UNLISTED,
|
channel=amo.CHANNEL_UNLISTED,
|
||||||
file_kw={'status': amo.STATUS_AWAITING_REVIEW},
|
file_kw={'status': amo.STATUS_AWAITING_REVIEW},
|
||||||
)
|
)
|
||||||
AutoApprovalSummary.objects.create(
|
AutoApprovalSummary.objects.create(
|
||||||
version=self.version, verdict=amo.AUTO_APPROVED, weight=101
|
version=self.review_version, verdict=amo.AUTO_APPROVED, weight=101
|
||||||
)
|
)
|
||||||
self.setup_data(amo.STATUS_NULL, file_status=amo.STATUS_AWAITING_REVIEW)
|
self.setup_data(amo.STATUS_NULL, file_status=amo.STATUS_AWAITING_REVIEW)
|
||||||
|
|
||||||
|
@ -2239,7 +2341,7 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
self.file.reload()
|
self.file.reload()
|
||||||
assert self.addon.status == amo.STATUS_NULL
|
assert self.addon.status == amo.STATUS_NULL
|
||||||
assert self.addon.current_version is None
|
assert self.addon.current_version is None
|
||||||
assert list(self.addon.versions.all()) == [self.version, old_version]
|
assert list(self.addon.versions.all()) == [self.review_version, old_version]
|
||||||
assert self.file.status == amo.STATUS_DISABLED
|
assert self.file.status == amo.STATUS_DISABLED
|
||||||
|
|
||||||
# unlisted auto approvals should be disabled until the next manual approval.
|
# unlisted auto approvals should be disabled until the next manual approval.
|
||||||
|
@ -2275,9 +2377,9 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
def _test_reject_multiple_versions_delayed(self, content_review):
|
def _test_reject_multiple_versions_delayed(self, content_review):
|
||||||
# Do a rejection with delay.
|
# Do a rejection with delay.
|
||||||
original_user = self.user
|
original_user = self.user
|
||||||
self.version = version_factory(addon=self.addon, version='3.0')
|
self.review_version = version_factory(addon=self.addon, version='3.0')
|
||||||
AutoApprovalSummary.objects.create(
|
AutoApprovalSummary.objects.create(
|
||||||
version=self.version, verdict=amo.AUTO_APPROVED, weight=101
|
version=self.review_version, verdict=amo.AUTO_APPROVED, weight=101
|
||||||
)
|
)
|
||||||
self.setup_data(
|
self.setup_data(
|
||||||
amo.STATUS_APPROVED,
|
amo.STATUS_APPROVED,
|
||||||
|
@ -2356,7 +2458,7 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
amo.STATUS_APPROVED, file_status=amo.STATUS_APPROVED, content_review=True
|
amo.STATUS_APPROVED, file_status=amo.STATUS_APPROVED, content_review=True
|
||||||
)
|
)
|
||||||
summary = AutoApprovalSummary.objects.create(
|
summary = AutoApprovalSummary.objects.create(
|
||||||
version=self.version, verdict=amo.AUTO_APPROVED
|
version=self.review_version, verdict=amo.AUTO_APPROVED
|
||||||
)
|
)
|
||||||
self.create_paths()
|
self.create_paths()
|
||||||
|
|
||||||
|
@ -2380,7 +2482,7 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
.filter(action=amo.LOG.APPROVE_CONTENT.id)
|
.filter(action=amo.LOG.APPROVE_CONTENT.id)
|
||||||
.get()
|
.get()
|
||||||
)
|
)
|
||||||
assert activity.arguments == [self.addon, self.version]
|
assert activity.arguments == [self.addon, self.review_version]
|
||||||
assert activity.details['comments'] == ''
|
assert activity.details['comments'] == ''
|
||||||
|
|
||||||
# Check points awarded.
|
# Check points awarded.
|
||||||
|
@ -2393,7 +2495,7 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
self.addon.get_dev_url('versions')
|
self.addon.get_dev_url('versions')
|
||||||
)
|
)
|
||||||
|
|
||||||
self.version.update(channel=amo.CHANNEL_UNLISTED)
|
self.review_version.update(channel=amo.CHANNEL_UNLISTED)
|
||||||
context_data = self.helper.handler.get_context_data()
|
context_data = self.helper.handler.get_context_data()
|
||||||
assert context_data['dev_versions_url'] == absolutify(
|
assert context_data['dev_versions_url'] == absolutify(
|
||||||
reverse('devhub.addons.versions', args=[self.addon.id])
|
reverse('devhub.addons.versions', args=[self.addon.id])
|
||||||
|
@ -2467,8 +2569,8 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
assert self.addon.promoted_group() == STRATEGIC
|
assert self.addon.promoted_group() == STRATEGIC
|
||||||
|
|
||||||
def _test_block_multiple_unlisted_versions(self, redirect_url):
|
def _test_block_multiple_unlisted_versions(self, redirect_url):
|
||||||
old_version = self.version
|
old_version = self.review_version
|
||||||
self.version = version_factory(
|
self.review_version = version_factory(
|
||||||
addon=self.addon, version='3.0', needs_human_review=True
|
addon=self.addon, version='3.0', needs_human_review=True
|
||||||
)
|
)
|
||||||
self.setup_data(
|
self.setup_data(
|
||||||
|
@ -2478,7 +2580,7 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
)
|
)
|
||||||
# Add a needs_human_review_by_mad flag that should be cleared later.
|
# Add a needs_human_review_by_mad flag that should be cleared later.
|
||||||
version_review_flags_factory(
|
version_review_flags_factory(
|
||||||
version=self.version, needs_human_review_by_mad=True
|
version=self.review_version, needs_human_review_by_mad=True
|
||||||
)
|
)
|
||||||
# Safeguards.
|
# Safeguards.
|
||||||
assert isinstance(self.helper.handler, ReviewUnlisted)
|
assert isinstance(self.helper.handler, ReviewUnlisted)
|
||||||
|
@ -2506,7 +2608,7 @@ class TestReviewHelper(TestReviewHelperBase):
|
||||||
|
|
||||||
# We should have set redirect_url to point to the Block admin page
|
# We should have set redirect_url to point to the Block admin page
|
||||||
if '%s' in redirect_url:
|
if '%s' in redirect_url:
|
||||||
redirect_url = redirect_url % (old_version.pk, self.version.pk)
|
redirect_url = redirect_url % (old_version.pk, self.review_version.pk)
|
||||||
assert self.helper.redirect_url == redirect_url
|
assert self.helper.redirect_url == redirect_url
|
||||||
|
|
||||||
def test_pending_blocklistsubmission_multiple_unlisted_versions(self):
|
def test_pending_blocklistsubmission_multiple_unlisted_versions(self):
|
||||||
|
@ -2564,9 +2666,9 @@ class TestReviewHelperSigning(TestReviewHelperBase):
|
||||||
file_kw={'filename': 'webextension.xpi'},
|
file_kw={'filename': 'webextension.xpi'},
|
||||||
users=[self.user],
|
users=[self.user],
|
||||||
)
|
)
|
||||||
self.version = self.addon.versions.all()[0]
|
self.review_version = self.addon.versions.all()[0]
|
||||||
self.helper = self.get_helper()
|
self.helper = self.get_helper()
|
||||||
self.file = self.version.file
|
self.file = self.review_version.file
|
||||||
|
|
||||||
def test_nomination_to_public(self):
|
def test_nomination_to_public(self):
|
||||||
self.setup_data(amo.STATUS_NOMINATED)
|
self.setup_data(amo.STATUS_NOMINATED)
|
||||||
|
|
|
@ -2864,6 +2864,7 @@ class TestReview(ReviewBase):
|
||||||
'public',
|
'public',
|
||||||
'reject',
|
'reject',
|
||||||
'reject_multiple_versions',
|
'reject_multiple_versions',
|
||||||
|
'unreject_multiple_versions',
|
||||||
'reply',
|
'reply',
|
||||||
'super',
|
'super',
|
||||||
'comment',
|
'comment',
|
||||||
|
@ -5008,6 +5009,85 @@ class TestReview(ReviewBase):
|
||||||
assert version.pending_rejection
|
assert version.pending_rejection
|
||||||
self.assertCloseToNow(version.pending_rejection, now=in_the_future)
|
self.assertCloseToNow(version.pending_rejection, now=in_the_future)
|
||||||
|
|
||||||
|
def test_unreject_multiple_versions(self):
|
||||||
|
old_version = self.version
|
||||||
|
version_factory(addon=self.addon, version='2.99')
|
||||||
|
old_version.file.update(status=amo.STATUS_DISABLED)
|
||||||
|
self.version = version_factory(
|
||||||
|
addon=self.addon, version='3.0', file_kw={'status': amo.STATUS_DISABLED}
|
||||||
|
)
|
||||||
|
GroupUser.objects.filter(user=self.reviewer).all().delete()
|
||||||
|
self.grant_permission(self.reviewer, 'Addons:Review')
|
||||||
|
self.grant_permission(self.reviewer, 'Reviews:Admin')
|
||||||
|
assert self.addon.status == amo.STATUS_APPROVED
|
||||||
|
|
||||||
|
response = self.client.post(
|
||||||
|
self.url,
|
||||||
|
{
|
||||||
|
'action': 'unreject_multiple_versions',
|
||||||
|
'versions': [old_version.pk, self.version.pk],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 302
|
||||||
|
for version in [old_version, self.version]:
|
||||||
|
file_ = version.file.reload()
|
||||||
|
assert file_.status == amo.STATUS_AWAITING_REVIEW
|
||||||
|
assert self.addon.reload().status == amo.STATUS_APPROVED
|
||||||
|
|
||||||
|
def test_unreject_multiple_versions_to_nominated(self):
|
||||||
|
old_version = self.version
|
||||||
|
old_version.file.update(status=amo.STATUS_DISABLED)
|
||||||
|
self.version = version_factory(
|
||||||
|
addon=self.addon, version='3.0', file_kw={'status': amo.STATUS_DISABLED}
|
||||||
|
)
|
||||||
|
GroupUser.objects.filter(user=self.reviewer).all().delete()
|
||||||
|
self.grant_permission(self.reviewer, 'Addons:Review')
|
||||||
|
self.grant_permission(self.reviewer, 'Reviews:Admin')
|
||||||
|
assert self.addon.status == amo.STATUS_NULL
|
||||||
|
|
||||||
|
response = self.client.post(
|
||||||
|
self.url,
|
||||||
|
{
|
||||||
|
'action': 'unreject_multiple_versions',
|
||||||
|
'versions': [old_version.pk, self.version.pk],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 302
|
||||||
|
for version in [old_version, self.version]:
|
||||||
|
file_ = version.file.reload()
|
||||||
|
assert file_.status == amo.STATUS_AWAITING_REVIEW
|
||||||
|
assert self.addon.reload().status == amo.STATUS_NOMINATED
|
||||||
|
|
||||||
|
def test_unreject_multiple_versions_with_unlisted(self):
|
||||||
|
old_version = self.version
|
||||||
|
old_version.file.update(status=amo.STATUS_DISABLED)
|
||||||
|
self.version = version_factory(
|
||||||
|
addon=self.addon, version='3.0', file_kw={'status': amo.STATUS_DISABLED}
|
||||||
|
)
|
||||||
|
self.make_addon_unlisted(self.addon)
|
||||||
|
GroupUser.objects.filter(user=self.reviewer).all().delete()
|
||||||
|
self.grant_permission(self.reviewer, 'Addons:Review')
|
||||||
|
self.grant_permission(self.reviewer, 'Reviews:Admin')
|
||||||
|
self.grant_permission(self.reviewer, 'Addons:ReviewUnlisted')
|
||||||
|
assert self.addon.status == amo.STATUS_NULL
|
||||||
|
|
||||||
|
unlisted_url = reverse('reviewers.review', args=['unlisted', self.addon.pk])
|
||||||
|
response = self.client.post(
|
||||||
|
unlisted_url,
|
||||||
|
{
|
||||||
|
'action': 'unreject_multiple_versions',
|
||||||
|
'versions': [old_version.pk, self.version.pk],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 302
|
||||||
|
for version in [old_version, self.version]:
|
||||||
|
file_ = version.file.reload()
|
||||||
|
assert file_.status == amo.STATUS_AWAITING_REVIEW
|
||||||
|
assert self.addon.reload().status == amo.STATUS_NULL
|
||||||
|
|
||||||
def test_block_multiple_versions(self):
|
def test_block_multiple_versions(self):
|
||||||
self.url = reverse('reviewers.review', args=('unlisted', self.addon.pk))
|
self.url = reverse('reviewers.review', args=('unlisted', self.addon.pk))
|
||||||
old_version = self.version
|
old_version = self.version
|
||||||
|
|
|
@ -561,9 +561,11 @@ class ReviewHelper:
|
||||||
is_appropriate_reviewer_post_review = acl.action_allowed_for(
|
is_appropriate_reviewer_post_review = acl.action_allowed_for(
|
||||||
self.user, permission_post_review
|
self.user, permission_post_review
|
||||||
)
|
)
|
||||||
|
is_admin_reviewer = is_appropriate_reviewer and acl.action_allowed_for(
|
||||||
|
self.user, amo.permissions.REVIEWS_ADMIN
|
||||||
|
)
|
||||||
|
|
||||||
addon_is_complete_and_not_disabled = self.addon.status not in (
|
addon_is_not_disabled_or_deleted = self.addon.status not in (
|
||||||
amo.STATUS_NULL,
|
|
||||||
amo.STATUS_DELETED,
|
amo.STATUS_DELETED,
|
||||||
amo.STATUS_DISABLED,
|
amo.STATUS_DISABLED,
|
||||||
)
|
)
|
||||||
|
@ -571,9 +573,8 @@ class ReviewHelper:
|
||||||
self.addon.status == amo.STATUS_NULL and version_is_unlisted
|
self.addon.status == amo.STATUS_NULL and version_is_unlisted
|
||||||
)
|
)
|
||||||
addon_is_reviewable = (
|
addon_is_reviewable = (
|
||||||
addon_is_complete_and_not_disabled
|
addon_is_not_disabled_or_deleted and self.addon.status != amo.STATUS_NULL
|
||||||
or addon_is_incomplete_and_version_is_unlisted
|
) or addon_is_incomplete_and_version_is_unlisted
|
||||||
)
|
|
||||||
version_is_unreviewed = self.version and self.version.is_unreviewed
|
version_is_unreviewed = self.version and self.version.is_unreviewed
|
||||||
addon_is_valid = self.addon.is_public() or self.addon.is_unreviewed()
|
addon_is_valid = self.addon.is_public() or self.addon.is_unreviewed()
|
||||||
addon_is_valid_and_version_is_listed = (
|
addon_is_valid_and_version_is_listed = (
|
||||||
|
@ -689,7 +690,7 @@ class ReviewHelper:
|
||||||
'method': self.handler.approve_multiple_versions,
|
'method': self.handler.approve_multiple_versions,
|
||||||
'label': _('Approve Multiple Versions'),
|
'label': _('Approve Multiple Versions'),
|
||||||
'minimal': True,
|
'minimal': True,
|
||||||
'versions': True,
|
'multiple_versions': True,
|
||||||
'details': _(
|
'details': _(
|
||||||
'This will approve the selected versions. '
|
'This will approve the selected versions. '
|
||||||
'The comments will be sent to the developer.'
|
'The comments will be sent to the developer.'
|
||||||
|
@ -708,7 +709,7 @@ class ReviewHelper:
|
||||||
# or (unlisted and) awaiting review
|
# or (unlisted and) awaiting review
|
||||||
or self.version.file.status == amo.STATUS_AWAITING_REVIEW
|
or self.version.file.status == amo.STATUS_AWAITING_REVIEW
|
||||||
),
|
),
|
||||||
'versions': True,
|
'multiple_versions': True,
|
||||||
'details': _(
|
'details': _(
|
||||||
'This will reject the selected versions. '
|
'This will reject the selected versions. '
|
||||||
'The comments will be sent to the developer.'
|
'The comments will be sent to the developer.'
|
||||||
|
@ -717,11 +718,23 @@ class ReviewHelper:
|
||||||
'allows_reasons': not is_static_theme,
|
'allows_reasons': not is_static_theme,
|
||||||
'requires_reasons': not is_static_theme,
|
'requires_reasons': not is_static_theme,
|
||||||
}
|
}
|
||||||
|
actions['unreject_multiple_versions'] = {
|
||||||
|
'method': self.handler.unreject_multiple_versions,
|
||||||
|
'label': _('Un-Reject Versions'),
|
||||||
|
'minimal': True,
|
||||||
|
'multiple_versions': True,
|
||||||
|
'details': _(
|
||||||
|
'This will un-reject the selected versions without notifying the '
|
||||||
|
'developer.'
|
||||||
|
),
|
||||||
|
'comments': False,
|
||||||
|
'available': (addon_is_not_disabled_or_deleted and is_admin_reviewer),
|
||||||
|
}
|
||||||
actions['block_multiple_versions'] = {
|
actions['block_multiple_versions'] = {
|
||||||
'method': self.handler.block_multiple_versions,
|
'method': self.handler.block_multiple_versions,
|
||||||
'label': _('Block Multiple Versions'),
|
'label': _('Block Multiple Versions'),
|
||||||
'minimal': True,
|
'minimal': True,
|
||||||
'versions': True,
|
'multiple_versions': True,
|
||||||
'comments': False,
|
'comments': False,
|
||||||
'details': _(
|
'details': _(
|
||||||
'This will disable the selected approved '
|
'This will disable the selected approved '
|
||||||
|
@ -736,7 +749,7 @@ class ReviewHelper:
|
||||||
'method': self.handler.confirm_multiple_versions,
|
'method': self.handler.confirm_multiple_versions,
|
||||||
'label': _('Confirm Multiple Versions'),
|
'label': _('Confirm Multiple Versions'),
|
||||||
'minimal': True,
|
'minimal': True,
|
||||||
'versions': True,
|
'multiple_versions': True,
|
||||||
'details': _(
|
'details': _(
|
||||||
'This will confirm approval of the selected '
|
'This will confirm approval of the selected '
|
||||||
'versions without notifying the developer.'
|
'versions without notifying the developer.'
|
||||||
|
@ -1360,6 +1373,37 @@ class ReviewBase:
|
||||||
content_review=self.content_review,
|
content_review=self.content_review,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def unreject_multiple_versions(self):
|
||||||
|
"""Un-reject a list of versions."""
|
||||||
|
# self.version and self.file won't point to the versions we want to
|
||||||
|
# modify in this action, so set them to None before finding the right
|
||||||
|
# versions.
|
||||||
|
self.version = None
|
||||||
|
self.file = None
|
||||||
|
now = datetime.now()
|
||||||
|
# we're only supporting non-automated reviews right now:
|
||||||
|
assert self.human_review
|
||||||
|
|
||||||
|
log.info(
|
||||||
|
'Making %s versions %s awaiting review (not disabled)'
|
||||||
|
% (self.addon, ', '.join(str(v.pk) for v in self.data['versions']))
|
||||||
|
)
|
||||||
|
|
||||||
|
for version in self.data['versions']:
|
||||||
|
self.set_file(amo.STATUS_AWAITING_REVIEW, version.file)
|
||||||
|
|
||||||
|
self.log_action(
|
||||||
|
action=amo.LOG.UNREJECT_VERSION,
|
||||||
|
version=version,
|
||||||
|
file=version.file,
|
||||||
|
timestamp=now,
|
||||||
|
user=self.user,
|
||||||
|
)
|
||||||
|
|
||||||
|
if self.data['versions']:
|
||||||
|
# if these are listed versions then the addon status may need updating
|
||||||
|
self.addon.update_nominated_status(self.user)
|
||||||
|
|
||||||
def notify_about_auto_approval_delay(self, version):
|
def notify_about_auto_approval_delay(self, version):
|
||||||
"""Notify developers of the add-on when their version has not been
|
"""Notify developers of the add-on when their version has not been
|
||||||
auto-approved for a while."""
|
auto-approved for a while."""
|
||||||
|
|
Загрузка…
Ссылка в новой задаче