bye bye preliminary - editors (#3594)
This commit is contained in:
Родитель
aab1e8cfd8
Коммит
42b82a57c1
|
@ -39,9 +39,7 @@ class Command(BaseCommand):
|
||||||
def get_files(addon_guids):
|
def get_files(addon_guids):
|
||||||
"""Return the list of files that need approval, given a list of GUIDs.
|
"""Return the list of files that need approval, given a list of GUIDs.
|
||||||
|
|
||||||
A file needs approval if:
|
A file needs approval if it's unreviewed.
|
||||||
- it's unreviewed
|
|
||||||
- it's preliminary reviewed, but its addon is requesting a full review
|
|
||||||
"""
|
"""
|
||||||
# Get all the add-ons that have a GUID from the list, and which are either
|
# Get all the add-ons that have a GUID from the list, and which are either
|
||||||
# reviewed or awaiting a review.
|
# reviewed or awaiting a review.
|
||||||
|
@ -59,11 +57,7 @@ def get_files(addon_guids):
|
||||||
def approve_files(files_with_review_type):
|
def approve_files(files_with_review_type):
|
||||||
"""Approve the files (and sign them).
|
"""Approve the files (and sign them).
|
||||||
|
|
||||||
A file will be fully approved if:
|
A file will be fully approved if it's waiting for a full review
|
||||||
- it's waiting for a full review
|
|
||||||
- it's preliminary reviewed, and its addon is waiting for a full review
|
|
||||||
A file will be prelim approved if:
|
|
||||||
- it's waiting for a prelim review
|
|
||||||
"""
|
"""
|
||||||
for file_, review_type in files_with_review_type:
|
for file_, review_type in files_with_review_type:
|
||||||
version = file_.version
|
version = file_.version
|
||||||
|
@ -77,10 +71,6 @@ def approve_files(files_with_review_type):
|
||||||
# Already fully reviewed, or waiting for a full review.
|
# Already fully reviewed, or waiting for a full review.
|
||||||
helper.handler.process_public()
|
helper.handler.process_public()
|
||||||
log.info(u'File %s (addon %s) fully reviewed', file_.pk, addon.pk)
|
log.info(u'File %s (addon %s) fully reviewed', file_.pk, addon.pk)
|
||||||
elif review_type == 'prelim':
|
|
||||||
# Already prelim reviewed, or waiting for a prelim review.
|
|
||||||
helper.handler.process_preliminary()
|
|
||||||
log.info(u'File %s (addon %s) prelim reviewed', file_.pk, addon.pk)
|
|
||||||
else:
|
else:
|
||||||
log.info(u'File %s (addon %s) not reviewed: '
|
log.info(u'File %s (addon %s) not reviewed: '
|
||||||
u'addon status: %s, file status: %s',
|
u'addon status: %s, file status: %s',
|
||||||
|
@ -88,17 +78,10 @@ def approve_files(files_with_review_type):
|
||||||
|
|
||||||
|
|
||||||
def get_review_type(file_):
|
def get_review_type(file_):
|
||||||
"""Return 'full', 'prelim' or None depending on the file/addon status."""
|
"""Return 'full' or None depending on the file/addon status."""
|
||||||
addon_status = file_.version.addon.status
|
addon_status = file_.version.addon.status
|
||||||
if addon_status in [amo.STATUS_NOMINATED, amo.STATUS_LITE_AND_NOMINATED]:
|
if addon_status == amo.STATUS_NOMINATED or (
|
||||||
# Add-on is waiting for a full review.
|
addon_status == amo.STATUS_PUBLIC and
|
||||||
|
file_.status == amo.STATUS_UNREVIEWED):
|
||||||
|
# Add-on or file is waiting for a full review.
|
||||||
return 'full'
|
return 'full'
|
||||||
if addon_status == amo.STATUS_UNREVIEWED:
|
|
||||||
# Add-on is waiting for a prelim review.
|
|
||||||
return 'prelim'
|
|
||||||
if file_.status == amo.STATUS_UNREVIEWED:
|
|
||||||
# Addon is reviewed, not file.
|
|
||||||
if addon_status == amo.STATUS_PUBLIC:
|
|
||||||
return 'full'
|
|
||||||
elif addon_status == amo.STATUS_LITE:
|
|
||||||
return 'prelim'
|
|
||||||
|
|
|
@ -121,11 +121,8 @@ def id_function(fixture_value):
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(
|
@pytest.fixture(
|
||||||
params=[(amo.STATUS_UNREVIEWED, amo.STATUS_UNREVIEWED, 'prelim'),
|
params=[(amo.STATUS_NOMINATED, amo.STATUS_UNREVIEWED, 'full'),
|
||||||
(amo.STATUS_LITE, amo.STATUS_UNREVIEWED, 'prelim'),
|
(amo.STATUS_PUBLIC, amo.STATUS_UNREVIEWED, 'full')],
|
||||||
(amo.STATUS_NOMINATED, amo.STATUS_UNREVIEWED, 'full'),
|
|
||||||
(amo.STATUS_PUBLIC, amo.STATUS_UNREVIEWED, 'full'),
|
|
||||||
(amo.STATUS_LITE_AND_NOMINATED, amo.STATUS_LITE, 'full')],
|
|
||||||
# ids are used to build better names for the tests using this fixture.
|
# ids are used to build better names for the tests using this fixture.
|
||||||
ids=id_function)
|
ids=id_function)
|
||||||
def use_case(request, db):
|
def use_case(request, db):
|
||||||
|
@ -133,11 +130,8 @@ def use_case(request, db):
|
||||||
|
|
||||||
Addon | File1 and 2 | Review type
|
Addon | File1 and 2 | Review type
|
||||||
==============================================================
|
==============================================================
|
||||||
waiting for prelim | unreviewed | prelim reviewed
|
|
||||||
prelim reviewed | unreviewed | prelim reviewed
|
|
||||||
waiting for full | unreviewed | fully reviewed
|
waiting for full | unreviewed | fully reviewed
|
||||||
fully reviewed | unreviewed | fully reviewed
|
fully reviewed | unreviewed | fully reviewed
|
||||||
prelim waiting for full | prelim reviewed | fully reviewed
|
|
||||||
"""
|
"""
|
||||||
addon_status, file_status, review_type = request.param
|
addon_status, file_status, review_type = request.param
|
||||||
|
|
||||||
|
@ -194,10 +188,8 @@ def test_approve_addons_approve_files(use_case, mozilla_user):
|
||||||
addon, file1, file2, review_type = use_case
|
addon, file1, file2, review_type = use_case
|
||||||
approve_addons.approve_files([(file1, review_type),
|
approve_addons.approve_files([(file1, review_type),
|
||||||
(file2, review_type)])
|
(file2, review_type)])
|
||||||
assert file1.reload().status == (
|
assert file1.reload().status == amo.STATUS_PUBLIC
|
||||||
amo.STATUS_LITE if review_type == 'prelim' else amo.STATUS_PUBLIC)
|
assert file2.reload().status == amo.STATUS_PUBLIC
|
||||||
assert file2.reload().status == (
|
|
||||||
amo.STATUS_LITE if review_type == 'prelim' else amo.STATUS_PUBLIC)
|
|
||||||
logs = AddonLog.objects.filter(addon=addon)
|
logs = AddonLog.objects.filter(addon=addon)
|
||||||
assert len(logs) == 2 # One per file.
|
assert len(logs) == 2 # One per file.
|
||||||
file1_log, file2_log = logs
|
file1_log, file2_log = logs
|
||||||
|
|
|
@ -373,7 +373,7 @@ class ReviewForm(happyforms.Form):
|
||||||
|
|
||||||
responses = CannedResponse.objects.filter(type=self.type)
|
responses = CannedResponse.objects.filter(type=self.type)
|
||||||
|
|
||||||
# Loop through the actions (prelim, public, etc).
|
# Loop through the actions (public, etc).
|
||||||
for k, action in self.helper.actions.iteritems():
|
for k, action in self.helper.actions.iteritems():
|
||||||
action_choices = [[c.response, c.name] for c in responses
|
action_choices = [[c.response, c.name] for c in responses
|
||||||
if c.sort_group and k in c.sort_group.split(',')]
|
if c.sort_group and k in c.sort_group.split(',')]
|
||||||
|
|
|
@ -26,8 +26,8 @@ from olympia.amo.utils import send_mail as amo_send_mail, to_language
|
||||||
from olympia.constants.base import REVIEW_LIMITED_DELAY_HOURS
|
from olympia.constants.base import REVIEW_LIMITED_DELAY_HOURS
|
||||||
from olympia.editors.models import (
|
from olympia.editors.models import (
|
||||||
ReviewerScore, ViewFullReviewQueue, ViewPendingQueue,
|
ReviewerScore, ViewFullReviewQueue, ViewPendingQueue,
|
||||||
ViewPreliminaryQueue, ViewUnlistedAllList, ViewUnlistedFullReviewQueue,
|
ViewUnlistedAllList, ViewUnlistedFullReviewQueue,
|
||||||
ViewUnlistedPendingQueue, ViewUnlistedPreliminaryQueue)
|
ViewUnlistedPendingQueue)
|
||||||
from olympia.lib.crypto.packaged import sign_file
|
from olympia.lib.crypto.packaged import sign_file
|
||||||
from olympia.users.models import UserProfile
|
from olympia.users.models import UserProfile
|
||||||
|
|
||||||
|
@ -48,19 +48,7 @@ def file_compare(file_obj, version):
|
||||||
|
|
||||||
@register.function
|
@register.function
|
||||||
def file_review_status(addon, file):
|
def file_review_status(addon, file):
|
||||||
# If the file is pending review, check the add-on status
|
if file.status == amo.STATUS_DISABLED:
|
||||||
if file.status == amo.STATUS_UNREVIEWED:
|
|
||||||
if addon.status in [amo.STATUS_NOMINATED, amo.STATUS_PUBLIC]:
|
|
||||||
return _(u'Pending Full Review')
|
|
||||||
if addon.status in [amo.STATUS_UNREVIEWED, amo.STATUS_LITE]:
|
|
||||||
return _(u'Pending Preliminary Review')
|
|
||||||
# Special case: prelim upgrading to full approval,
|
|
||||||
# file can already be preliminary reviewed or not
|
|
||||||
if (file.status in [amo.STATUS_LITE, amo.STATUS_UNREVIEWED] and
|
|
||||||
addon.status == amo.STATUS_LITE_AND_NOMINATED):
|
|
||||||
if addon.latest_version.version_int == file.version.version_int:
|
|
||||||
return _(u'Pending Full Review')
|
|
||||||
if file.status in [amo.STATUS_DISABLED, amo.STATUS_REJECTED]:
|
|
||||||
if file.reviewed is not None:
|
if file.reviewed is not None:
|
||||||
return _(u'Rejected')
|
return _(u'Rejected')
|
||||||
# Can't assume that if the reviewed date is missing its
|
# Can't assume that if the reviewed date is missing its
|
||||||
|
@ -111,12 +99,8 @@ def editors_breadcrumbs(context, queue=None, addon_queue=None, items=None,
|
||||||
|
|
||||||
if addon_queue:
|
if addon_queue:
|
||||||
queue_id = addon_queue.status
|
queue_id = addon_queue.status
|
||||||
queue_ids = {amo.STATUS_UNREVIEWED: 'prelim',
|
queue_ids = {amo.STATUS_NOMINATED: 'nominated',
|
||||||
amo.STATUS_NOMINATED: 'nominated',
|
amo.STATUS_PUBLIC: 'pending'}
|
||||||
amo.STATUS_PUBLIC: 'pending',
|
|
||||||
amo.STATUS_LITE: 'prelim',
|
|
||||||
amo.STATUS_LITE_AND_NOMINATED: 'nominated',
|
|
||||||
amo.STATUS_PENDING: 'pending'}
|
|
||||||
|
|
||||||
queue = queue_ids.get(queue_id, 'queue')
|
queue = queue_ids.get(queue_id, 'queue')
|
||||||
|
|
||||||
|
@ -128,7 +112,6 @@ def editors_breadcrumbs(context, queue=None, addon_queue=None, items=None,
|
||||||
'queue': _('Queue'),
|
'queue': _('Queue'),
|
||||||
'pending': _('Pending Updates'),
|
'pending': _('Pending Updates'),
|
||||||
'nominated': _('Full Reviews'),
|
'nominated': _('Full Reviews'),
|
||||||
'prelim': _('Preliminary Reviews'),
|
|
||||||
'moderated': _('Moderated Reviews'),
|
'moderated': _('Moderated Reviews'),
|
||||||
|
|
||||||
'pending_themes': _('Pending Themes'),
|
'pending_themes': _('Pending Themes'),
|
||||||
|
@ -140,7 +123,6 @@ def editors_breadcrumbs(context, queue=None, addon_queue=None, items=None,
|
||||||
'queue': _('Queue'),
|
'queue': _('Queue'),
|
||||||
'pending': _('Unlisted Pending Updates'),
|
'pending': _('Unlisted Pending Updates'),
|
||||||
'nominated': _('Unlisted Full Reviews'),
|
'nominated': _('Unlisted Full Reviews'),
|
||||||
'prelim': _('Unlisted Preliminary Reviews'),
|
|
||||||
'all': _('All Unlisted Add-ons'),
|
'all': _('All Unlisted Add-ons'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,11 +163,6 @@ def queue_tabnav(context):
|
||||||
'Pending Updates ({0})',
|
'Pending Updates ({0})',
|
||||||
counts['pending'])
|
counts['pending'])
|
||||||
.format(counts['pending']))),
|
.format(counts['pending']))),
|
||||||
('prelim', 'queue_prelim',
|
|
||||||
(ngettext('Preliminary Review ({0})',
|
|
||||||
'Preliminary Reviews ({0})',
|
|
||||||
counts['prelim'])
|
|
||||||
.format(counts['prelim']))),
|
|
||||||
('moderated', 'queue_moderated',
|
('moderated', 'queue_moderated',
|
||||||
(ngettext('Moderated Review ({0})',
|
(ngettext('Moderated Review ({0})',
|
||||||
'Moderated Reviews ({0})',
|
'Moderated Reviews ({0})',
|
||||||
|
@ -202,11 +179,6 @@ def queue_tabnav(context):
|
||||||
'Unlisted Pending Updates ({0})',
|
'Unlisted Pending Updates ({0})',
|
||||||
unlisted_counts['pending'])
|
unlisted_counts['pending'])
|
||||||
.format(unlisted_counts['pending']))),
|
.format(unlisted_counts['pending']))),
|
||||||
('prelim', 'unlisted_queue_prelim',
|
|
||||||
(ngettext('Unlisted Preliminary Review ({0})',
|
|
||||||
'Unlisted Preliminary Reviews ({0})',
|
|
||||||
unlisted_counts['prelim'])
|
|
||||||
.format(unlisted_counts['prelim']))),
|
|
||||||
('all', 'unlisted_queue_all',
|
('all', 'unlisted_queue_all',
|
||||||
(ngettext('All Unlisted Add-ons ({0})',
|
(ngettext('All Unlisted Add-ons ({0})',
|
||||||
'All Unlisted Add-ons ({0})',
|
'All Unlisted Add-ons ({0})',
|
||||||
|
@ -419,12 +391,6 @@ class ViewFullReviewQueueTable(EditorQueueTable):
|
||||||
model = ViewFullReviewQueue
|
model = ViewFullReviewQueue
|
||||||
|
|
||||||
|
|
||||||
class ViewPreliminaryQueueTable(EditorQueueTable):
|
|
||||||
|
|
||||||
class Meta(EditorQueueTable.Meta):
|
|
||||||
model = ViewPreliminaryQueue
|
|
||||||
|
|
||||||
|
|
||||||
class ViewUnlistedPendingQueueTable(EditorQueueTable):
|
class ViewUnlistedPendingQueueTable(EditorQueueTable):
|
||||||
|
|
||||||
class Meta(EditorQueueTable.Meta):
|
class Meta(EditorQueueTable.Meta):
|
||||||
|
@ -437,12 +403,6 @@ class ViewUnlistedFullReviewQueueTable(EditorQueueTable):
|
||||||
model = ViewUnlistedFullReviewQueue
|
model = ViewUnlistedFullReviewQueue
|
||||||
|
|
||||||
|
|
||||||
class ViewUnlistedPreliminaryQueueTable(EditorQueueTable):
|
|
||||||
|
|
||||||
class Meta(EditorQueueTable.Meta):
|
|
||||||
model = ViewUnlistedPreliminaryQueue
|
|
||||||
|
|
||||||
|
|
||||||
class ViewUnlistedAllListTable(EditorAllListTable):
|
class ViewUnlistedAllListTable(EditorAllListTable):
|
||||||
|
|
||||||
class Meta(EditorQueueTable.Meta):
|
class Meta(EditorQueueTable.Meta):
|
||||||
|
@ -452,8 +412,6 @@ class ViewUnlistedAllListTable(EditorAllListTable):
|
||||||
log = commonware.log.getLogger('z.mailer')
|
log = commonware.log.getLogger('z.mailer')
|
||||||
|
|
||||||
|
|
||||||
NOMINATED_STATUSES = (amo.STATUS_NOMINATED, amo.STATUS_LITE_AND_NOMINATED)
|
|
||||||
PRELIMINARY_STATUSES = (amo.STATUS_UNREVIEWED, amo.STATUS_LITE)
|
|
||||||
PENDING_STATUSES = (amo.STATUS_BETA, amo.STATUS_DISABLED, amo.STATUS_NULL,
|
PENDING_STATUSES = (amo.STATUS_BETA, amo.STATUS_DISABLED, amo.STATUS_NULL,
|
||||||
amo.STATUS_PENDING, amo.STATUS_PUBLIC)
|
amo.STATUS_PENDING, amo.STATUS_PUBLIC)
|
||||||
|
|
||||||
|
@ -510,17 +468,9 @@ class ReviewHelper:
|
||||||
self.handler.set_data(data)
|
self.handler.set_data(data)
|
||||||
|
|
||||||
def get_review_type(self, request, addon, version):
|
def get_review_type(self, request, addon, version):
|
||||||
if self.addon.status in NOMINATED_STATUSES:
|
if self.addon.status == amo.STATUS_NOMINATED:
|
||||||
self.review_type = 'nominated'
|
self.review_type = 'nominated'
|
||||||
self.handler = ReviewAddon(request, addon, version, 'nominated')
|
self.handler = ReviewAddon(request, addon, version, 'nominated')
|
||||||
|
|
||||||
elif self.addon.status == amo.STATUS_UNREVIEWED:
|
|
||||||
self.review_type = 'preliminary'
|
|
||||||
self.handler = ReviewAddon(request, addon, version, 'preliminary')
|
|
||||||
|
|
||||||
elif self.addon.status == amo.STATUS_LITE:
|
|
||||||
self.review_type = 'preliminary'
|
|
||||||
self.handler = ReviewFiles(request, addon, version, 'preliminary')
|
|
||||||
else:
|
else:
|
||||||
self.review_type = 'pending'
|
self.review_type = 'pending'
|
||||||
self.handler = ReviewFiles(request, addon, version, 'pending')
|
self.handler = ReviewFiles(request, addon, version, 'pending')
|
||||||
|
@ -532,7 +482,6 @@ class ReviewHelper:
|
||||||
# ReviewHelper for its `handler` attribute and we don't care about
|
# ReviewHelper for its `handler` attribute and we don't care about
|
||||||
# the actions.
|
# the actions.
|
||||||
return actions
|
return actions
|
||||||
labels, details = self._review_actions()
|
|
||||||
reviewable_because_complete = addon.status not in (
|
reviewable_because_complete = addon.status not in (
|
||||||
amo.STATUS_NULL, amo.STATUS_DELETED)
|
amo.STATUS_NULL, amo.STATUS_DELETED)
|
||||||
reviewable_because_admin = (
|
reviewable_because_admin = (
|
||||||
|
@ -544,101 +493,51 @@ class ReviewHelper:
|
||||||
addon.latest_version.nomination is not None and
|
addon.latest_version.nomination is not None and
|
||||||
(datetime.datetime.now() - addon.latest_version.nomination >=
|
(datetime.datetime.now() - addon.latest_version.nomination >=
|
||||||
datetime.timedelta(hours=REVIEW_LIMITED_DELAY_HOURS))))
|
datetime.timedelta(hours=REVIEW_LIMITED_DELAY_HOURS))))
|
||||||
reviewable_because_pending = addon.latest_version is not None and (
|
reviewable_because_pending = (
|
||||||
len(addon.latest_version.is_unreviewed) > 0 or
|
addon.latest_version is not None and
|
||||||
addon.status == amo.STATUS_LITE_AND_NOMINATED)
|
len(addon.latest_version.is_unreviewed) > 0)
|
||||||
if (reviewable_because_complete and
|
if (reviewable_because_complete and
|
||||||
reviewable_because_admin and
|
reviewable_because_admin and
|
||||||
reviewable_because_submission_time and
|
reviewable_because_submission_time and
|
||||||
reviewable_because_pending):
|
reviewable_because_pending):
|
||||||
if self.review_type != 'preliminary':
|
actions['public'] = {
|
||||||
if addon.is_listed:
|
'method': self.handler.process_public,
|
||||||
label = _lazy('Push to public')
|
'minimal': False,
|
||||||
else:
|
'details': _lazy('This will approve, sign, and publish this '
|
||||||
label = _lazy('Grant full review')
|
'version. The comments will be sent to the '
|
||||||
actions['public'] = {'method': self.handler.process_public,
|
'developer.'),
|
||||||
'minimal': False,
|
'label': _lazy('Approve')}
|
||||||
'label': label}
|
actions['reject'] = {
|
||||||
# An unlisted sideload add-on, which requests a full review, cannot
|
'method': self.handler.process_sandbox,
|
||||||
# be granted a preliminary review.
|
'label': _lazy('Reject'),
|
||||||
prelim_allowed = not waffle.flag_is_active(
|
'details': _lazy('This will reject this version and remove it '
|
||||||
request, 'no-prelim-review') and addon.is_listed
|
'from the queue. The comments will be sent '
|
||||||
if prelim_allowed or self.review_type == 'preliminary':
|
'to the developer.'),
|
||||||
actions['prelim'] = {
|
'minimal': False}
|
||||||
'method': self.handler.process_preliminary,
|
actions['info'] = {
|
||||||
'label': labels['prelim'],
|
'method': self.handler.request_information,
|
||||||
'minimal': False}
|
'label': _lazy('Request more information'),
|
||||||
actions['reject'] = {'method': self.handler.process_sandbox,
|
'details': _lazy('This will request more information from the '
|
||||||
'label': _lazy('Reject'),
|
'developer. You will be notified when they '
|
||||||
'minimal': False}
|
'reply.'),
|
||||||
actions['info'] = {'method': self.handler.request_information,
|
'minimal': True}
|
||||||
'label': _lazy('Request more information'),
|
actions['super'] = {
|
||||||
'minimal': True}
|
'method': self.handler.process_super_review,
|
||||||
actions['super'] = {'method': self.handler.process_super_review,
|
'label': _lazy('Request super-review'),
|
||||||
'label': _lazy('Request super-review'),
|
'details': _lazy('If you have concerns about this add-on that an '
|
||||||
'minimal': True}
|
'admin reviewer should look into, enter your '
|
||||||
actions['comment'] = {'method': self.handler.process_comment,
|
'comments in the area below. They will not be '
|
||||||
'label': _lazy('Comment'),
|
'sent to the developer.'),
|
||||||
'minimal': True}
|
'minimal': True}
|
||||||
for k, v in actions.items():
|
actions['comment'] = {
|
||||||
v['details'] = details.get(k)
|
'method': self.handler.process_comment,
|
||||||
|
'label': _lazy('Comment'),
|
||||||
|
'details': _lazy('Make a comment on this version. The developer '
|
||||||
|
'won\'t be able to see this.'),
|
||||||
|
'minimal': True}
|
||||||
|
|
||||||
return actions
|
return actions
|
||||||
|
|
||||||
def _review_actions(self):
|
|
||||||
labels = {'prelim': _lazy('Grant preliminary review')}
|
|
||||||
details = {'prelim': _lazy('This will mark the files as '
|
|
||||||
'preliminarily reviewed.'),
|
|
||||||
'info': _lazy('Use this form to request more information '
|
|
||||||
'from the author. They will receive an email '
|
|
||||||
'and be able to answer here. You will be '
|
|
||||||
'notified by email when they reply.'),
|
|
||||||
'super': _lazy('If you have concerns about this add-on\'s '
|
|
||||||
'security, copyright issues, or other '
|
|
||||||
'concerns that an administrator should look '
|
|
||||||
'into, enter your comments in the area '
|
|
||||||
'below. They will be sent to '
|
|
||||||
'administrators, not the author.'),
|
|
||||||
'reject': _lazy('This will reject the add-on and remove '
|
|
||||||
'it from the review queue.'),
|
|
||||||
'comment': _lazy('Make a comment on this version. The '
|
|
||||||
'author won\'t be able to see this.')}
|
|
||||||
|
|
||||||
if self.addon.status == amo.STATUS_LITE:
|
|
||||||
details['reject'] = _lazy('This will reject the files and remove '
|
|
||||||
'them from the review queue.')
|
|
||||||
|
|
||||||
if self.addon.status in (amo.STATUS_UNREVIEWED, amo.STATUS_NOMINATED):
|
|
||||||
details['prelim'] = _lazy('This will mark the add-on as '
|
|
||||||
'preliminarily reviewed. Future '
|
|
||||||
'versions will undergo '
|
|
||||||
'preliminary review.')
|
|
||||||
elif self.addon.status == amo.STATUS_LITE:
|
|
||||||
details['prelim'] = _lazy('This will mark the files as '
|
|
||||||
'preliminarily reviewed. Future '
|
|
||||||
'versions will undergo '
|
|
||||||
'preliminary review.')
|
|
||||||
elif self.addon.status == amo.STATUS_LITE_AND_NOMINATED:
|
|
||||||
labels['prelim'] = _lazy('Retain preliminary review')
|
|
||||||
details['prelim'] = _lazy('This will retain the add-on as '
|
|
||||||
'preliminarily reviewed. Future '
|
|
||||||
'versions will undergo preliminary '
|
|
||||||
'review.')
|
|
||||||
if self.review_type == 'pending':
|
|
||||||
details['public'] = _lazy('This will approve a sandboxed version '
|
|
||||||
'of a public add-on to appear on the '
|
|
||||||
'public site.')
|
|
||||||
details['reject'] = _lazy('This will reject a version of a public '
|
|
||||||
'add-on and remove it from the queue.')
|
|
||||||
else:
|
|
||||||
details['public'] = _lazy('This will mark the add-on and its most '
|
|
||||||
'recent version and files as public. '
|
|
||||||
'Future versions will go into the '
|
|
||||||
'sandbox until they are reviewed by an '
|
|
||||||
'editor.')
|
|
||||||
|
|
||||||
return labels, details
|
|
||||||
|
|
||||||
def process(self):
|
def process(self):
|
||||||
action = self.handler.data.get('action', '')
|
action = self.handler.data.get('action', '')
|
||||||
if not action:
|
if not action:
|
||||||
|
@ -785,21 +684,11 @@ class ReviewBase(object):
|
||||||
|
|
||||||
class ReviewAddon(ReviewBase):
|
class ReviewAddon(ReviewBase):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super(ReviewAddon, self).__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
self.is_upgrade = (
|
|
||||||
self.addon.status == amo.STATUS_LITE_AND_NOMINATED and
|
|
||||||
self.review_type == 'nominated')
|
|
||||||
|
|
||||||
def set_data(self, data):
|
def set_data(self, data):
|
||||||
self.data = data
|
self.data = data
|
||||||
|
|
||||||
def process_public(self, auto_validation=False):
|
def process_public(self, auto_validation=False):
|
||||||
"""Set an addon to public."""
|
"""Set an addon to public."""
|
||||||
if self.review_type == 'preliminary':
|
|
||||||
raise AssertionError('Preliminary addons cannot be made public.')
|
|
||||||
|
|
||||||
# Sign addon.
|
# Sign addon.
|
||||||
for file_ in self.files:
|
for file_ in self.files:
|
||||||
sign_file(file_, settings.SIGNING_SERVER)
|
sign_file(file_, settings.SIGNING_SERVER)
|
||||||
|
@ -835,13 +724,7 @@ class ReviewAddon(ReviewBase):
|
||||||
# Hold onto the status before we change it.
|
# Hold onto the status before we change it.
|
||||||
status = self.addon.status
|
status = self.addon.status
|
||||||
|
|
||||||
if (not self.is_upgrade or
|
self.set_addon(status=amo.STATUS_NULL)
|
||||||
not self.addon.versions.exclude(id=self.version.id)
|
|
||||||
.filter(files__status__in=amo.REVIEWED_STATUSES)):
|
|
||||||
self.set_addon(status=amo.STATUS_NULL)
|
|
||||||
else:
|
|
||||||
self.set_addon(status=amo.STATUS_LITE)
|
|
||||||
|
|
||||||
self.set_files(amo.STATUS_DISABLED, self.files,
|
self.set_files(amo.STATUS_DISABLED, self.files,
|
||||||
hide_disabled_file=True)
|
hide_disabled_file=True)
|
||||||
|
|
||||||
|
@ -860,40 +743,6 @@ class ReviewAddon(ReviewBase):
|
||||||
if self.request:
|
if self.request:
|
||||||
ReviewerScore.award_points(self.request.user, self.addon, status)
|
ReviewerScore.award_points(self.request.user, self.addon, status)
|
||||||
|
|
||||||
def process_preliminary(self, auto_validation=False):
|
|
||||||
"""Set an addon to preliminary."""
|
|
||||||
# Sign addon.
|
|
||||||
for file_ in self.files:
|
|
||||||
sign_file(file_, settings.PRELIMINARY_SIGNING_SERVER)
|
|
||||||
|
|
||||||
# Hold onto the status before we change it.
|
|
||||||
status = self.addon.status
|
|
||||||
|
|
||||||
changes = {'status': amo.STATUS_LITE}
|
|
||||||
template = u'%s_to_preliminary' % self.review_type
|
|
||||||
subject = u'Mozilla Add-ons: %s %s Preliminary Reviewed'
|
|
||||||
if (self.review_type == 'preliminary' and
|
|
||||||
self.addon.status == amo.STATUS_LITE_AND_NOMINATED):
|
|
||||||
template = u'nominated_to_nominated'
|
|
||||||
if not self.addon.is_listed:
|
|
||||||
template = u'unlisted_to_reviewed'
|
|
||||||
if auto_validation:
|
|
||||||
template = u'unlisted_to_reviewed_auto'
|
|
||||||
subject = u'Mozilla Add-ons: %s %s signed and ready to download'
|
|
||||||
|
|
||||||
self.set_addon(**changes)
|
|
||||||
self.set_files(amo.STATUS_LITE, self.files, copy_to_mirror=True)
|
|
||||||
|
|
||||||
self.log_action(amo.LOG.PRELIMINARY_VERSION)
|
|
||||||
self.notify_email(template, subject)
|
|
||||||
|
|
||||||
log.info(u'Making %s preliminary' % (self.addon))
|
|
||||||
log.info(u'Sending email for %s' % (self.addon))
|
|
||||||
|
|
||||||
if self.request and not auto_validation:
|
|
||||||
# Assign reviewer incentive scores.
|
|
||||||
ReviewerScore.award_points(self.request.user, self.addon, status)
|
|
||||||
|
|
||||||
def process_super_review(self):
|
def process_super_review(self):
|
||||||
"""Give an addon super review."""
|
"""Give an addon super review."""
|
||||||
self.addon.update(admin_review=True)
|
self.addon.update(admin_review=True)
|
||||||
|
@ -911,9 +760,6 @@ class ReviewFiles(ReviewBase):
|
||||||
|
|
||||||
def process_public(self, auto_validation=False):
|
def process_public(self, auto_validation=False):
|
||||||
"""Set an addons files to public."""
|
"""Set an addons files to public."""
|
||||||
if self.review_type == 'preliminary':
|
|
||||||
raise AssertionError('Preliminary addons cannot be made public.')
|
|
||||||
|
|
||||||
# Sign addon.
|
# Sign addon.
|
||||||
for file_ in self.files:
|
for file_ in self.files:
|
||||||
sign_file(file_, settings.SIGNING_SERVER)
|
sign_file(file_, settings.SIGNING_SERVER)
|
||||||
|
@ -966,37 +812,8 @@ class ReviewFiles(ReviewBase):
|
||||||
if self.request:
|
if self.request:
|
||||||
ReviewerScore.award_points(self.request.user, self.addon, status)
|
ReviewerScore.award_points(self.request.user, self.addon, status)
|
||||||
|
|
||||||
def process_preliminary(self, auto_validation=False):
|
|
||||||
"""Set an addons files to preliminary."""
|
|
||||||
# Sign addon.
|
|
||||||
for file_ in self.files:
|
|
||||||
sign_file(file_, settings.PRELIMINARY_SIGNING_SERVER)
|
|
||||||
|
|
||||||
# Hold onto the status before we change it.
|
|
||||||
status = self.addon.status
|
|
||||||
|
|
||||||
self.set_files(amo.STATUS_LITE, self.files, copy_to_mirror=True)
|
|
||||||
|
|
||||||
self.log_action(amo.LOG.PRELIMINARY_VERSION)
|
|
||||||
template = u'%s_to_preliminary' % self.review_type
|
|
||||||
subject = u'Mozilla Add-ons: %s %s Preliminary Reviewed'
|
|
||||||
if not self.addon.is_listed:
|
|
||||||
template = u'unlisted_to_reviewed'
|
|
||||||
if auto_validation:
|
|
||||||
template = u'unlisted_to_reviewed_auto'
|
|
||||||
subject = u'Mozilla Add-ons: %s %s signed and ready to download'
|
|
||||||
self.notify_email(template, subject)
|
|
||||||
|
|
||||||
log.info(u'Making %s files %s preliminary' %
|
|
||||||
(self.addon, ', '.join([f.filename for f in self.files])))
|
|
||||||
log.info(u'Sending email for %s' % (self.addon))
|
|
||||||
|
|
||||||
if self.request and not auto_validation:
|
|
||||||
# Assign reviewer incentive scores.
|
|
||||||
ReviewerScore.award_points(self.request.user, self.addon, status)
|
|
||||||
|
|
||||||
def process_super_review(self):
|
def process_super_review(self):
|
||||||
"""Give an addon super review when preliminary."""
|
"""Give an addon super review."""
|
||||||
self.addon.update(admin_review=True)
|
self.addon.update(admin_review=True)
|
||||||
|
|
||||||
self.notify_email('author_super_review',
|
self.notify_email('author_super_review',
|
||||||
|
|
|
@ -201,9 +201,7 @@ class ViewFullReviewQueue(ViewQueue):
|
||||||
def base_query(self):
|
def base_query(self):
|
||||||
q = super(ViewFullReviewQueue, self).base_query()
|
q = super(ViewFullReviewQueue, self).base_query()
|
||||||
q['where'].extend(['files.status <> %s' % amo.STATUS_BETA,
|
q['where'].extend(['files.status <> %s' % amo.STATUS_BETA,
|
||||||
'addons.status IN (%s, %s)' % (
|
'addons.status = %s' % amo.STATUS_NOMINATED])
|
||||||
amo.STATUS_NOMINATED,
|
|
||||||
amo.STATUS_LITE_AND_NOMINATED)])
|
|
||||||
return q
|
return q
|
||||||
|
|
||||||
|
|
||||||
|
@ -216,17 +214,6 @@ class ViewPendingQueue(ViewQueue):
|
||||||
return q
|
return q
|
||||||
|
|
||||||
|
|
||||||
class ViewPreliminaryQueue(ViewQueue):
|
|
||||||
|
|
||||||
def base_query(self):
|
|
||||||
q = super(ViewPreliminaryQueue, self).base_query()
|
|
||||||
q['where'].extend(['files.status = %s' % amo.STATUS_UNREVIEWED,
|
|
||||||
'addons.status IN (%s, %s)' % (
|
|
||||||
amo.STATUS_LITE,
|
|
||||||
amo.STATUS_UNREVIEWED)])
|
|
||||||
return q
|
|
||||||
|
|
||||||
|
|
||||||
class ViewAllList(RawSQLModel):
|
class ViewAllList(RawSQLModel):
|
||||||
id = models.IntegerField()
|
id = models.IntegerField()
|
||||||
addon_name = models.CharField(max_length=255)
|
addon_name = models.CharField(max_length=255)
|
||||||
|
@ -316,10 +303,6 @@ class ViewUnlistedPendingQueue(ViewPendingQueue):
|
||||||
listed = False
|
listed = False
|
||||||
|
|
||||||
|
|
||||||
class ViewUnlistedPreliminaryQueue(ViewPreliminaryQueue):
|
|
||||||
listed = False
|
|
||||||
|
|
||||||
|
|
||||||
class ViewUnlistedAllList(ViewAllList):
|
class ViewUnlistedAllList(ViewAllList):
|
||||||
listed = False
|
listed = False
|
||||||
|
|
||||||
|
@ -434,9 +417,7 @@ class ReviewerScore(ModelBase):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
queue = ''
|
queue = ''
|
||||||
if status in [amo.STATUS_UNREVIEWED, amo.STATUS_LITE]:
|
if status == amo.STATUS_NOMINATED:
|
||||||
queue = 'PRELIM'
|
|
||||||
elif status in [amo.STATUS_NOMINATED, amo.STATUS_LITE_AND_NOMINATED]:
|
|
||||||
queue = 'FULL'
|
queue = 'FULL'
|
||||||
elif status == amo.STATUS_PUBLIC:
|
elif status == amo.STATUS_PUBLIC:
|
||||||
queue = 'UPDATE'
|
queue = 'UPDATE'
|
||||||
|
|
|
@ -48,8 +48,6 @@
|
||||||
{{ _('Full Reviews') }} ({{ queue_counts['nominated'] }})</a></li>
|
{{ _('Full Reviews') }} ({{ queue_counts['nominated'] }})</a></li>
|
||||||
<li><a href="{{ url('editors.queue_pending') }}">
|
<li><a href="{{ url('editors.queue_pending') }}">
|
||||||
{{ _('Pending Updates') }} ({{ queue_counts['pending'] }})</a></li>
|
{{ _('Pending Updates') }} ({{ queue_counts['pending'] }})</a></li>
|
||||||
<li><a href="{{ url('editors.queue_prelim') }}">
|
|
||||||
{{ _('Preliminary Reviews') }} ({{ queue_counts['prelim'] }})</a></li>
|
|
||||||
<li><a href="{{ url('editors.queue_moderated') }}">
|
<li><a href="{{ url('editors.queue_moderated') }}">
|
||||||
{{ _('Moderated Reviews') }} ({{ queue_counts['moderated'] }})</a></li>
|
{{ _('Moderated Reviews') }} ({{ queue_counts['moderated'] }})</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -63,8 +61,6 @@
|
||||||
{{ _('Full Reviews') }} ({{ unlisted_queue_counts['nominated'] }})</a></li>
|
{{ _('Full Reviews') }} ({{ unlisted_queue_counts['nominated'] }})</a></li>
|
||||||
<li><a href="{{ url('editors.unlisted_queue_pending') }}">
|
<li><a href="{{ url('editors.unlisted_queue_pending') }}">
|
||||||
{{ _('Pending Updates') }} ({{ unlisted_queue_counts['pending'] }})</a></li>
|
{{ _('Pending Updates') }} ({{ unlisted_queue_counts['pending'] }})</a></li>
|
||||||
<li><a href="{{ url('editors.unlisted_queue_prelim') }}">
|
|
||||||
{{ _('Preliminary Reviews') }} ({{ unlisted_queue_counts['prelim'] }})</a></li>
|
|
||||||
<li><a href="{{ url('editors.unlisted_queue_all') }}">
|
<li><a href="{{ url('editors.unlisted_queue_all') }}">
|
||||||
{{ _('All Add-ons') }} ({{ unlisted_queue_counts['all'] }})</a></li>
|
{{ _('All Add-ons') }} ({{ unlisted_queue_counts['all'] }})</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
{% extends "editors/emails/base.ltxt" %}{% block content %}
|
|
||||||
Your add-on, {{ name }} {{ number }}, has been reviewed and did not meet the criteria for full review. However, it has been granted preliminary review and is now available for download in our gallery at {{ addon_url }}
|
|
||||||
{% include "editors/emails/files.ltxt" %}
|
|
||||||
|
|
||||||
Reviewer:
|
|
||||||
{{ reviewer }}
|
|
||||||
|
|
||||||
Comments:
|
|
||||||
{{ comments }}
|
|
||||||
|
|
||||||
{{ tested }}
|
|
||||||
|
|
||||||
Your add-on will now appear in search results and categories with some limitations. You may re-request full review by addressing the reviewer's comments and uploading a new version.
|
|
||||||
{% endblock %}
|
|
|
@ -1,12 +0,0 @@
|
||||||
{% extends "editors/emails/base.ltxt" %}{% block content %}
|
|
||||||
Your add-on, {{ name }} {{ number }}, has been preliminarily reviewed and is now available for download in our gallery at {{ addon_url }}
|
|
||||||
{% include "editors/emails/files.ltxt" %}
|
|
||||||
Reviewer:
|
|
||||||
{{ reviewer }}
|
|
||||||
|
|
||||||
Comments:
|
|
||||||
{{ comments }}
|
|
||||||
|
|
||||||
{{ tested }}
|
|
||||||
|
|
||||||
{% endblock %}
|
|
|
@ -1,13 +0,0 @@
|
||||||
{% extends "editors/emails/base.ltxt" %}{% block content %}
|
|
||||||
Your add-on, {{ name }}, {{ number }}, has been preliminarily reviewed and is now available for download in our gallery at {{ addon_url }}
|
|
||||||
{% include "editors/emails/files.ltxt" %}
|
|
||||||
Reviewer:
|
|
||||||
{{ reviewer }}
|
|
||||||
|
|
||||||
Comments:
|
|
||||||
{{ comments }}
|
|
||||||
|
|
||||||
{{ tested }}
|
|
||||||
|
|
||||||
Your add-on will now appear in search results and categories with some limitations. You may request full review to remove these limitations.
|
|
||||||
{% endblock %}
|
|
|
@ -1,13 +0,0 @@
|
||||||
{% extends "editors/emails/base.ltxt" %}{% block content %}
|
|
||||||
Your add-on, {{ name }} {{ number }}, has been reviewed and did not meet the criteria for being hosted in our gallery.
|
|
||||||
|
|
||||||
Reviewer:
|
|
||||||
{{ reviewer }}
|
|
||||||
|
|
||||||
Comments:
|
|
||||||
{{ comments }}
|
|
||||||
|
|
||||||
{{ tested }}
|
|
||||||
|
|
||||||
This version of your add-on has been disabled. You may re-request review by addressing the reviewer's comments and uploading a new version at {{ dev_versions_url }}
|
|
||||||
{% endblock %}
|
|
|
@ -20,17 +20,10 @@
|
||||||
queue_counts_total['pending'])|f(num=queue_counts_total['pending']) }}
|
queue_counts_total['pending'])|f(num=queue_counts_total['pending']) }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="editor-stats-title">
|
|
||||||
<a href="{{ url('editors.queue_prelim') }}">
|
|
||||||
{{ ngettext('Preliminary Review ({num})',
|
|
||||||
'Preliminary Reviews ({num})',
|
|
||||||
queue_counts_total['prelim'])|f(num=queue_counts_total['prelim']) }}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="editor-stats">
|
<div class="editor-stats">
|
||||||
{% for type in ('nominated', 'pending', 'prelim'): %}
|
{% for type in ('nominated', 'pending'): %}
|
||||||
<div class="editor-stats-table">
|
<div class="editor-stats-table">
|
||||||
<div class="editor-stats-dark">
|
<div class="editor-stats-dark">
|
||||||
<strong>{{ _('Current waiting times:') }}</strong>
|
<strong>{{ _('Current waiting times:') }}</strong>
|
||||||
|
@ -70,17 +63,10 @@
|
||||||
unlisted_queue_counts['pending'])|f(num=unlisted_queue_counts['pending']) }}
|
unlisted_queue_counts['pending'])|f(num=unlisted_queue_counts['pending']) }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="editor-stats-title">
|
|
||||||
<a href="{{ url('editors.unlisted_queue_prelim') }}">
|
|
||||||
{{ ngettext('Unlisted Preliminary Review ({num})',
|
|
||||||
'Unlisted Preliminary Reviews ({num})',
|
|
||||||
unlisted_queue_counts['prelim'])|f(num=unlisted_queue_counts['prelim']) }}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="editor-stats">
|
<div class="editor-stats">
|
||||||
{% for type in ('nominated', 'pending', 'prelim'): %}
|
{% for type in ('nominated', 'pending'): %}
|
||||||
<div class="editor-stats-table">
|
<div class="editor-stats-table">
|
||||||
<div class="editor-stats-dark">
|
<div class="editor-stats-dark">
|
||||||
<strong>{{ _('Current waiting times:') }}</strong>
|
<strong>{{ _('Current waiting times:') }}</strong>
|
||||||
|
@ -106,12 +92,12 @@
|
||||||
<div class="featured" id="editors-stats">
|
<div class="featured" id="editors-stats">
|
||||||
<div class="featured-inner">
|
<div class="featured-inner">
|
||||||
<div class="listing-header">
|
<div class="listing-header">
|
||||||
<div class="editor-stats-title"><span>{{ _('Total Reviews') }}</span></div>
|
<div class="editor-stats-title three-col"><span>{{ _('Total Reviews') }}</span></div>
|
||||||
<div class="editor-stats-title"><span>{{ _('Reviews This Month') }}</span></div>
|
<div class="editor-stats-title three-col"><span>{{ _('Reviews This Month') }}</span></div>
|
||||||
<div class="editor-stats-title"><span>{{ _('New Editors') }}</span></div>
|
<div class="editor-stats-title three-col"><span>{{ _('New Editors') }}</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="editor-stats">
|
<div class="editor-stats">
|
||||||
<div class="editor-stats-table">
|
<div class="editor-stats-table three-col">
|
||||||
<div>
|
<div>
|
||||||
<table>
|
<table>
|
||||||
{% for row in reviews_total: %}
|
{% for row in reviews_total: %}
|
||||||
|
@ -126,7 +112,7 @@
|
||||||
<div>{{ _("You're #{0} with {1} reviews")|f(reviews_total_position, reviews_total_count) }}</div>
|
<div>{{ _("You're #{0} with {1} reviews")|f(reviews_total_position, reviews_total_count) }}</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="editor-stats-table">
|
<div class="editor-stats-table three-col">
|
||||||
<div>
|
<div>
|
||||||
<table>
|
<table>
|
||||||
{% for row in reviews_monthly: %}
|
{% for row in reviews_monthly: %}
|
||||||
|
@ -141,7 +127,7 @@
|
||||||
<div>{{ _("You're #{0} with {1} reviews")|f(reviews_monthly_position, reviews_monthly_count) }}</div>
|
<div>{{ _("You're #{0} with {1} reviews")|f(reviews_monthly_position, reviews_monthly_count) }}</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="editor-stats-table">
|
<div class="editor-stats-table three-col">
|
||||||
<div>
|
<div>
|
||||||
<table>
|
<table>
|
||||||
{% for editors in new_editors %}
|
{% for editors in new_editors %}
|
||||||
|
|
|
@ -2,13 +2,11 @@ import mock
|
||||||
|
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
|
|
||||||
from waffle.testutils import override_flag
|
|
||||||
|
|
||||||
from olympia import amo
|
from olympia import amo
|
||||||
from olympia.amo.tests import TestCase
|
from olympia.amo.tests import TestCase
|
||||||
from olympia.addons.models import Addon
|
from olympia.addons.models import Addon
|
||||||
from olympia.editors.forms import ReviewForm
|
from olympia.editors.forms import ReviewForm
|
||||||
from olympia.editors.helpers import NOMINATED_STATUSES, ReviewHelper
|
from olympia.editors.helpers import ReviewHelper
|
||||||
from olympia.editors.models import CannedResponse
|
from olympia.editors.models import CannedResponse
|
||||||
from olympia.users.models import UserProfile
|
from olympia.users.models import UserProfile
|
||||||
|
|
||||||
|
@ -36,48 +34,17 @@ class TestReviewActions(TestCase):
|
||||||
version=self.version))
|
version=self.version))
|
||||||
return form.helper.get_actions(self.request, self.addon)
|
return form.helper.get_actions(self.request, self.addon)
|
||||||
|
|
||||||
def test_lite_nominated(self):
|
def test_nominated_addon(self):
|
||||||
status = self.set_statuses(addon_status=amo.STATUS_LITE_AND_NOMINATED,
|
|
||||||
file_status=amo.STATUS_UNREVIEWED)
|
|
||||||
assert force_text(status['prelim']['label']) == (
|
|
||||||
'Retain preliminary review')
|
|
||||||
|
|
||||||
def test_other_statuses(self):
|
|
||||||
for status in Addon.STATUS_CHOICES:
|
|
||||||
statuses = NOMINATED_STATUSES + (
|
|
||||||
amo.STATUS_NULL, amo.STATUS_DELETED)
|
|
||||||
if status in statuses:
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
label = self.set_statuses(
|
|
||||||
addon_status=status,
|
|
||||||
file_status=amo.STATUS_UNREVIEWED)['prelim']['label']
|
|
||||||
assert force_text(label) == 'Grant preliminary review'
|
|
||||||
|
|
||||||
def test_nominated_unlisted_addon_no_prelim(self):
|
|
||||||
self.addon.update(is_listed=False)
|
self.addon.update(is_listed=False)
|
||||||
actions = self.set_statuses(addon_status=amo.STATUS_NOMINATED,
|
actions = self.set_statuses(addon_status=amo.STATUS_NOMINATED,
|
||||||
file_status=amo.STATUS_UNREVIEWED)
|
file_status=amo.STATUS_UNREVIEWED)
|
||||||
assert 'prelim' not in actions
|
assert actions['public']['label'] == 'Approve'
|
||||||
assert actions['public']['label'] == 'Grant full review'
|
|
||||||
|
|
||||||
def test_reject(self):
|
def test_reject(self):
|
||||||
reject = self.set_statuses(
|
reject = self.set_statuses(
|
||||||
addon_status=amo.STATUS_UNREVIEWED,
|
addon_status=amo.STATUS_NOMINATED,
|
||||||
file_status=amo.STATUS_UNREVIEWED)['reject']['details']
|
file_status=amo.STATUS_UNREVIEWED)['reject']['details']
|
||||||
assert force_text(reject).startswith('This will reject the add-on')
|
assert force_text(reject).startswith('This will reject this version')
|
||||||
|
|
||||||
def test_reject_lite(self):
|
|
||||||
reject = self.set_statuses(
|
|
||||||
addon_status=amo.STATUS_LITE,
|
|
||||||
file_status=amo.STATUS_UNREVIEWED)['reject']['details']
|
|
||||||
assert force_text(reject).startswith('This will reject the files')
|
|
||||||
|
|
||||||
def test_not_public(self):
|
|
||||||
# If the file is pending preliminary review then there is no option to
|
|
||||||
# grant full review so the length of the actions is one shorter
|
|
||||||
assert len(self.set_statuses(addon_status=amo.STATUS_UNREVIEWED,
|
|
||||||
file_status=amo.STATUS_UNREVIEWED)) == 5
|
|
||||||
|
|
||||||
def test_addon_status_null(self):
|
def test_addon_status_null(self):
|
||||||
# If the add-on is null we only show info, comment and super review.
|
# If the add-on is null we only show info, comment and super review.
|
||||||
|
@ -96,8 +63,6 @@ class TestReviewActions(TestCase):
|
||||||
file_status=amo.STATUS_PUBLIC)) == 3
|
file_status=amo.STATUS_PUBLIC)) == 3
|
||||||
assert len(self.set_statuses(addon_status=amo.STATUS_PUBLIC,
|
assert len(self.set_statuses(addon_status=amo.STATUS_PUBLIC,
|
||||||
file_status=amo.STATUS_BETA)) == 3
|
file_status=amo.STATUS_BETA)) == 3
|
||||||
assert len(self.set_statuses(addon_status=amo.STATUS_LITE,
|
|
||||||
file_status=amo.STATUS_LITE)) == 3
|
|
||||||
assert len(self.set_statuses(addon_status=amo.STATUS_DISABLED,
|
assert len(self.set_statuses(addon_status=amo.STATUS_DISABLED,
|
||||||
file_status=amo.STATUS_DISABLED)) == 3
|
file_status=amo.STATUS_DISABLED)) == 3
|
||||||
|
|
||||||
|
@ -106,43 +71,12 @@ class TestReviewActions(TestCase):
|
||||||
self.addon.update(admin_review=True)
|
self.addon.update(admin_review=True)
|
||||||
# Test with an admin editor.
|
# Test with an admin editor.
|
||||||
action_allowed_mock.return_value = True
|
action_allowed_mock.return_value = True
|
||||||
status = self.set_statuses(addon_status=amo.STATUS_LITE_AND_NOMINATED,
|
status = self.set_statuses(addon_status=amo.STATUS_NOMINATED,
|
||||||
file_status=amo.STATUS_UNREVIEWED)
|
|
||||||
assert 'public' in status.keys()
|
|
||||||
assert 'prelim' in status.keys()
|
|
||||||
# Test with an non-admin editor.
|
|
||||||
action_allowed_mock.return_value = False
|
|
||||||
status = self.set_statuses(addon_status=amo.STATUS_LITE_AND_NOMINATED,
|
|
||||||
file_status=amo.STATUS_UNREVIEWED)
|
|
||||||
assert 'public' not in status.keys()
|
|
||||||
assert 'prelim' not in status.keys()
|
|
||||||
|
|
||||||
|
|
||||||
@override_flag('no-prelim-review', active=True)
|
|
||||||
class TestReviewActionsNoPrelim(TestReviewActions):
|
|
||||||
|
|
||||||
def test_lite_nominated(self):
|
|
||||||
""" Without prelim this shouldn't be an option."""
|
|
||||||
status = self.set_statuses(addon_status=amo.STATUS_LITE_AND_NOMINATED,
|
|
||||||
file_status=amo.STATUS_UNREVIEWED)
|
|
||||||
assert 'prelim' not in status
|
|
||||||
|
|
||||||
def test_nominated_addon_no_prelim(self):
|
|
||||||
actions = self.set_statuses(addon_status=amo.STATUS_NOMINATED,
|
|
||||||
file_status=amo.STATUS_UNREVIEWED)
|
|
||||||
assert 'prelim' not in actions
|
|
||||||
|
|
||||||
@mock.patch('olympia.access.acl.action_allowed')
|
|
||||||
def test_admin_flagged_addon_actions(self, action_allowed_mock):
|
|
||||||
self.addon.update(admin_review=True)
|
|
||||||
# Test with an admin editor.
|
|
||||||
action_allowed_mock.return_value = True
|
|
||||||
status = self.set_statuses(addon_status=amo.STATUS_LITE_AND_NOMINATED,
|
|
||||||
file_status=amo.STATUS_UNREVIEWED)
|
file_status=amo.STATUS_UNREVIEWED)
|
||||||
assert 'public' in status.keys()
|
assert 'public' in status.keys()
|
||||||
# Test with an non-admin editor.
|
# Test with an non-admin editor.
|
||||||
action_allowed_mock.return_value = False
|
action_allowed_mock.return_value = False
|
||||||
status = self.set_statuses(addon_status=amo.STATUS_LITE_AND_NOMINATED,
|
status = self.set_statuses(addon_status=amo.STATUS_NOMINATED,
|
||||||
file_status=amo.STATUS_UNREVIEWED)
|
file_status=amo.STATUS_UNREVIEWED)
|
||||||
assert 'public' not in status.keys()
|
assert 'public' not in status.keys()
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ from django.utils import translation
|
||||||
import pytest
|
import pytest
|
||||||
from mock import Mock, patch
|
from mock import Mock, patch
|
||||||
from pyquery import PyQuery as pq
|
from pyquery import PyQuery as pq
|
||||||
from waffle.testutils import override_flag, override_switch
|
from waffle.testutils import override_switch
|
||||||
|
|
||||||
from olympia import amo
|
from olympia import amo
|
||||||
from olympia.activity.models import ActivityLogToken
|
from olympia.activity.models import ActivityLogToken
|
||||||
|
@ -24,16 +24,11 @@ from olympia.translations.models import Translation
|
||||||
from olympia.users.models import UserProfile
|
from olympia.users.models import UserProfile
|
||||||
from olympia.versions.models import Version
|
from olympia.versions.models import Version
|
||||||
|
|
||||||
from . test_models import create_addon_file
|
|
||||||
|
|
||||||
|
|
||||||
pytestmark = pytest.mark.django_db
|
pytestmark = pytest.mark.django_db
|
||||||
|
|
||||||
|
|
||||||
REVIEW_ADDON_STATUSES = (amo.STATUS_NOMINATED, amo.STATUS_LITE_AND_NOMINATED,
|
REVIEW_FILES_STATUSES = (amo.STATUS_PUBLIC, amo.STATUS_DISABLED)
|
||||||
amo.STATUS_UNREVIEWED)
|
|
||||||
REVIEW_FILES_STATUSES = (amo.STATUS_PUBLIC,
|
|
||||||
amo.STATUS_DISABLED, amo.STATUS_LITE)
|
|
||||||
|
|
||||||
|
|
||||||
class TestViewPendingQueueTable(TestCase):
|
class TestViewPendingQueueTable(TestCase):
|
||||||
|
@ -256,7 +251,7 @@ class TestReviewHelper(TestCase):
|
||||||
|
|
||||||
def get_data(self):
|
def get_data(self):
|
||||||
return {'comments': 'foo', 'addon_files': self.version.files.all(),
|
return {'comments': 'foo', 'addon_files': self.version.files.all(),
|
||||||
'action': 'prelim', 'operating_systems': 'osx',
|
'action': 'public', 'operating_systems': 'osx',
|
||||||
'applications': 'Firefox'}
|
'applications': 'Firefox'}
|
||||||
|
|
||||||
def get_helper(self):
|
def get_helper(self):
|
||||||
|
@ -278,11 +273,6 @@ class TestReviewHelper(TestCase):
|
||||||
|
|
||||||
def test_type_nominated(self):
|
def test_type_nominated(self):
|
||||||
assert self.setup_type(amo.STATUS_NOMINATED) == 'nominated'
|
assert self.setup_type(amo.STATUS_NOMINATED) == 'nominated'
|
||||||
assert self.setup_type(amo.STATUS_LITE_AND_NOMINATED) == 'nominated'
|
|
||||||
|
|
||||||
def test_type_preliminary(self):
|
|
||||||
assert self.setup_type(amo.STATUS_UNREVIEWED) == 'preliminary'
|
|
||||||
assert self.setup_type(amo.STATUS_LITE) == 'preliminary'
|
|
||||||
|
|
||||||
def test_type_pending(self):
|
def test_type_pending(self):
|
||||||
assert self.setup_type(amo.STATUS_PENDING) == 'pending'
|
assert self.setup_type(amo.STATUS_PENDING) == 'pending'
|
||||||
|
@ -302,9 +292,8 @@ class TestReviewHelper(TestCase):
|
||||||
assert self.helper.handler.__class__ == helpers.ReviewFiles
|
assert self.helper.handler.__class__ == helpers.ReviewFiles
|
||||||
|
|
||||||
def test_review_addon(self):
|
def test_review_addon(self):
|
||||||
for status in REVIEW_ADDON_STATUSES:
|
self.setup_data(status=amo.STATUS_NOMINATED)
|
||||||
self.setup_data(status=status)
|
assert self.helper.handler.__class__ == helpers.ReviewAddon
|
||||||
assert self.helper.handler.__class__ == helpers.ReviewAddon
|
|
||||||
|
|
||||||
def test_process_action_none(self):
|
def test_process_action_none(self):
|
||||||
self.helper.set_data({'action': 'foo'})
|
self.helper.set_data({'action': 'foo'})
|
||||||
|
@ -338,57 +327,18 @@ class TestReviewHelper(TestCase):
|
||||||
for k, v in actions.items():
|
for k, v in actions.items():
|
||||||
assert unicode(v['details']), "Missing details for: %s" % k
|
assert unicode(v['details']), "Missing details for: %s" % k
|
||||||
|
|
||||||
def get_action_details(self, status, action):
|
|
||||||
self.file.update(status=amo.STATUS_UNREVIEWED)
|
|
||||||
self.addon.update(status=status)
|
|
||||||
return unicode(self.get_helper().actions[action]['details'])
|
|
||||||
|
|
||||||
def test_action_changes(self):
|
|
||||||
assert (self.get_action_details(amo.STATUS_LITE, 'reject')[:26] ==
|
|
||||||
'This will reject the files')
|
|
||||||
assert (self.get_action_details(amo.STATUS_UNREVIEWED,
|
|
||||||
'reject')[:27] == 'This will reject the add-on')
|
|
||||||
assert (self.get_action_details(amo.STATUS_UNREVIEWED,
|
|
||||||
'prelim')[:25] == 'This will mark the add-on')
|
|
||||||
assert (self.get_action_details(amo.STATUS_NOMINATED, 'prelim')[:25] ==
|
|
||||||
'This will mark the add-on')
|
|
||||||
assert (self.get_action_details(amo.STATUS_LITE, 'prelim')[:24] ==
|
|
||||||
'This will mark the files')
|
|
||||||
assert (self.get_action_details(amo.STATUS_LITE_AND_NOMINATED,
|
|
||||||
'prelim')[:27] == 'This will retain the add-on')
|
|
||||||
assert (self.get_action_details(amo.STATUS_NULL, 'info')[:41] ==
|
|
||||||
'Use this form to request more information')
|
|
||||||
assert (self.get_action_details(amo.STATUS_NOMINATED,
|
|
||||||
'public')[-31:] == 'they are reviewed by an editor.')
|
|
||||||
assert (self.get_action_details(amo.STATUS_PUBLIC, 'public')[-29:] ==
|
|
||||||
'to appear on the public site.')
|
|
||||||
|
|
||||||
def get_review_actions(self, addon_status, file_status):
|
def get_review_actions(self, addon_status, file_status):
|
||||||
self.file.update(status=file_status)
|
self.file.update(status=file_status)
|
||||||
self.addon.update(status=addon_status)
|
self.addon.update(status=addon_status)
|
||||||
return self.get_helper().actions
|
return self.get_helper().actions
|
||||||
|
|
||||||
def test_actions_full_nominated(self):
|
def test_actions_full_nominated(self):
|
||||||
expected = ['public', 'prelim', 'reject', 'info', 'super', 'comment']
|
|
||||||
assert self.get_review_actions(
|
|
||||||
addon_status=amo.STATUS_NOMINATED,
|
|
||||||
file_status=amo.STATUS_UNREVIEWED).keys() == expected
|
|
||||||
|
|
||||||
@override_flag('no-prelim-review', active=True)
|
|
||||||
def test_actions_full_nominated_no_prelim(self):
|
|
||||||
expected = ['public', 'reject', 'info', 'super', 'comment']
|
expected = ['public', 'reject', 'info', 'super', 'comment']
|
||||||
assert self.get_review_actions(
|
assert self.get_review_actions(
|
||||||
addon_status=amo.STATUS_NOMINATED,
|
addon_status=amo.STATUS_NOMINATED,
|
||||||
file_status=amo.STATUS_UNREVIEWED).keys() == expected
|
file_status=amo.STATUS_UNREVIEWED).keys() == expected
|
||||||
|
|
||||||
def test_actions_full_update(self):
|
def test_actions_full_update(self):
|
||||||
expected = ['public', 'prelim', 'reject', 'info', 'super', 'comment']
|
|
||||||
assert self.get_review_actions(
|
|
||||||
addon_status=amo.STATUS_PUBLIC,
|
|
||||||
file_status=amo.STATUS_UNREVIEWED).keys() == expected
|
|
||||||
|
|
||||||
@override_flag('no-prelim-review', active=True)
|
|
||||||
def test_actions_full_update_no_prelim(self):
|
|
||||||
expected = ['public', 'reject', 'info', 'super', 'comment']
|
expected = ['public', 'reject', 'info', 'super', 'comment']
|
||||||
assert self.get_review_actions(
|
assert self.get_review_actions(
|
||||||
addon_status=amo.STATUS_PUBLIC,
|
addon_status=amo.STATUS_PUBLIC,
|
||||||
|
@ -396,45 +346,12 @@ class TestReviewHelper(TestCase):
|
||||||
|
|
||||||
def test_actions_full_nonpending(self):
|
def test_actions_full_nonpending(self):
|
||||||
expected = ['info', 'super', 'comment']
|
expected = ['info', 'super', 'comment']
|
||||||
f_statuses = [amo.STATUS_PUBLIC, amo.STATUS_DISABLED, amo.STATUS_LITE]
|
f_statuses = [amo.STATUS_PUBLIC, amo.STATUS_DISABLED]
|
||||||
for file_status in f_statuses:
|
for file_status in f_statuses:
|
||||||
assert self.get_review_actions(
|
assert self.get_review_actions(
|
||||||
addon_status=amo.STATUS_PUBLIC,
|
addon_status=amo.STATUS_PUBLIC,
|
||||||
file_status=file_status).keys() == expected
|
file_status=file_status).keys() == expected
|
||||||
|
|
||||||
def test_actions_prelim_pending(self):
|
|
||||||
expected = ['prelim', 'reject', 'info', 'super', 'comment']
|
|
||||||
assert self.get_review_actions(
|
|
||||||
addon_status=amo.STATUS_UNREVIEWED,
|
|
||||||
file_status=amo.STATUS_UNREVIEWED).keys() == expected
|
|
||||||
|
|
||||||
def test_actions_prelim_update(self):
|
|
||||||
expected = ['prelim', 'reject', 'info', 'super', 'comment']
|
|
||||||
assert self.get_review_actions(
|
|
||||||
addon_status=amo.STATUS_LITE,
|
|
||||||
file_status=amo.STATUS_UNREVIEWED).keys() == expected
|
|
||||||
|
|
||||||
def test_actions_prelim_nonpending(self):
|
|
||||||
expected = ['info', 'super', 'comment']
|
|
||||||
f_statuses = [amo.STATUS_DISABLED, amo.STATUS_LITE]
|
|
||||||
for file_status in f_statuses:
|
|
||||||
assert self.get_review_actions(
|
|
||||||
addon_status=amo.STATUS_LITE,
|
|
||||||
file_status=file_status).keys() == expected
|
|
||||||
|
|
||||||
def test_actions_prelim_upgrade_to_full(self):
|
|
||||||
expected = ['public', 'prelim', 'reject', 'info', 'super', 'comment']
|
|
||||||
assert self.get_review_actions(
|
|
||||||
addon_status=amo.STATUS_LITE_AND_NOMINATED,
|
|
||||||
file_status=amo.STATUS_LITE).keys() == expected
|
|
||||||
|
|
||||||
@override_flag('no-prelim-review', active=True)
|
|
||||||
def test_actions_prelim_upgrade_to_full_no_prelim(self):
|
|
||||||
expected = ['public', 'reject', 'info', 'super', 'comment']
|
|
||||||
assert self.get_review_actions(
|
|
||||||
addon_status=amo.STATUS_LITE_AND_NOMINATED,
|
|
||||||
file_status=amo.STATUS_LITE).keys() == expected
|
|
||||||
|
|
||||||
def test_set_files(self):
|
def test_set_files(self):
|
||||||
self.file.update(datestatuschanged=yesterday)
|
self.file.update(datestatuschanged=yesterday)
|
||||||
self.helper.set_data({'addon_files': self.version.files.all()})
|
self.helper.set_data({'addon_files': self.version.files.all()})
|
||||||
|
@ -471,13 +388,11 @@ class TestReviewHelper(TestCase):
|
||||||
def test_notify_email(self):
|
def test_notify_email(self):
|
||||||
self.helper.set_data(self.get_data())
|
self.helper.set_data(self.get_data())
|
||||||
base_fragment = 'reply to this email or join #amo-editors'
|
base_fragment = 'reply to this email or join #amo-editors'
|
||||||
for template in ['nominated_to_nominated', 'nominated_to_preliminary',
|
for template in ('nominated_to_nominated',
|
||||||
'nominated_to_public', 'nominated_to_sandbox',
|
'nominated_to_public', 'nominated_to_sandbox',
|
||||||
'pending_to_preliminary', 'pending_to_public',
|
'pending_to_public', 'pending_to_sandbox',
|
||||||
'pending_to_sandbox', 'preliminary_to_preliminary',
|
|
||||||
'author_super_review', 'unlisted_to_reviewed',
|
'author_super_review', 'unlisted_to_reviewed',
|
||||||
'unlisted_to_reviewed_auto',
|
'unlisted_to_reviewed_auto', 'unlisted_to_sandbox'):
|
||||||
'unlisted_to_sandbox']:
|
|
||||||
mail.outbox = []
|
mail.outbox = []
|
||||||
self.helper.handler.notify_email(template, 'Sample subject %s, %s')
|
self.helper.handler.notify_email(template, 'Sample subject %s, %s')
|
||||||
assert len(mail.outbox) == 1
|
assert len(mail.outbox) == 1
|
||||||
|
@ -493,13 +408,11 @@ class TestReviewHelper(TestCase):
|
||||||
reply_email = (
|
reply_email = (
|
||||||
'reviewreply+%s@%s' % (uuid, settings.INBOUND_EMAIL_DOMAIN))
|
'reviewreply+%s@%s' % (uuid, settings.INBOUND_EMAIL_DOMAIN))
|
||||||
|
|
||||||
for template in ['nominated_to_nominated', 'nominated_to_preliminary',
|
for template in ('nominated_to_nominated', 'nominated_to_public',
|
||||||
'nominated_to_public', 'nominated_to_sandbox',
|
'nominated_to_sandbox', 'pending_to_public',
|
||||||
'pending_to_preliminary', 'pending_to_public',
|
'pending_to_sandbox', 'author_super_review',
|
||||||
'pending_to_sandbox', 'preliminary_to_preliminary',
|
'unlisted_to_reviewed', 'unlisted_to_reviewed_auto',
|
||||||
'author_super_review', 'unlisted_to_reviewed',
|
'unlisted_to_sandbox'):
|
||||||
'unlisted_to_reviewed_auto',
|
|
||||||
'unlisted_to_sandbox']:
|
|
||||||
mail.outbox = []
|
mail.outbox = []
|
||||||
self.helper.handler.notify_email(template, 'Sample subject %s, %s')
|
self.helper.handler.notify_email(template, 'Sample subject %s, %s')
|
||||||
assert len(mail.outbox) == 1
|
assert len(mail.outbox) == 1
|
||||||
|
@ -509,16 +422,12 @@ class TestReviewHelper(TestCase):
|
||||||
def test_email_links(self):
|
def test_email_links(self):
|
||||||
expected = {
|
expected = {
|
||||||
'nominated_to_nominated': 'addon_url',
|
'nominated_to_nominated': 'addon_url',
|
||||||
'nominated_to_preliminary': 'addon_url',
|
|
||||||
'nominated_to_public': 'addon_url',
|
'nominated_to_public': 'addon_url',
|
||||||
'nominated_to_sandbox': 'dev_versions_url',
|
'nominated_to_sandbox': 'dev_versions_url',
|
||||||
|
|
||||||
'pending_to_preliminary': 'addon_url',
|
|
||||||
'pending_to_public': 'addon_url',
|
'pending_to_public': 'addon_url',
|
||||||
'pending_to_sandbox': 'dev_versions_url',
|
'pending_to_sandbox': 'dev_versions_url',
|
||||||
|
|
||||||
'preliminary_to_preliminary': 'addon_url',
|
|
||||||
|
|
||||||
'unlisted_to_reviewed': 'dev_versions_url',
|
'unlisted_to_reviewed': 'dev_versions_url',
|
||||||
'unlisted_to_reviewed_auto': 'dev_versions_url',
|
'unlisted_to_reviewed_auto': 'dev_versions_url',
|
||||||
'unlisted_to_sandbox': 'dev_versions_url'
|
'unlisted_to_sandbox': 'dev_versions_url'
|
||||||
|
@ -539,7 +448,9 @@ class TestReviewHelper(TestCase):
|
||||||
mail.outbox = []
|
mail.outbox = []
|
||||||
ActivityLog.objects.for_addons(self.helper.addon).delete()
|
ActivityLog.objects.for_addons(self.helper.addon).delete()
|
||||||
self.addon.update(status=status, is_listed=is_listed)
|
self.addon.update(status=status, is_listed=is_listed)
|
||||||
self.file.update(status=status)
|
file_status = (amo.STATUS_UNREVIEWED if status == amo.STATUS_NOMINATED
|
||||||
|
else status)
|
||||||
|
self.file.update(status=file_status)
|
||||||
self.helper = self.get_helper()
|
self.helper = self.get_helper()
|
||||||
data = self.get_data().copy()
|
data = self.get_data().copy()
|
||||||
for key in delete:
|
for key in delete:
|
||||||
|
@ -595,23 +506,21 @@ class TestReviewHelper(TestCase):
|
||||||
assert 'Your add-on, Delicious Bookmarks ' in mail.outbox[0].body
|
assert 'Your add-on, Delicious Bookmarks ' in mail.outbox[0].body
|
||||||
|
|
||||||
def test_nomination_to_public_no_files(self):
|
def test_nomination_to_public_no_files(self):
|
||||||
for status in helpers.NOMINATED_STATUSES:
|
self.setup_data(amo.STATUS_NOMINATED, ['addon_files'])
|
||||||
self.setup_data(status, ['addon_files'])
|
self.helper.handler.process_public()
|
||||||
self.helper.handler.process_public()
|
|
||||||
|
|
||||||
assert self.addon.versions.all()[0].files.all()[0].status == (
|
assert self.addon.versions.all()[0].files.all()[0].status == (
|
||||||
amo.STATUS_PUBLIC)
|
amo.STATUS_PUBLIC)
|
||||||
|
|
||||||
def test_nomination_to_public_and_current_version(self):
|
def test_nomination_to_public_and_current_version(self):
|
||||||
for status in helpers.NOMINATED_STATUSES:
|
self.setup_data(amo.STATUS_NOMINATED, ['addon_files'])
|
||||||
self.setup_data(status, ['addon_files'])
|
self.addon = Addon.objects.get(pk=3615)
|
||||||
self.addon = Addon.objects.get(pk=3615)
|
self.addon.update(_current_version=None)
|
||||||
self.addon.update(_current_version=None)
|
assert not self.addon.current_version
|
||||||
assert not self.addon.current_version
|
|
||||||
|
|
||||||
self.helper.handler.process_public()
|
self.helper.handler.process_public()
|
||||||
self.addon = Addon.objects.get(pk=3615)
|
self.addon = Addon.objects.get(pk=3615)
|
||||||
assert self.addon.current_version
|
assert self.addon.current_version
|
||||||
|
|
||||||
def test_nomination_to_public_new_addon(self):
|
def test_nomination_to_public_new_addon(self):
|
||||||
""" Make sure new add-ons can be made public (bug 637959) """
|
""" Make sure new add-ons can be made public (bug 637959) """
|
||||||
|
@ -643,199 +552,107 @@ class TestReviewHelper(TestCase):
|
||||||
|
|
||||||
@patch('olympia.editors.helpers.sign_file')
|
@patch('olympia.editors.helpers.sign_file')
|
||||||
def test_nomination_to_public(self, sign_mock):
|
def test_nomination_to_public(self, sign_mock):
|
||||||
for status in helpers.NOMINATED_STATUSES:
|
sign_mock.reset()
|
||||||
sign_mock.reset()
|
self.setup_data(amo.STATUS_NOMINATED)
|
||||||
self.setup_data(status)
|
with self.settings(SIGNING_SERVER='full'):
|
||||||
with self.settings(SIGNING_SERVER='full'):
|
self.helper.handler.process_public()
|
||||||
self.helper.handler.process_public()
|
|
||||||
|
|
||||||
assert self.addon.status == amo.STATUS_PUBLIC
|
assert self.addon.status == amo.STATUS_PUBLIC
|
||||||
assert self.addon.versions.all()[0].files.all()[0].status == (
|
assert self.addon.versions.all()[0].files.all()[0].status == (
|
||||||
amo.STATUS_PUBLIC)
|
amo.STATUS_PUBLIC)
|
||||||
|
|
||||||
assert len(mail.outbox) == 1
|
assert len(mail.outbox) == 1
|
||||||
assert mail.outbox[0].subject == (
|
assert mail.outbox[0].subject == (
|
||||||
'%s Fully Reviewed' % self.preamble)
|
'%s Fully Reviewed' % self.preamble)
|
||||||
assert 'has been fully reviewed' in mail.outbox[0].body
|
assert 'has been fully reviewed' in mail.outbox[0].body
|
||||||
|
|
||||||
sign_mock.assert_called_with(self.file, 'full')
|
sign_mock.assert_called_with(self.file, 'full')
|
||||||
assert storage.exists(self.file.mirror_file_path)
|
assert storage.exists(self.file.mirror_file_path)
|
||||||
|
|
||||||
assert self.check_log_count(amo.LOG.APPROVE_VERSION.id) == 1
|
assert self.check_log_count(amo.LOG.APPROVE_VERSION.id) == 1
|
||||||
|
|
||||||
self._check_score(amo.REVIEWED_ADDON_FULL)
|
self._check_score(amo.REVIEWED_ADDON_FULL)
|
||||||
|
|
||||||
@patch('olympia.editors.helpers.sign_file')
|
@patch('olympia.editors.helpers.sign_file')
|
||||||
def test_nomination_to_public_unlisted(self, sign_mock):
|
def test_nomination_to_public_unlisted(self, sign_mock):
|
||||||
for status in helpers.NOMINATED_STATUSES:
|
sign_mock.reset()
|
||||||
sign_mock.reset()
|
self.setup_data(amo.STATUS_NOMINATED, is_listed=False)
|
||||||
self.setup_data(status, is_listed=False)
|
with self.settings(SIGNING_SERVER='full'):
|
||||||
with self.settings(SIGNING_SERVER='full'):
|
self.helper.handler.process_public()
|
||||||
self.helper.handler.process_public()
|
|
||||||
|
|
||||||
assert self.addon.status == amo.STATUS_PUBLIC
|
assert self.addon.status == amo.STATUS_PUBLIC
|
||||||
assert self.addon.versions.all()[0].files.all()[0].status == (
|
assert self.addon.versions.all()[0].files.all()[0].status == (
|
||||||
amo.STATUS_PUBLIC)
|
amo.STATUS_PUBLIC)
|
||||||
|
|
||||||
assert len(mail.outbox) == 1
|
assert len(mail.outbox) == 1
|
||||||
assert mail.outbox[0].subject == (
|
assert mail.outbox[0].subject == (
|
||||||
'%s signed and ready to download' % self.preamble)
|
'%s signed and ready to download' % self.preamble)
|
||||||
assert 'has been reviewed and is now signed' in mail.outbox[0].body
|
assert 'has been reviewed and is now signed' in mail.outbox[0].body
|
||||||
|
|
||||||
sign_mock.assert_called_with(self.file, 'full')
|
sign_mock.assert_called_with(self.file, 'full')
|
||||||
assert storage.exists(self.file.mirror_file_path)
|
assert storage.exists(self.file.mirror_file_path)
|
||||||
|
|
||||||
assert self.check_log_count(amo.LOG.APPROVE_VERSION.id) == 1
|
assert self.check_log_count(amo.LOG.APPROVE_VERSION.id) == 1
|
||||||
|
|
||||||
self._check_score(amo.REVIEWED_ADDON_FULL)
|
self._check_score(amo.REVIEWED_ADDON_FULL)
|
||||||
|
|
||||||
@patch('olympia.editors.helpers.sign_file')
|
@patch('olympia.editors.helpers.sign_file')
|
||||||
def test_nomination_to_public_failed_signing(self, sign_mock):
|
def test_nomination_to_public_failed_signing(self, sign_mock):
|
||||||
sign_mock.side_effect = Exception
|
sign_mock.side_effect = Exception
|
||||||
for status in helpers.NOMINATED_STATUSES:
|
sign_mock.reset()
|
||||||
sign_mock.reset()
|
self.setup_data(amo.STATUS_NOMINATED)
|
||||||
self.setup_data(status)
|
with self.settings(SIGNING_SERVER='full'):
|
||||||
with self.settings(SIGNING_SERVER='full'):
|
|
||||||
with self.assertRaises(Exception):
|
|
||||||
self.helper.handler.process_public()
|
|
||||||
|
|
||||||
# Status unchanged.
|
|
||||||
assert self.addon.status == status
|
|
||||||
assert self.addon.versions.all()[0].files.all()[0].status == status
|
|
||||||
|
|
||||||
assert len(mail.outbox) == 0
|
|
||||||
assert self.check_log_count(amo.LOG.APPROVE_VERSION.id) == 0
|
|
||||||
|
|
||||||
@patch('olympia.editors.helpers.sign_file')
|
|
||||||
def test_nomination_to_preliminary(self, sign_mock):
|
|
||||||
for status in helpers.NOMINATED_STATUSES:
|
|
||||||
sign_mock.reset()
|
|
||||||
self.setup_data(status)
|
|
||||||
with self.settings(PRELIMINARY_SIGNING_SERVER='prelim'):
|
|
||||||
self.helper.handler.process_preliminary()
|
|
||||||
|
|
||||||
assert self.addon.status == amo.STATUS_LITE
|
|
||||||
assert self.addon.versions.all()[0].files.all()[0].status == (
|
|
||||||
amo.STATUS_LITE)
|
|
||||||
|
|
||||||
assert len(mail.outbox) == 1
|
|
||||||
assert mail.outbox[0].subject == (
|
|
||||||
'%s Preliminary Reviewed' % self.preamble)
|
|
||||||
assert 'has been granted preliminary review' in mail.outbox[0].body
|
|
||||||
|
|
||||||
sign_mock.assert_called_with(self.file, 'prelim')
|
|
||||||
assert storage.exists(self.file.mirror_file_path)
|
|
||||||
|
|
||||||
assert self.check_log_count(amo.LOG.PRELIMINARY_VERSION.id) == 1
|
|
||||||
|
|
||||||
self._check_score(amo.REVIEWED_ADDON_FULL)
|
|
||||||
|
|
||||||
@patch('olympia.editors.helpers.sign_file')
|
|
||||||
def test_nomination_to_preliminary_unlisted(self, sign_mock):
|
|
||||||
for status in helpers.NOMINATED_STATUSES:
|
|
||||||
sign_mock.reset()
|
|
||||||
self.setup_data(status, is_listed=False)
|
|
||||||
with self.settings(PRELIMINARY_SIGNING_SERVER='prelim'):
|
|
||||||
self.helper.handler.process_preliminary()
|
|
||||||
|
|
||||||
assert self.addon.status == amo.STATUS_LITE
|
|
||||||
assert self.addon.versions.all()[0].files.all()[0].status == (
|
|
||||||
amo.STATUS_LITE)
|
|
||||||
|
|
||||||
assert len(mail.outbox) == 1
|
|
||||||
assert mail.outbox[0].subject == (
|
|
||||||
'%s signed and ready to download' % self.preamble)
|
|
||||||
assert 'has been reviewed and is now signed' in mail.outbox[0].body
|
|
||||||
|
|
||||||
sign_mock.assert_called_with(self.file, 'prelim')
|
|
||||||
assert storage.exists(self.file.mirror_file_path)
|
|
||||||
|
|
||||||
assert self.check_log_count(amo.LOG.PRELIMINARY_VERSION.id) == 1
|
|
||||||
|
|
||||||
self._check_score(amo.REVIEWED_ADDON_FULL)
|
|
||||||
|
|
||||||
@patch('olympia.editors.helpers.sign_file')
|
|
||||||
def test_nomination_to_preliminary_unlisted_auto(self, sign_mock):
|
|
||||||
for status in helpers.NOMINATED_STATUSES:
|
|
||||||
sign_mock.reset()
|
|
||||||
self.setup_data(status, is_listed=False)
|
|
||||||
with self.settings(PRELIMINARY_SIGNING_SERVER='prelim'):
|
|
||||||
self.helper.handler.process_preliminary(auto_validation=True)
|
|
||||||
|
|
||||||
assert self.addon.status == amo.STATUS_LITE
|
|
||||||
assert self.addon.versions.all()[0].files.all()[0].status == (
|
|
||||||
amo.STATUS_LITE)
|
|
||||||
|
|
||||||
assert len(mail.outbox) == 1
|
|
||||||
assert mail.outbox[0].subject == (
|
|
||||||
'%s signed and ready to download' % self.preamble)
|
|
||||||
assert 'has passed our automatic tests' in mail.outbox[0].body
|
|
||||||
|
|
||||||
sign_mock.assert_called_with(self.file, 'prelim')
|
|
||||||
assert storage.exists(self.file.mirror_file_path)
|
|
||||||
|
|
||||||
assert self.check_log_count(amo.LOG.PRELIMINARY_VERSION.id) == 1
|
|
||||||
|
|
||||||
assert not ReviewerScore.objects.all()
|
|
||||||
|
|
||||||
@patch('olympia.editors.helpers.sign_file')
|
|
||||||
def test_nomination_to_preliminary_failed_signing(self, sign_mock):
|
|
||||||
sign_mock.side_effect = Exception
|
|
||||||
for status in helpers.NOMINATED_STATUSES:
|
|
||||||
sign_mock.reset()
|
|
||||||
self.setup_data(status)
|
|
||||||
with self.assertRaises(Exception):
|
with self.assertRaises(Exception):
|
||||||
self.helper.handler.process_preliminary()
|
self.helper.handler.process_public()
|
||||||
|
|
||||||
# Status unchanged.
|
# Status unchanged.
|
||||||
assert self.addon.status == status
|
assert self.addon.status == amo.STATUS_NOMINATED
|
||||||
assert self.addon.versions.all()[0].files.all()[0].status == status
|
assert self.addon.versions.all()[0].files.all()[0].status == (
|
||||||
|
amo.STATUS_UNREVIEWED)
|
||||||
|
|
||||||
assert len(mail.outbox) == 0
|
assert len(mail.outbox) == 0
|
||||||
assert self.check_log_count(amo.LOG.APPROVE_VERSION.id) == 0
|
assert self.check_log_count(amo.LOG.APPROVE_VERSION.id) == 0
|
||||||
|
|
||||||
@patch('olympia.editors.helpers.sign_file')
|
@patch('olympia.editors.helpers.sign_file')
|
||||||
def test_nomination_to_sandbox(self, sign_mock):
|
def test_nomination_to_sandbox(self, sign_mock):
|
||||||
for status in helpers.NOMINATED_STATUSES:
|
self.setup_data(amo.STATUS_NOMINATED)
|
||||||
self.setup_data(status)
|
self.helper.handler.process_sandbox()
|
||||||
self.helper.handler.process_sandbox()
|
|
||||||
|
|
||||||
assert self.addon.status == amo.STATUS_NULL
|
assert self.addon.status == amo.STATUS_NULL
|
||||||
assert self.addon.versions.all()[0].files.all()[0].status == (
|
assert self.addon.versions.all()[0].files.all()[0].status == (
|
||||||
amo.STATUS_DISABLED)
|
amo.STATUS_DISABLED)
|
||||||
|
|
||||||
assert len(mail.outbox) == 1
|
assert len(mail.outbox) == 1
|
||||||
assert mail.outbox[0].subject == (
|
assert mail.outbox[0].subject == (
|
||||||
'%s didn\'t pass review' % self.preamble)
|
'%s didn\'t pass review' % self.preamble)
|
||||||
assert 'did not meet the criteria' in mail.outbox[0].body
|
assert 'did not meet the criteria' in mail.outbox[0].body
|
||||||
|
|
||||||
assert not sign_mock.called
|
assert not sign_mock.called
|
||||||
assert not storage.exists(self.file.mirror_file_path)
|
assert not storage.exists(self.file.mirror_file_path)
|
||||||
assert self.check_log_count(amo.LOG.REJECT_VERSION.id) == 1
|
assert self.check_log_count(amo.LOG.REJECT_VERSION.id) == 1
|
||||||
|
|
||||||
@patch('olympia.editors.helpers.sign_file')
|
@patch('olympia.editors.helpers.sign_file')
|
||||||
def test_nomination_to_sandbox_unlisted(self, sign_mock):
|
def test_nomination_to_sandbox_unlisted(self, sign_mock):
|
||||||
for status in helpers.NOMINATED_STATUSES:
|
self.setup_data(amo.STATUS_NOMINATED, is_listed=False)
|
||||||
self.setup_data(status, is_listed=False)
|
self.helper.handler.process_sandbox()
|
||||||
self.helper.handler.process_sandbox()
|
|
||||||
|
|
||||||
assert self.addon.status == amo.STATUS_NULL
|
assert self.addon.status == amo.STATUS_NULL
|
||||||
assert self.addon.versions.all()[0].files.all()[0].status == (
|
assert self.addon.versions.all()[0].files.all()[0].status == (
|
||||||
amo.STATUS_DISABLED)
|
amo.STATUS_DISABLED)
|
||||||
|
|
||||||
assert len(mail.outbox) == 1
|
assert len(mail.outbox) == 1
|
||||||
assert mail.outbox[0].subject == (
|
assert mail.outbox[0].subject == (
|
||||||
'%s didn\'t pass review' % self.preamble)
|
'%s didn\'t pass review' % self.preamble)
|
||||||
assert 'didn\'t pass review' in mail.outbox[0].body
|
assert 'didn\'t pass review' in mail.outbox[0].body
|
||||||
|
|
||||||
assert not sign_mock.called
|
assert not sign_mock.called
|
||||||
assert not storage.exists(self.file.mirror_file_path)
|
assert not storage.exists(self.file.mirror_file_path)
|
||||||
assert self.check_log_count(amo.LOG.REJECT_VERSION.id) == 1
|
assert self.check_log_count(amo.LOG.REJECT_VERSION.id) == 1
|
||||||
|
|
||||||
def test_email_unicode_monster(self):
|
def test_email_unicode_monster(self):
|
||||||
self.addon.name = u'TaobaoShopping淘宝网导航按钮'
|
self.addon.name = u'TaobaoShopping淘宝网导航按钮'
|
||||||
self.addon.save()
|
self.addon.save()
|
||||||
self.setup_data(helpers.NOMINATED_STATUSES[0])
|
self.setup_data(amo.STATUS_NOMINATED)
|
||||||
self.helper.handler.process_sandbox()
|
self.helper.handler.process_sandbox()
|
||||||
assert u'TaobaoShopping淘宝网导航按钮' in mail.outbox[0].subject
|
assert u'TaobaoShopping淘宝网导航按钮' in mail.outbox[0].subject
|
||||||
|
|
||||||
|
@ -846,221 +663,70 @@ class TestReviewHelper(TestCase):
|
||||||
assert url in mail.outbox[1].body
|
assert url in mail.outbox[1].body
|
||||||
|
|
||||||
def test_nomination_to_super_review(self):
|
def test_nomination_to_super_review(self):
|
||||||
for status in helpers.NOMINATED_STATUSES:
|
self.setup_data(amo.STATUS_NOMINATED)
|
||||||
self.setup_data(status)
|
self.helper.handler.process_super_review()
|
||||||
self.helper.handler.process_super_review()
|
|
||||||
|
|
||||||
assert self.addon.admin_review
|
assert self.addon.admin_review
|
||||||
|
|
||||||
assert len(mail.outbox) == 2
|
assert len(mail.outbox) == 2
|
||||||
assert mail.outbox[1].subject == (
|
assert mail.outbox[1].subject == (
|
||||||
'Super review requested: Delicious Bookmarks')
|
'Super review requested: Delicious Bookmarks')
|
||||||
assert mail.outbox[0].subject == (
|
assert mail.outbox[0].subject == (
|
||||||
('Mozilla Add-ons: Delicious Bookmarks 2.1.072 flagged for '
|
('Mozilla Add-ons: Delicious Bookmarks 2.1.072 flagged for '
|
||||||
'Admin Review'))
|
'Admin Review'))
|
||||||
assert self.check_log_count(amo.LOG.REQUEST_SUPER_REVIEW.id) == 1
|
assert self.check_log_count(amo.LOG.REQUEST_SUPER_REVIEW.id) == 1
|
||||||
|
|
||||||
def test_unreviewed_to_public(self):
|
|
||||||
self.setup_data(amo.STATUS_UNREVIEWED)
|
|
||||||
self.assertRaises(AssertionError,
|
|
||||||
self.helper.handler.process_public)
|
|
||||||
|
|
||||||
def test_lite_to_public(self):
|
|
||||||
self.setup_data(amo.STATUS_LITE)
|
|
||||||
self.assertRaises(AssertionError,
|
|
||||||
self.helper.handler.process_public)
|
|
||||||
|
|
||||||
@patch('olympia.editors.helpers.sign_file')
|
|
||||||
def test_preliminary_to_preliminary(self, sign_mock):
|
|
||||||
for status in helpers.PRELIMINARY_STATUSES:
|
|
||||||
self.setup_data(status)
|
|
||||||
self.helper.handler.process_preliminary()
|
|
||||||
|
|
||||||
for file in self.helper.handler.data['addon_files']:
|
|
||||||
assert file.status == amo.STATUS_LITE
|
|
||||||
|
|
||||||
assert len(mail.outbox) == 1
|
|
||||||
assert mail.outbox[0].subject == (
|
|
||||||
'%s Preliminary Reviewed' % self.preamble)
|
|
||||||
assert 'has been preliminarily reviewed' in mail.outbox[0].body
|
|
||||||
|
|
||||||
assert sign_mock.called
|
|
||||||
assert storage.exists(self.file.mirror_file_path)
|
|
||||||
assert self.check_log_count(amo.LOG.PRELIMINARY_VERSION.id) == 1
|
|
||||||
|
|
||||||
self._check_score(amo.REVIEWED_ADDON_PRELIM)
|
|
||||||
|
|
||||||
@patch('olympia.editors.helpers.sign_file')
|
|
||||||
def test_preliminary_to_preliminary_unlisted(self, sign_mock):
|
|
||||||
for status in helpers.PRELIMINARY_STATUSES:
|
|
||||||
self.setup_data(status, is_listed=False)
|
|
||||||
self.helper.handler.process_preliminary()
|
|
||||||
|
|
||||||
for file in self.helper.handler.data['addon_files']:
|
|
||||||
assert file.status == amo.STATUS_LITE
|
|
||||||
|
|
||||||
assert len(mail.outbox) == 1
|
|
||||||
assert mail.outbox[0].subject == (
|
|
||||||
'%s signed and ready to download' % self.preamble)
|
|
||||||
assert 'has been reviewed and is now signed' in mail.outbox[0].body
|
|
||||||
|
|
||||||
assert sign_mock.called
|
|
||||||
assert storage.exists(self.file.mirror_file_path)
|
|
||||||
assert self.check_log_count(amo.LOG.PRELIMINARY_VERSION.id) == 1
|
|
||||||
|
|
||||||
self._check_score(amo.REVIEWED_ADDON_PRELIM)
|
|
||||||
|
|
||||||
@patch('olympia.editors.helpers.sign_file')
|
|
||||||
def test_preliminary_to_preliminary_unlisted_auto(self, sign_mock):
|
|
||||||
for status in helpers.PRELIMINARY_STATUSES:
|
|
||||||
self.setup_data(status, is_listed=False)
|
|
||||||
self.helper.handler.process_preliminary(auto_validation=True)
|
|
||||||
|
|
||||||
for file in self.helper.handler.data['addon_files']:
|
|
||||||
assert file.status == amo.STATUS_LITE
|
|
||||||
|
|
||||||
assert len(mail.outbox) == 1
|
|
||||||
assert mail.outbox[0].subject == (
|
|
||||||
'%s signed and ready to download' % self.preamble)
|
|
||||||
assert 'has passed our automatic tests' in mail.outbox[0].body
|
|
||||||
|
|
||||||
assert sign_mock.called
|
|
||||||
assert storage.exists(self.file.mirror_file_path)
|
|
||||||
assert self.check_log_count(amo.LOG.PRELIMINARY_VERSION.id) == 1
|
|
||||||
|
|
||||||
assert not ReviewerScore.objects.all()
|
|
||||||
|
|
||||||
@patch('olympia.editors.helpers.sign_file')
|
|
||||||
def test_preliminary_to_sandbox(self, sign_mock):
|
|
||||||
for status in [amo.STATUS_UNREVIEWED, amo.STATUS_LITE_AND_NOMINATED]:
|
|
||||||
self.setup_data(status)
|
|
||||||
self.helper.handler.process_sandbox()
|
|
||||||
|
|
||||||
for file in self.helper.handler.data['addon_files']:
|
|
||||||
assert file.status == amo.STATUS_DISABLED
|
|
||||||
|
|
||||||
assert len(mail.outbox) == 1
|
|
||||||
assert mail.outbox[0].subject == (
|
|
||||||
'%s didn\'t pass review' % self.preamble)
|
|
||||||
assert 'did not meet the criteria' in mail.outbox[0].body
|
|
||||||
|
|
||||||
assert not sign_mock.called
|
|
||||||
assert not storage.exists(self.file.mirror_file_path)
|
|
||||||
assert self.check_log_count(amo.LOG.REJECT_VERSION.id) == 1
|
|
||||||
|
|
||||||
@patch('olympia.editors.helpers.sign_file')
|
|
||||||
def test_preliminary_to_sandbox_unlisted(self, sign_mock):
|
|
||||||
for status in [amo.STATUS_UNREVIEWED, amo.STATUS_LITE_AND_NOMINATED]:
|
|
||||||
self.setup_data(status, is_listed=False)
|
|
||||||
self.helper.handler.process_sandbox()
|
|
||||||
|
|
||||||
for file in self.helper.handler.data['addon_files']:
|
|
||||||
assert file.status == amo.STATUS_DISABLED
|
|
||||||
|
|
||||||
assert len(mail.outbox) == 1
|
|
||||||
assert mail.outbox[0].subject == (
|
|
||||||
'%s didn\'t pass review' % self.preamble)
|
|
||||||
assert 'didn\'t pass review' in mail.outbox[0].body
|
|
||||||
|
|
||||||
assert not sign_mock.called
|
|
||||||
assert not storage.exists(self.file.mirror_file_path)
|
|
||||||
assert self.check_log_count(amo.LOG.REJECT_VERSION.id) == 1
|
|
||||||
|
|
||||||
def test_preliminary_upgrade_to_sandbox(self):
|
|
||||||
self.setup_data(amo.STATUS_LITE)
|
|
||||||
assert self.addon.status == amo.STATUS_LITE
|
|
||||||
assert self.file.status == amo.STATUS_LITE
|
|
||||||
|
|
||||||
a = create_addon_file(self.addon.name, '2.2', amo.STATUS_LITE,
|
|
||||||
amo.STATUS_UNREVIEWED)
|
|
||||||
self.version = a['version']
|
|
||||||
|
|
||||||
self.addon.update(status=amo.STATUS_LITE_AND_NOMINATED)
|
|
||||||
self.helper = self.get_helper()
|
|
||||||
self.helper.set_data(self.get_data())
|
|
||||||
|
|
||||||
self.helper.handler.process_sandbox()
|
|
||||||
assert self.addon.status == amo.STATUS_LITE
|
|
||||||
assert self.file.status == amo.STATUS_LITE
|
|
||||||
f = File.objects.get(pk=a['file'].id)
|
|
||||||
assert f.status == amo.STATUS_DISABLED
|
|
||||||
|
|
||||||
def test_preliminary_to_super_review(self):
|
|
||||||
for status in helpers.PRELIMINARY_STATUSES:
|
|
||||||
self.setup_data(status)
|
|
||||||
self.helper.handler.process_super_review()
|
|
||||||
|
|
||||||
assert self.addon.admin_review
|
|
||||||
|
|
||||||
assert len(mail.outbox) == 2
|
|
||||||
assert mail.outbox[1].subject == (
|
|
||||||
'Super review requested: Delicious Bookmarks')
|
|
||||||
assert mail.outbox[0].subject == (
|
|
||||||
('Mozilla Add-ons: Delicious Bookmarks 2.1.072 flagged for '
|
|
||||||
'Admin Review'))
|
|
||||||
assert self.check_log_count(amo.LOG.REQUEST_SUPER_REVIEW.id) == 1
|
|
||||||
|
|
||||||
def test_nomination_to_super_review_and_escalate(self):
|
def test_nomination_to_super_review_and_escalate(self):
|
||||||
# Note we are changing the file status here.
|
self.setup_data(amo.STATUS_NOMINATED)
|
||||||
for file_status in (amo.STATUS_PENDING, amo.STATUS_UNREVIEWED):
|
self.file.update(status=amo.STATUS_UNREVIEWED)
|
||||||
self.setup_data(amo.STATUS_LITE)
|
self.helper.handler.process_super_review()
|
||||||
self.file.update(status=file_status)
|
|
||||||
self.helper.handler.process_super_review()
|
|
||||||
|
|
||||||
assert self.addon.admin_review
|
assert self.addon.admin_review
|
||||||
|
|
||||||
assert len(mail.outbox) == 2
|
assert len(mail.outbox) == 2
|
||||||
assert mail.outbox[1].subject == (
|
assert mail.outbox[1].subject == (
|
||||||
'Super review requested: Delicious Bookmarks')
|
'Super review requested: Delicious Bookmarks')
|
||||||
assert mail.outbox[0].subject == (
|
assert mail.outbox[0].subject == (
|
||||||
('Mozilla Add-ons: Delicious Bookmarks 2.1.072 flagged for '
|
('Mozilla Add-ons: Delicious Bookmarks 2.1.072 flagged for '
|
||||||
'Admin Review'))
|
'Admin Review'))
|
||||||
|
|
||||||
assert self.check_log_count(amo.LOG.REQUEST_SUPER_REVIEW.id) == 1
|
assert self.check_log_count(amo.LOG.REQUEST_SUPER_REVIEW.id) == 1
|
||||||
|
|
||||||
@patch('olympia.editors.helpers.sign_file')
|
@patch('olympia.editors.helpers.sign_file')
|
||||||
def test_pending_to_public(self, sign_mock):
|
def test_pending_to_public(self, sign_mock):
|
||||||
for status in [amo.STATUS_NOMINATED, amo.STATUS_LITE_AND_NOMINATED]:
|
self.setup_data(amo.STATUS_NOMINATED)
|
||||||
self.setup_data(status)
|
self.create_paths()
|
||||||
self.create_paths()
|
self.helper.handler.process_public()
|
||||||
self.helper.handler.process_public()
|
|
||||||
|
|
||||||
for file in self.helper.handler.data['addon_files']:
|
for file in self.helper.handler.data['addon_files']:
|
||||||
assert file.status == amo.STATUS_PUBLIC
|
assert file.status == amo.STATUS_PUBLIC
|
||||||
|
|
||||||
assert len(mail.outbox) == 1
|
assert len(mail.outbox) == 1
|
||||||
assert mail.outbox[0].subject == (
|
assert mail.outbox[0].subject == (
|
||||||
'%s Fully Reviewed' % self.preamble)
|
'%s Fully Reviewed' % self.preamble)
|
||||||
assert 'has been fully reviewed' in mail.outbox[0].body
|
assert 'has been fully reviewed' in mail.outbox[0].body
|
||||||
|
|
||||||
assert sign_mock.called
|
assert sign_mock.called
|
||||||
assert storage.exists(self.file.mirror_file_path)
|
assert storage.exists(self.file.mirror_file_path)
|
||||||
assert self.check_log_count(amo.LOG.APPROVE_VERSION.id) == 1
|
assert self.check_log_count(amo.LOG.APPROVE_VERSION.id) == 1
|
||||||
|
|
||||||
if status == amo.STATUS_PUBLIC:
|
|
||||||
self._check_score(amo.REVIEWED_ADDON_UPDATE)
|
|
||||||
|
|
||||||
@patch('olympia.editors.helpers.sign_file')
|
@patch('olympia.editors.helpers.sign_file')
|
||||||
def test_pending_to_public_unlisted(self, sign_mock):
|
def test_pending_to_public_unlisted(self, sign_mock):
|
||||||
for status in [amo.STATUS_NOMINATED, amo.STATUS_LITE_AND_NOMINATED]:
|
self.setup_data(amo.STATUS_NOMINATED, is_listed=False)
|
||||||
self.setup_data(status, is_listed=False)
|
self.create_paths()
|
||||||
self.create_paths()
|
self.helper.handler.process_public()
|
||||||
self.helper.handler.process_public()
|
|
||||||
|
|
||||||
for file in self.helper.handler.data['addon_files']:
|
for file in self.helper.handler.data['addon_files']:
|
||||||
assert file.status == amo.STATUS_PUBLIC
|
assert file.status == amo.STATUS_PUBLIC
|
||||||
|
|
||||||
assert len(mail.outbox) == 1
|
assert len(mail.outbox) == 1
|
||||||
assert mail.outbox[0].subject == (
|
assert mail.outbox[0].subject == (
|
||||||
'%s signed and ready to download' % self.preamble)
|
'%s signed and ready to download' % self.preamble)
|
||||||
assert 'has been reviewed and is now signed' in mail.outbox[0].body
|
assert 'has been reviewed and is now signed' in mail.outbox[0].body
|
||||||
|
|
||||||
assert sign_mock.called
|
assert sign_mock.called
|
||||||
assert storage.exists(self.file.mirror_file_path)
|
assert storage.exists(self.file.mirror_file_path)
|
||||||
assert self.check_log_count(amo.LOG.APPROVE_VERSION.id) == 1
|
assert self.check_log_count(amo.LOG.APPROVE_VERSION.id) == 1
|
||||||
|
|
||||||
if status == amo.STATUS_PUBLIC:
|
|
||||||
self._check_score(amo.REVIEWED_ADDON_UPDATE)
|
|
||||||
|
|
||||||
@patch('olympia.editors.helpers.sign_file')
|
@patch('olympia.editors.helpers.sign_file')
|
||||||
def test_pending_to_sandbox(self, sign_mock):
|
def test_pending_to_sandbox(self, sign_mock):
|
||||||
|
@ -1146,27 +812,19 @@ class TestReviewHelper(TestCase):
|
||||||
('Mozilla Add-ons: Delicious Bookmarks 2.1.072 flagged for '
|
('Mozilla Add-ons: Delicious Bookmarks 2.1.072 flagged for '
|
||||||
'Admin Review'))
|
'Admin Review'))
|
||||||
|
|
||||||
def test_nominated_review_time_set(self):
|
def test_nominated_review_time_set_version(self):
|
||||||
for status in REVIEW_ADDON_STATUSES:
|
for process in ('process_sandbox', 'process_public'):
|
||||||
for process in ['process_sandbox', 'process_preliminary',
|
self.version.update(reviewed=None)
|
||||||
'process_public']:
|
self.setup_data(amo.STATUS_NOMINATED)
|
||||||
if (status == amo.STATUS_UNREVIEWED and
|
getattr(self.helper.handler, process)()
|
||||||
process == 'process_public'):
|
assert self.version.reviewed
|
||||||
continue
|
|
||||||
self.version.update(reviewed=None)
|
|
||||||
self.setup_data(status)
|
|
||||||
getattr(self.helper.handler, process)()
|
|
||||||
assert self.version.reviewed, ('Reviewed for status %r, %s()'
|
|
||||||
% (status, process))
|
|
||||||
|
|
||||||
def test_preliminary_review_time_set(self):
|
def test_nominated_review_time_set_file(self):
|
||||||
for status in amo.UNDER_REVIEW_STATUSES:
|
for process in ('process_sandbox', 'process_public'):
|
||||||
for process in ['process_sandbox', 'process_preliminary']:
|
self.file.update(reviewed=None)
|
||||||
self.file.update(reviewed=None)
|
self.setup_data(amo.STATUS_NOMINATED)
|
||||||
self.setup_data(status)
|
getattr(self.helper.handler, process)()
|
||||||
getattr(self.helper.handler, process)()
|
assert File.objects.get(pk=self.file.pk).reviewed
|
||||||
assert File.objects.get(pk=self.file.pk).reviewed, (
|
|
||||||
'Reviewed for status %r, %s()' % (status, process))
|
|
||||||
|
|
||||||
|
|
||||||
def test_page_title_unicode():
|
def test_page_title_unicode():
|
||||||
|
|
|
@ -16,8 +16,8 @@ from olympia.applications.models import AppVersion
|
||||||
from olympia.editors.models import (
|
from olympia.editors.models import (
|
||||||
EditorSubscription, RereviewQueueTheme, ReviewerScore, send_notifications,
|
EditorSubscription, RereviewQueueTheme, ReviewerScore, send_notifications,
|
||||||
ViewFullReviewQueue, ViewPendingQueue,
|
ViewFullReviewQueue, ViewPendingQueue,
|
||||||
ViewPreliminaryQueue, ViewUnlistedAllList, ViewUnlistedFullReviewQueue,
|
ViewUnlistedAllList, ViewUnlistedFullReviewQueue,
|
||||||
ViewUnlistedPendingQueue, ViewUnlistedPreliminaryQueue)
|
ViewUnlistedPendingQueue)
|
||||||
from olympia.users.models import UserProfile
|
from olympia.users.models import UserProfile
|
||||||
|
|
||||||
|
|
||||||
|
@ -233,16 +233,6 @@ class TestFullReviewQueue(TestQueue):
|
||||||
amo.STATUS_NOMINATED, amo.STATUS_UNREVIEWED,
|
amo.STATUS_NOMINATED, amo.STATUS_UNREVIEWED,
|
||||||
listed=self.listed, **kw)
|
listed=self.listed, **kw)
|
||||||
|
|
||||||
def test_lite_review_addons_also_shows_up(self):
|
|
||||||
create_addon_file('Full', '0.1',
|
|
||||||
amo.STATUS_NOMINATED, amo.STATUS_UNREVIEWED,
|
|
||||||
listed=self.listed)
|
|
||||||
create_addon_file('Lite', '0.1',
|
|
||||||
amo.STATUS_LITE_AND_NOMINATED,
|
|
||||||
amo.STATUS_LITE, listed=self.listed)
|
|
||||||
assert sorted(q.addon_name for q in self.Queue.objects.all()) == (
|
|
||||||
['Full', 'Lite'])
|
|
||||||
|
|
||||||
def test_waiting_time(self):
|
def test_waiting_time(self):
|
||||||
self.new_file(name='Addon 1', version=u'0.1')
|
self.new_file(name='Addon 1', version=u'0.1')
|
||||||
Version.objects.update(nomination=datetime.utcnow())
|
Version.objects.update(nomination=datetime.utcnow())
|
||||||
|
@ -252,41 +242,6 @@ class TestFullReviewQueue(TestQueue):
|
||||||
assert row.waiting_time_hours is not None
|
assert row.waiting_time_hours is not None
|
||||||
|
|
||||||
|
|
||||||
class TestPreliminaryQueue(TestQueue):
|
|
||||||
__test__ = True
|
|
||||||
Queue = ViewPreliminaryQueue
|
|
||||||
|
|
||||||
def new_file(self, name=u'Preliminary', version=u'1.0',
|
|
||||||
addon_status=amo.STATUS_LITE,
|
|
||||||
file_status=amo.STATUS_UNREVIEWED, **kw):
|
|
||||||
return create_addon_file(name, version, addon_status, file_status,
|
|
||||||
listed=self.listed, **kw)
|
|
||||||
|
|
||||||
def new_search_ext(self, name, version, **kw):
|
|
||||||
return create_search_ext(name, version,
|
|
||||||
amo.STATUS_LITE, amo.STATUS_UNREVIEWED,
|
|
||||||
listed=self.listed, **kw)
|
|
||||||
|
|
||||||
def test_unreviewed_addons_are_in_q(self):
|
|
||||||
create_addon_file('Lite', '0.1',
|
|
||||||
amo.STATUS_LITE, amo.STATUS_UNREVIEWED,
|
|
||||||
listed=self.listed)
|
|
||||||
create_addon_file('Unreviewed', '0.1',
|
|
||||||
amo.STATUS_UNREVIEWED, amo.STATUS_UNREVIEWED,
|
|
||||||
listed=self.listed)
|
|
||||||
assert sorted(q.addon_name for q in self.Queue.objects.all()) == (
|
|
||||||
['Lite', 'Unreviewed'])
|
|
||||||
|
|
||||||
def test_waiting_time(self):
|
|
||||||
self.new_file(name='Addon 1', version=u'0.1')
|
|
||||||
Version.objects.update(created=datetime.utcnow())
|
|
||||||
row = self.Queue.objects.all()[0]
|
|
||||||
assert row.waiting_time_days == 0
|
|
||||||
# Time zone might be off due to your MySQL install, hard to test this.
|
|
||||||
assert row.waiting_time_min is not None
|
|
||||||
assert row.waiting_time_hours is not None
|
|
||||||
|
|
||||||
|
|
||||||
class TestUnlistedPendingQueue(TestPendingQueue):
|
class TestUnlistedPendingQueue(TestPendingQueue):
|
||||||
Queue = ViewUnlistedPendingQueue
|
Queue = ViewUnlistedPendingQueue
|
||||||
listed = False
|
listed = False
|
||||||
|
@ -297,27 +252,18 @@ class TestUnlistedFullReviewQueue(TestFullReviewQueue):
|
||||||
listed = False
|
listed = False
|
||||||
|
|
||||||
|
|
||||||
class TestUnlistedPreliminaryQueue(TestPreliminaryQueue):
|
|
||||||
Queue = ViewUnlistedPreliminaryQueue
|
|
||||||
listed = False
|
|
||||||
|
|
||||||
|
|
||||||
class TestUnlistedAllList(TestCase):
|
class TestUnlistedAllList(TestCase):
|
||||||
Queue = ViewUnlistedAllList
|
Queue = ViewUnlistedAllList
|
||||||
listed = False
|
listed = False
|
||||||
fixtures = ['base/users']
|
fixtures = ['base/users']
|
||||||
|
|
||||||
def new_file(self, name=u'Preliminary', version=u'1.0',
|
def new_file(self, name=u'Nominated', version=u'1.0',
|
||||||
addon_status=amo.STATUS_LITE,
|
addon_status=amo.STATUS_NOMINATED,
|
||||||
file_status=amo.STATUS_UNREVIEWED, **kw):
|
file_status=amo.STATUS_UNREVIEWED, **kw):
|
||||||
return create_addon_file(name, version, addon_status, file_status,
|
return create_addon_file(name, version, addon_status, file_status,
|
||||||
listed=self.listed, **kw)
|
listed=self.listed, **kw)
|
||||||
|
|
||||||
def test_all_addons_are_in_q(self):
|
def test_all_addons_are_in_q(self):
|
||||||
self.new_file('Lite', addon_status=amo.STATUS_LITE,
|
|
||||||
file_status=amo.STATUS_UNREVIEWED)
|
|
||||||
self.new_file('Unreviewed', addon_status=amo.STATUS_UNREVIEWED,
|
|
||||||
file_status=amo.STATUS_UNREVIEWED)
|
|
||||||
self.new_file('Public', addon_status=amo.STATUS_PUBLIC,
|
self.new_file('Public', addon_status=amo.STATUS_PUBLIC,
|
||||||
file_status=amo.STATUS_PUBLIC)
|
file_status=amo.STATUS_PUBLIC)
|
||||||
self.new_file('Nominated', addon_status=amo.STATUS_NOMINATED,
|
self.new_file('Nominated', addon_status=amo.STATUS_NOMINATED,
|
||||||
|
@ -325,7 +271,7 @@ class TestUnlistedAllList(TestCase):
|
||||||
self.new_file('Deleted', addon_status=amo.STATUS_PUBLIC,
|
self.new_file('Deleted', addon_status=amo.STATUS_PUBLIC,
|
||||||
file_status=amo.STATUS_PUBLIC)['addon'].delete()
|
file_status=amo.STATUS_PUBLIC)['addon'].delete()
|
||||||
assert sorted(q.addon_name for q in self.Queue.objects.all()) == (
|
assert sorted(q.addon_name for q in self.Queue.objects.all()) == (
|
||||||
['Deleted', 'Lite', 'Nominated', 'Public', 'Unreviewed'])
|
['Deleted', 'Nominated', 'Public'])
|
||||||
|
|
||||||
def test_authors(self):
|
def test_authors(self):
|
||||||
addon = self.new_file()['addon']
|
addon = self.new_file()['addon']
|
||||||
|
@ -341,7 +287,7 @@ class TestUnlistedAllList(TestCase):
|
||||||
today = datetime.today().date()
|
today = datetime.today().date()
|
||||||
self.new_file(name='addon123', version='1.0')
|
self.new_file(name='addon123', version='1.0')
|
||||||
v2 = self.new_file(name='addon123', version='2.0')['version']
|
v2 = self.new_file(name='addon123', version='2.0')['version']
|
||||||
log = amo.log(amo.LOG.PRELIMINARY_VERSION, v2, v2.addon,
|
log = amo.log(amo.LOG.APPROVE_VERSION, v2, v2.addon,
|
||||||
user=UserProfile.objects.get(pk=999))
|
user=UserProfile.objects.get(pk=999))
|
||||||
self.new_file(name='addon123', version='3.0')
|
self.new_file(name='addon123', version='3.0')
|
||||||
row = self.Queue.objects.all()[0]
|
row = self.Queue.objects.all()[0]
|
||||||
|
@ -357,7 +303,7 @@ class TestUnlistedAllList(TestCase):
|
||||||
assert row.review_version_num is None
|
assert row.review_version_num is None
|
||||||
|
|
||||||
ver = self.new_file(name='addon456', version='2.0')['version']
|
ver = self.new_file(name='addon456', version='2.0')['version']
|
||||||
amo.log(amo.LOG.PRELIMINARY_VERSION, ver, ver.addon,
|
amo.log(amo.LOG.APPROVE_VERSION, ver, ver.addon,
|
||||||
user=UserProfile.objects.get(pk=999))
|
user=UserProfile.objects.get(pk=999))
|
||||||
row = self.Queue.objects.all()[0]
|
row = self.Queue.objects.all()[0]
|
||||||
assert row.review_version_num == '2.0'
|
assert row.review_version_num == '2.0'
|
||||||
|
@ -371,7 +317,7 @@ class TestUnlistedAllList(TestCase):
|
||||||
|
|
||||||
def test_no_automatic_reviews(self):
|
def test_no_automatic_reviews(self):
|
||||||
ver = self.new_file(name='addon789', version='1.0')['version']
|
ver = self.new_file(name='addon789', version='1.0')['version']
|
||||||
amo.log(amo.LOG.PRELIMINARY_VERSION, ver, ver.addon,
|
amo.log(amo.LOG.APPROVE_VERSION, ver, ver.addon,
|
||||||
user=UserProfile.objects.get(pk=settings.TASK_USER_ID))
|
user=UserProfile.objects.get(pk=settings.TASK_USER_ID))
|
||||||
row = self.Queue.objects.all()[0]
|
row = self.Queue.objects.all()[0]
|
||||||
assert row.review_version_num is None
|
assert row.review_version_num is None
|
||||||
|
@ -491,14 +437,11 @@ class TestReviewerScore(TestCase):
|
||||||
}
|
}
|
||||||
statuses = {
|
statuses = {
|
||||||
amo.STATUS_NULL: None,
|
amo.STATUS_NULL: None,
|
||||||
amo.STATUS_UNREVIEWED: 'PRELIM',
|
|
||||||
amo.STATUS_PENDING: None,
|
amo.STATUS_PENDING: None,
|
||||||
amo.STATUS_NOMINATED: 'FULL',
|
amo.STATUS_NOMINATED: 'FULL',
|
||||||
amo.STATUS_PUBLIC: 'UPDATE',
|
amo.STATUS_PUBLIC: 'UPDATE',
|
||||||
amo.STATUS_DISABLED: None,
|
amo.STATUS_DISABLED: None,
|
||||||
amo.STATUS_BETA: None,
|
amo.STATUS_BETA: None,
|
||||||
amo.STATUS_LITE: 'PRELIM',
|
|
||||||
amo.STATUS_LITE_AND_NOMINATED: 'FULL',
|
|
||||||
amo.STATUS_DELETED: None,
|
amo.STATUS_DELETED: None,
|
||||||
amo.STATUS_REJECTED: None,
|
amo.STATUS_REJECTED: None,
|
||||||
amo.STATUS_REVIEW_PENDING: None,
|
amo.STATUS_REVIEW_PENDING: None,
|
||||||
|
@ -523,16 +466,16 @@ class TestReviewerScore(TestCase):
|
||||||
user2 = UserProfile.objects.get(email='admin@mozilla.com')
|
user2 = UserProfile.objects.get(email='admin@mozilla.com')
|
||||||
bonus_days = 2
|
bonus_days = 2
|
||||||
days = amo.REVIEWED_OVERDUE_LIMIT + bonus_days
|
days = amo.REVIEWED_OVERDUE_LIMIT + bonus_days
|
||||||
addon_objects = create_addon_file(
|
bonus_addon = create_addon_file(
|
||||||
u'AwardBonus',
|
u'AwardBonus',
|
||||||
u'1.0',
|
u'1.0',
|
||||||
amo.STATUS_NOMINATED,
|
amo.STATUS_NOMINATED,
|
||||||
amo.STATUS_UNREVIEWED,
|
amo.STATUS_UNREVIEWED,
|
||||||
nomination=(datetime.now() - timedelta(days=days))
|
nomination=(datetime.now() - timedelta(days=days, minutes=5))
|
||||||
)
|
)['addon']
|
||||||
self._give_points(user2, addon_objects['addon'], 1)
|
self._give_points(user2, bonus_addon, amo.STATUS_NOMINATED)
|
||||||
score = ReviewerScore.objects.get(user=user2)
|
score = ReviewerScore.objects.get(user=user2)
|
||||||
expected = (amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_PRELIM] +
|
expected = (amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_FULL] +
|
||||||
(amo.REVIEWED_OVERDUE_BONUS * bonus_days))
|
(amo.REVIEWED_OVERDUE_BONUS * bonus_days))
|
||||||
|
|
||||||
assert score.score == expected
|
assert score.score == expected
|
||||||
|
@ -547,11 +490,11 @@ class TestReviewerScore(TestCase):
|
||||||
def test_get_total(self):
|
def test_get_total(self):
|
||||||
user2 = UserProfile.objects.get(email='admin@mozilla.com')
|
user2 = UserProfile.objects.get(email='admin@mozilla.com')
|
||||||
self._give_points()
|
self._give_points()
|
||||||
self._give_points(status=amo.STATUS_LITE)
|
self._give_points(status=amo.STATUS_PUBLIC)
|
||||||
self._give_points(user=user2, status=amo.STATUS_NOMINATED)
|
self._give_points(user=user2, status=amo.STATUS_NOMINATED)
|
||||||
assert ReviewerScore.get_total(self.user) == (
|
assert ReviewerScore.get_total(self.user) == (
|
||||||
amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_FULL] +
|
amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_FULL] +
|
||||||
amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_PRELIM])
|
amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_UPDATE])
|
||||||
assert ReviewerScore.get_total(user2) == (
|
assert ReviewerScore.get_total(user2) == (
|
||||||
amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_FULL])
|
amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_FULL])
|
||||||
|
|
||||||
|
@ -559,19 +502,19 @@ class TestReviewerScore(TestCase):
|
||||||
user2 = UserProfile.objects.get(email='admin@mozilla.com')
|
user2 = UserProfile.objects.get(email='admin@mozilla.com')
|
||||||
self._give_points()
|
self._give_points()
|
||||||
time.sleep(1) # Wait 1 sec so ordering by created is checked.
|
time.sleep(1) # Wait 1 sec so ordering by created is checked.
|
||||||
self._give_points(status=amo.STATUS_LITE)
|
self._give_points(status=amo.STATUS_PUBLIC)
|
||||||
self._give_points(user=user2)
|
self._give_points(user=user2)
|
||||||
scores = ReviewerScore.get_recent(self.user)
|
scores = ReviewerScore.get_recent(self.user)
|
||||||
assert len(scores) == 2
|
assert len(scores) == 2
|
||||||
assert scores[0].score == (
|
assert scores[0].score == (
|
||||||
amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_PRELIM])
|
amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_UPDATE])
|
||||||
assert scores[1].score == (
|
assert scores[1].score == (
|
||||||
amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_FULL])
|
amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_FULL])
|
||||||
|
|
||||||
def test_get_leaderboards(self):
|
def test_get_leaderboards(self):
|
||||||
user2 = UserProfile.objects.get(email='regular@mozilla.com')
|
user2 = UserProfile.objects.get(email='regular@mozilla.com')
|
||||||
self._give_points()
|
self._give_points()
|
||||||
self._give_points(status=amo.STATUS_LITE)
|
self._give_points(status=amo.STATUS_PUBLIC)
|
||||||
self._give_points(user=user2, status=amo.STATUS_NOMINATED)
|
self._give_points(user=user2, status=amo.STATUS_NOMINATED)
|
||||||
leaders = ReviewerScore.get_leaderboards(self.user)
|
leaders = ReviewerScore.get_leaderboards(self.user)
|
||||||
assert leaders['user_rank'] == 1
|
assert leaders['user_rank'] == 1
|
||||||
|
@ -580,7 +523,7 @@ class TestReviewerScore(TestCase):
|
||||||
assert leaders['leader_top'][0]['user_id'] == self.user.id
|
assert leaders['leader_top'][0]['user_id'] == self.user.id
|
||||||
assert leaders['leader_top'][0]['total'] == (
|
assert leaders['leader_top'][0]['total'] == (
|
||||||
amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_FULL] +
|
amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_FULL] +
|
||||||
amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_PRELIM])
|
amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_UPDATE])
|
||||||
assert leaders['leader_top'][1]['rank'] == 2
|
assert leaders['leader_top'][1]['rank'] == 2
|
||||||
assert leaders['leader_top'][1]['user_id'] == user2.id
|
assert leaders['leader_top'][1]['user_id'] == user2.id
|
||||||
assert leaders['leader_top'][1]['total'] == (
|
assert leaders['leader_top'][1]['total'] == (
|
||||||
|
@ -596,7 +539,7 @@ class TestReviewerScore(TestCase):
|
||||||
def test_no_admins_or_staff_in_leaderboards(self):
|
def test_no_admins_or_staff_in_leaderboards(self):
|
||||||
user2 = UserProfile.objects.get(email='admin@mozilla.com')
|
user2 = UserProfile.objects.get(email='admin@mozilla.com')
|
||||||
self._give_points()
|
self._give_points()
|
||||||
self._give_points(status=amo.STATUS_LITE)
|
self._give_points(status=amo.STATUS_PUBLIC)
|
||||||
self._give_points(user=user2, status=amo.STATUS_NOMINATED)
|
self._give_points(user=user2, status=amo.STATUS_NOMINATED)
|
||||||
leaders = ReviewerScore.get_leaderboards(self.user)
|
leaders = ReviewerScore.get_leaderboards(self.user)
|
||||||
assert leaders['user_rank'] == 1
|
assert leaders['user_rank'] == 1
|
||||||
|
@ -626,12 +569,12 @@ class TestReviewerScore(TestCase):
|
||||||
user2 = UserProfile.objects.get(email='regular@mozilla.com')
|
user2 = UserProfile.objects.get(email='regular@mozilla.com')
|
||||||
amo.REVIEWED_LEVELS[0]['points'] = 180
|
amo.REVIEWED_LEVELS[0]['points'] = 180
|
||||||
self._give_points()
|
self._give_points()
|
||||||
self._give_points(status=amo.STATUS_LITE)
|
self._give_points(status=amo.STATUS_PUBLIC)
|
||||||
self._give_points(user=user2, status=amo.STATUS_NOMINATED)
|
self._give_points(user=user2, status=amo.STATUS_NOMINATED)
|
||||||
users = ReviewerScore.all_users_by_score()
|
users = ReviewerScore.all_users_by_score()
|
||||||
assert len(users) == 2
|
assert len(users) == 2
|
||||||
# First user.
|
# First user.
|
||||||
assert users[0]['total'] == 180
|
assert users[0]['total'] == 200
|
||||||
assert users[0]['user_id'] == self.user.id
|
assert users[0]['user_id'] == self.user.id
|
||||||
assert users[0]['level'] == amo.REVIEWED_LEVELS[0]['name']
|
assert users[0]['level'] == amo.REVIEWED_LEVELS[0]['name']
|
||||||
# Second user.
|
# Second user.
|
||||||
|
|
|
@ -48,60 +48,15 @@ def addon_with_files(db):
|
||||||
('process_sandbox', amo.STATUS_NOMINATED, amo.STATUS_UNREVIEWED,
|
('process_sandbox', amo.STATUS_NOMINATED, amo.STATUS_UNREVIEWED,
|
||||||
helpers.ReviewAddon, 'nominated', amo.STATUS_NULL,
|
helpers.ReviewAddon, 'nominated', amo.STATUS_NULL,
|
||||||
amo.STATUS_DISABLED),
|
amo.STATUS_DISABLED),
|
||||||
# scenario2: should succeed, files approved.
|
|
||||||
('process_preliminary', amo.STATUS_NOMINATED, amo.STATUS_UNREVIEWED,
|
|
||||||
helpers.ReviewAddon, 'nominated', amo.STATUS_LITE, amo.STATUS_LITE),
|
|
||||||
|
|
||||||
# New addon request prelim.
|
|
||||||
# scenario3: should fail, no change.
|
|
||||||
('process_public', amo.STATUS_UNREVIEWED, amo.STATUS_UNREVIEWED,
|
|
||||||
helpers.ReviewAddon, 'preliminary', amo.STATUS_UNREVIEWED,
|
|
||||||
amo.STATUS_UNREVIEWED),
|
|
||||||
# scenario4: Should succeed, files rejected.
|
|
||||||
('process_sandbox', amo.STATUS_UNREVIEWED, amo.STATUS_UNREVIEWED,
|
|
||||||
helpers.ReviewAddon, 'preliminary', amo.STATUS_NULL,
|
|
||||||
amo.STATUS_DISABLED),
|
|
||||||
# scenario5: should succeed, files approved.
|
|
||||||
('process_preliminary', amo.STATUS_UNREVIEWED, amo.STATUS_UNREVIEWED,
|
|
||||||
helpers.ReviewAddon, 'preliminary', amo.STATUS_LITE, amo.STATUS_LITE),
|
|
||||||
|
|
||||||
# Prelim addon request full.
|
|
||||||
# scenario6: should succeed, files approved.
|
|
||||||
('process_public', amo.STATUS_LITE_AND_NOMINATED, amo.STATUS_LITE,
|
|
||||||
helpers.ReviewAddon, 'nominated', amo.STATUS_PUBLIC,
|
|
||||||
amo.STATUS_PUBLIC),
|
|
||||||
# scenario7: should succeed, files rejected.
|
|
||||||
('process_sandbox', amo.STATUS_LITE_AND_NOMINATED, amo.STATUS_LITE,
|
|
||||||
helpers.ReviewAddon, 'nominated', amo.STATUS_NULL,
|
|
||||||
amo.STATUS_LITE),
|
|
||||||
# scenario8: Should succeed, files approved.
|
|
||||||
('process_preliminary', amo.STATUS_LITE_AND_NOMINATED, amo.STATUS_LITE,
|
|
||||||
helpers.ReviewAddon, 'nominated', amo.STATUS_LITE, amo.STATUS_LITE),
|
|
||||||
|
|
||||||
# Full addon with a new file.
|
# Full addon with a new file.
|
||||||
# scenario9: should succeed, files approved.
|
# scenario2: should succeed, files approved.
|
||||||
('process_public', amo.STATUS_PUBLIC, amo.STATUS_UNREVIEWED,
|
('process_public', amo.STATUS_PUBLIC, amo.STATUS_UNREVIEWED,
|
||||||
helpers.ReviewFiles, 'pending', amo.STATUS_PUBLIC, amo.STATUS_PUBLIC),
|
helpers.ReviewFiles, 'pending', amo.STATUS_PUBLIC, amo.STATUS_PUBLIC),
|
||||||
# scenario10: should succeed, files rejected.
|
# scenario3: should succeed, files rejected.
|
||||||
('process_sandbox', amo.STATUS_PUBLIC, amo.STATUS_UNREVIEWED,
|
('process_sandbox', amo.STATUS_PUBLIC, amo.STATUS_UNREVIEWED,
|
||||||
helpers.ReviewFiles, 'pending', amo.STATUS_NOMINATED,
|
helpers.ReviewFiles, 'pending', amo.STATUS_NOMINATED,
|
||||||
amo.STATUS_DISABLED),
|
amo.STATUS_DISABLED),
|
||||||
# scenario11: should succeed, files approved.
|
|
||||||
('process_preliminary', amo.STATUS_PUBLIC, amo.STATUS_UNREVIEWED,
|
|
||||||
helpers.ReviewFiles, 'pending', amo.STATUS_LITE, amo.STATUS_LITE),
|
|
||||||
|
|
||||||
# Prelim addon with a new file.
|
|
||||||
# scenario12: should fail, no change.
|
|
||||||
('process_public', amo.STATUS_LITE, amo.STATUS_UNREVIEWED,
|
|
||||||
helpers.ReviewFiles, 'preliminary', amo.STATUS_LITE,
|
|
||||||
amo.STATUS_UNREVIEWED),
|
|
||||||
# scenario13: should succeed, files rejected.
|
|
||||||
('process_sandbox', amo.STATUS_LITE, amo.STATUS_UNREVIEWED,
|
|
||||||
helpers.ReviewFiles, 'preliminary', amo.STATUS_LITE,
|
|
||||||
amo.STATUS_DISABLED),
|
|
||||||
# scenario14: should succeed, files approved.
|
|
||||||
('process_preliminary', amo.STATUS_LITE, amo.STATUS_UNREVIEWED,
|
|
||||||
helpers.ReviewFiles, 'preliminary', amo.STATUS_LITE, amo.STATUS_LITE),
|
|
||||||
])
|
])
|
||||||
def test_review_scenario(mock_request, addon_with_files, review_action,
|
def test_review_scenario(mock_request, addon_with_files, review_action,
|
||||||
addon_status, file_status, review_class, review_type,
|
addon_status, file_status, review_class, review_type,
|
||||||
|
@ -118,7 +73,7 @@ def test_review_scenario(mock_request, addon_with_files, review_action,
|
||||||
helper.get_review_type(mock_request, addon, version)
|
helper.get_review_type(mock_request, addon, version)
|
||||||
assert helper.review_type == review_type
|
assert helper.review_type == review_type
|
||||||
helper.set_data({'comments': 'testing review scenarios'})
|
helper.set_data({'comments': 'testing review scenarios'})
|
||||||
# Run the action (process_public, process_sandbox, process_preliminary).
|
# Run the action (process_public, process_sandbox).
|
||||||
try:
|
try:
|
||||||
getattr(helper.handler, review_action)()
|
getattr(helper.handler, review_action)()
|
||||||
except AssertionError:
|
except AssertionError:
|
||||||
|
|
|
@ -540,12 +540,10 @@ class TestHome(EditorTest):
|
||||||
listed_queues_links = [
|
listed_queues_links = [
|
||||||
reverse('editors.queue_nominated'),
|
reverse('editors.queue_nominated'),
|
||||||
reverse('editors.queue_pending'),
|
reverse('editors.queue_pending'),
|
||||||
reverse('editors.queue_prelim'),
|
|
||||||
reverse('editors.queue_moderated')]
|
reverse('editors.queue_moderated')]
|
||||||
unlisted_queues_links = [
|
unlisted_queues_links = [
|
||||||
reverse('editors.unlisted_queue_nominated'),
|
reverse('editors.unlisted_queue_nominated'),
|
||||||
reverse('editors.unlisted_queue_pending'),
|
reverse('editors.unlisted_queue_pending'),
|
||||||
reverse('editors.unlisted_queue_prelim'),
|
|
||||||
reverse('editors.unlisted_queue_all')]
|
reverse('editors.unlisted_queue_all')]
|
||||||
|
|
||||||
# Only listed queues for editors.
|
# Only listed queues for editors.
|
||||||
|
@ -634,23 +632,13 @@ class QueueTest(EditorTest):
|
||||||
}),
|
}),
|
||||||
('Nominated Two', {
|
('Nominated Two', {
|
||||||
'version_str': '0.1',
|
'version_str': '0.1',
|
||||||
'addon_status': amo.STATUS_LITE_AND_NOMINATED,
|
'addon_status': amo.STATUS_NOMINATED,
|
||||||
'file_status': amo.STATUS_LITE,
|
|
||||||
}),
|
|
||||||
('Prelim One', {
|
|
||||||
'version_str': '0.1',
|
|
||||||
'addon_status': amo.STATUS_LITE,
|
|
||||||
'file_status': amo.STATUS_UNREVIEWED,
|
|
||||||
}),
|
|
||||||
('Prelim Two', {
|
|
||||||
'version_str': '0.1',
|
|
||||||
'addon_status': amo.STATUS_UNREVIEWED,
|
|
||||||
'file_status': amo.STATUS_UNREVIEWED,
|
'file_status': amo.STATUS_UNREVIEWED,
|
||||||
}),
|
}),
|
||||||
('Public', {
|
('Public', {
|
||||||
'version_str': '0.1',
|
'version_str': '0.1',
|
||||||
'addon_status': amo.STATUS_PUBLIC,
|
'addon_status': amo.STATUS_PUBLIC,
|
||||||
'file_status': amo.STATUS_LITE,
|
'file_status': amo.STATUS_PUBLIC,
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
results = SortedDict()
|
results = SortedDict()
|
||||||
|
@ -819,7 +807,7 @@ class TestQueueBasics(QueueTest):
|
||||||
doc = pq(r.content)
|
doc = pq(r.content)
|
||||||
assert doc('#navbar li.top ul').eq(0).text() == (
|
assert doc('#navbar li.top ul').eq(0).text() == (
|
||||||
'Full Reviews (2) Pending Updates (2) '
|
'Full Reviews (2) Pending Updates (2) '
|
||||||
'Preliminary Reviews (2) Moderated Reviews (0)')
|
'Moderated Reviews (0)')
|
||||||
|
|
||||||
def test_legacy_queue_sort(self):
|
def test_legacy_queue_sort(self):
|
||||||
sorts = (
|
sorts = (
|
||||||
|
@ -846,13 +834,6 @@ class TestQueueBasics(QueueTest):
|
||||||
for data in self.get_review_data():
|
for data in self.get_review_data():
|
||||||
self.check_bar(addon, eq=1, data=data, reset_status=True)
|
self.check_bar(addon, eq=1, data=data, reset_status=True)
|
||||||
|
|
||||||
def test_prelim_bar(self):
|
|
||||||
self.generate_files()
|
|
||||||
|
|
||||||
addon = self.addons['Prelim One']
|
|
||||||
for data in self.get_review_data():
|
|
||||||
self.check_bar(addon, eq=2, data=data)
|
|
||||||
|
|
||||||
def check_bar(self, addon, eq, data, reset_status=False):
|
def check_bar(self, addon, eq, data, reset_status=False):
|
||||||
# `eq` is the table number (0, 1 or 2).
|
# `eq` is the table number (0, 1 or 2).
|
||||||
def style(w):
|
def style(w):
|
||||||
|
@ -985,8 +966,7 @@ class TestUnlistedQueueBasics(TestQueueBasics):
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
doc = pq(r.content)
|
doc = pq(r.content)
|
||||||
assert doc('#navbar li.top ul').eq(1).text() == (
|
assert doc('#navbar li.top ul').eq(1).text() == (
|
||||||
'Full Reviews (2) Pending Updates (2) Preliminary Reviews (2) '
|
'Full Reviews (2) Pending Updates (2) All Add-ons (5)')
|
||||||
'All Add-ons (7)')
|
|
||||||
|
|
||||||
def test_listed_unlisted_queues(self):
|
def test_listed_unlisted_queues(self):
|
||||||
# Make sure the listed addons are displayed in the listed queue, and
|
# Make sure the listed addons are displayed in the listed queue, and
|
||||||
|
@ -1092,28 +1072,6 @@ class TestNominatedQueue(QueueTest):
|
||||||
self._test_get_queue()
|
self._test_get_queue()
|
||||||
|
|
||||||
|
|
||||||
class TestPreliminaryQueue(QueueTest):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(TestPreliminaryQueue, self).setUp()
|
|
||||||
# These should be the only ones present.
|
|
||||||
self.expected_addons = self.get_expected_addons_by_names(
|
|
||||||
['Prelim One', 'Prelim Two'])
|
|
||||||
self.url = reverse('editors.queue_prelim')
|
|
||||||
|
|
||||||
def test_results(self):
|
|
||||||
self._test_results()
|
|
||||||
|
|
||||||
def test_breadcrumbs(self):
|
|
||||||
self._test_breadcrumbs([('Preliminary Reviews', None)])
|
|
||||||
|
|
||||||
def test_queue_count(self):
|
|
||||||
self._test_queue_count(2, 'Preliminary Reviews', 2)
|
|
||||||
|
|
||||||
def test_get_queue(self):
|
|
||||||
self._test_get_queue()
|
|
||||||
|
|
||||||
|
|
||||||
class TestModeratedQueue(QueueTest):
|
class TestModeratedQueue(QueueTest):
|
||||||
fixtures = ['base/users', 'reviews/dev-reply']
|
fixtures = ['base/users', 'reviews/dev-reply']
|
||||||
|
|
||||||
|
@ -1246,7 +1204,7 @@ class TestModeratedQueue(QueueTest):
|
||||||
note_key=amo.REVIEWED_ADDON_REVIEW).count() == 1
|
note_key=amo.REVIEWED_ADDON_REVIEW).count() == 1
|
||||||
|
|
||||||
def test_queue_count(self):
|
def test_queue_count(self):
|
||||||
self._test_queue_count(3, 'Moderated Review', 1)
|
self._test_queue_count(2, 'Moderated Review', 1)
|
||||||
|
|
||||||
def test_breadcrumbs(self):
|
def test_breadcrumbs(self):
|
||||||
self._test_breadcrumbs([('Moderated Reviews', None)])
|
self._test_breadcrumbs([('Moderated Reviews', None)])
|
||||||
|
@ -1314,22 +1272,6 @@ class TestUnlistedNominatedQueue(TestNominatedQueue):
|
||||||
self._test_queue_count(0, 'Unlisted Full Reviews', 2)
|
self._test_queue_count(0, 'Unlisted Full Reviews', 2)
|
||||||
|
|
||||||
|
|
||||||
class TestUnlistedPreliminaryQueue(TestPreliminaryQueue):
|
|
||||||
listed = False
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(TestUnlistedPreliminaryQueue, self).setUp()
|
|
||||||
self.url = reverse('editors.unlisted_queue_prelim')
|
|
||||||
# Don't need to call get_expected_addons_by_name() again because
|
|
||||||
# we already called it in setUp() of the parent class
|
|
||||||
|
|
||||||
def test_breadcrumbs(self):
|
|
||||||
self._test_breadcrumbs([('Unlisted Preliminary Reviews', None)])
|
|
||||||
|
|
||||||
def test_queue_count(self):
|
|
||||||
self._test_queue_count(2, 'Unlisted Preliminary Reviews', 2)
|
|
||||||
|
|
||||||
|
|
||||||
class TestUnlistedAllList(QueueTest):
|
class TestUnlistedAllList(QueueTest):
|
||||||
listed = False
|
listed = False
|
||||||
|
|
||||||
|
@ -1339,7 +1281,7 @@ class TestUnlistedAllList(QueueTest):
|
||||||
# We should have all add-ons.
|
# We should have all add-ons.
|
||||||
self.expected_addons = self.get_expected_addons_by_names(
|
self.expected_addons = self.get_expected_addons_by_names(
|
||||||
['Pending One', 'Pending Two', 'Nominated One', 'Nominated Two',
|
['Pending One', 'Pending Two', 'Nominated One', 'Nominated Two',
|
||||||
'Prelim One', 'Prelim Two', 'Public'])
|
'Public'])
|
||||||
# Need to set unique nomination times or we get a psuedo-random order.
|
# Need to set unique nomination times or we get a psuedo-random order.
|
||||||
for idx, addon in enumerate(self.expected_addons):
|
for idx, addon in enumerate(self.expected_addons):
|
||||||
addon.latest_version.update(
|
addon.latest_version.update(
|
||||||
|
@ -1349,14 +1291,14 @@ class TestUnlistedAllList(QueueTest):
|
||||||
self._test_breadcrumbs([('All Unlisted Add-ons', None)])
|
self._test_breadcrumbs([('All Unlisted Add-ons', None)])
|
||||||
|
|
||||||
def test_queue_count(self):
|
def test_queue_count(self):
|
||||||
assert Addon.with_unlisted.all().count() == 7
|
assert Addon.with_unlisted.all().count() == 5
|
||||||
self._test_queue_count(3, 'All Unlisted Add-ons', 7)
|
self._test_queue_count(2, 'All Unlisted Add-ons', 5)
|
||||||
|
|
||||||
def test_results(self):
|
def test_results(self):
|
||||||
self._test_results()
|
self._test_results()
|
||||||
|
|
||||||
def test_review_notes_json(self):
|
def test_review_notes_json(self):
|
||||||
log = amo.log(amo.LOG.PRELIMINARY_VERSION,
|
log = amo.log(amo.LOG.APPROVE_VERSION,
|
||||||
self.expected_addons[0].latest_version,
|
self.expected_addons[0].latest_version,
|
||||||
self.expected_addons[0],
|
self.expected_addons[0],
|
||||||
user=UserProfile.objects.get(pk=999),
|
user=UserProfile.objects.get(pk=999),
|
||||||
|
@ -1879,11 +1821,11 @@ class TestQueueSearchVersionSpecific(SearchTest):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestQueueSearchVersionSpecific, self).setUp()
|
super(TestQueueSearchVersionSpecific, self).setUp()
|
||||||
self.url = reverse('editors.queue_prelim')
|
self.url = reverse('editors.queue_nominated')
|
||||||
create_addon_file('Not Admin Reviewed', '0.1',
|
create_addon_file('Not Admin Reviewed', '0.1',
|
||||||
amo.STATUS_LITE, amo.STATUS_UNREVIEWED)
|
amo.STATUS_NOMINATED, amo.STATUS_UNREVIEWED)
|
||||||
create_addon_file('Justin Bieber Theme', '0.1',
|
create_addon_file('Justin Bieber Theme', '0.1',
|
||||||
amo.STATUS_LITE, amo.STATUS_UNREVIEWED,
|
amo.STATUS_NOMINATED, amo.STATUS_UNREVIEWED,
|
||||||
addon_type=amo.ADDON_THEME)
|
addon_type=amo.ADDON_THEME)
|
||||||
self.bieber = Version.objects.filter(
|
self.bieber = Version.objects.filter(
|
||||||
addon__name__localized_string='Justin Bieber Theme')
|
addon__name__localized_string='Justin Bieber Theme')
|
||||||
|
@ -2104,7 +2046,7 @@ class TestReview(ReviewBase):
|
||||||
for idx in xrange(comments.length):
|
for idx in xrange(comments.length):
|
||||||
td = comments.eq(idx)
|
td = comments.eq(idx)
|
||||||
assert td.find('.history-comment').text() == 'something'
|
assert td.find('.history-comment').text() == 'something'
|
||||||
assert td.find('th').text() == 'Preliminarily approved'
|
assert td.find('th').text() == 'Approved'
|
||||||
assert td.find('td a').text() == self.editor.display_name
|
assert td.find('td a').text() == self.editor.display_name
|
||||||
|
|
||||||
def generate_deleted_versions(self):
|
def generate_deleted_versions(self):
|
||||||
|
@ -2114,7 +2056,7 @@ class TestReview(ReviewBase):
|
||||||
|
|
||||||
versions = ({'version': '0.1', 'action': 'comment',
|
versions = ({'version': '0.1', 'action': 'comment',
|
||||||
'comments': 'millenium hand and shrimp'},
|
'comments': 'millenium hand and shrimp'},
|
||||||
{'version': '0.1', 'action': 'prelim',
|
{'version': '0.1', 'action': 'public',
|
||||||
'comments': 'buggrit'},
|
'comments': 'buggrit'},
|
||||||
{'version': '0.2', 'action': 'comment',
|
{'version': '0.2', 'action': 'comment',
|
||||||
'comments': 'I told em'},
|
'comments': 'I told em'},
|
||||||
|
@ -2199,7 +2141,7 @@ class TestReview(ReviewBase):
|
||||||
|
|
||||||
def test_item_history_header(self):
|
def test_item_history_header(self):
|
||||||
doc = pq(self.client.get(self.url).content)
|
doc = pq(self.client.get(self.url).content)
|
||||||
assert ('Preliminarily Reviewed' in
|
assert ('Reviewed' in
|
||||||
doc('#review-files .listing-header .light').text())
|
doc('#review-files .listing-header .light').text())
|
||||||
|
|
||||||
def test_item_history_comment(self):
|
def test_item_history_comment(self):
|
||||||
|
@ -2331,16 +2273,8 @@ class TestReview(ReviewBase):
|
||||||
assert Addon.objects.get(pk=self.addon.pk).admin_review
|
assert Addon.objects.get(pk=self.addon.pk).admin_review
|
||||||
|
|
||||||
def test_no_public(self):
|
def test_no_public(self):
|
||||||
s = amo.STATUS_PUBLIC
|
has_public = self.version.files.filter(
|
||||||
|
status=amo.STATUS_PUBLIC).exists()
|
||||||
has_public = self.version.files.filter(status=s).exists()
|
|
||||||
assert not has_public
|
|
||||||
|
|
||||||
for version_file in self.version.files.all():
|
|
||||||
version_file.status = amo.STATUS_PUBLIC
|
|
||||||
version_file.save()
|
|
||||||
|
|
||||||
has_public = self.version.files.filter(status=s).exists()
|
|
||||||
assert has_public
|
assert has_public
|
||||||
|
|
||||||
response = self.client.get(self.url)
|
response = self.client.get(self.url)
|
||||||
|
@ -2427,7 +2361,7 @@ class TestReview(ReviewBase):
|
||||||
@patch('olympia.editors.helpers.sign_file')
|
@patch('olympia.editors.helpers.sign_file')
|
||||||
def review_version(self, version, url, mock_sign):
|
def review_version(self, version, url, mock_sign):
|
||||||
version.files.all()[0].update(status=amo.STATUS_UNREVIEWED)
|
version.files.all()[0].update(status=amo.STATUS_UNREVIEWED)
|
||||||
data = dict(action='prelim', operating_systems='win',
|
data = dict(action='public', operating_systems='win',
|
||||||
applications='something', comments='something')
|
applications='something', comments='something')
|
||||||
self.client.post(url, data)
|
self.client.post(url, data)
|
||||||
|
|
||||||
|
@ -2468,16 +2402,12 @@ class TestReview(ReviewBase):
|
||||||
self.assertContains(r, 'View Privacy Policy')
|
self.assertContains(r, 'View Privacy Policy')
|
||||||
|
|
||||||
def test_breadcrumbs_all(self):
|
def test_breadcrumbs_all(self):
|
||||||
queues = {'Full Reviews': [amo.STATUS_NOMINATED,
|
queues = {'Full Reviews': amo.STATUS_NOMINATED,
|
||||||
amo.STATUS_LITE_AND_NOMINATED],
|
'Pending Updates': amo.STATUS_PUBLIC}
|
||||||
'Preliminary Reviews': [amo.STATUS_UNREVIEWED,
|
for text, queue_id in queues.items():
|
||||||
amo.STATUS_LITE],
|
self.addon.update(status=queue_id)
|
||||||
'Pending Updates': [amo.STATUS_PENDING, amo.STATUS_PUBLIC]}
|
doc = pq(self.client.get(self.url).content)
|
||||||
for text, queue_ids in queues.items():
|
assert doc('#breadcrumbs li').eq(1).text() == text
|
||||||
for qid in queue_ids:
|
|
||||||
self.addon.update(status=qid)
|
|
||||||
doc = pq(self.client.get(self.url).content)
|
|
||||||
assert doc('#breadcrumbs li').eq(1).text() == text
|
|
||||||
|
|
||||||
def test_viewing(self):
|
def test_viewing(self):
|
||||||
url = reverse('editors.review_viewing')
|
url = reverse('editors.review_viewing')
|
||||||
|
@ -2739,61 +2669,6 @@ class TestReview(ReviewBase):
|
||||||
assert not validate.called
|
assert not validate.called
|
||||||
|
|
||||||
|
|
||||||
class TestReviewPreliminary(ReviewBase):
|
|
||||||
|
|
||||||
def prelim_dict(self):
|
|
||||||
return self.get_dict(action='prelim')
|
|
||||||
|
|
||||||
def test_prelim_comments_requested(self):
|
|
||||||
response = self.client.post(self.url, {'action': 'prelim'})
|
|
||||||
assert response.context['form'].errors['comments'][0] == (
|
|
||||||
'This field is required.')
|
|
||||||
|
|
||||||
@patch('olympia.editors.helpers.sign_file')
|
|
||||||
def test_prelim_from_lite(self, mock_sign):
|
|
||||||
self.addon.update(status=amo.STATUS_LITE)
|
|
||||||
self.version.files.all()[0].update(status=amo.STATUS_UNREVIEWED)
|
|
||||||
response = self.client.post(self.url, self.prelim_dict())
|
|
||||||
assert response.status_code == 302
|
|
||||||
assert self.get_addon().status == amo.STATUS_LITE
|
|
||||||
|
|
||||||
assert mock_sign.called
|
|
||||||
|
|
||||||
def test_prelim_from_lite_required(self):
|
|
||||||
self.version.files.update(status=amo.STATUS_UNREVIEWED)
|
|
||||||
self.addon.update(status=amo.STATUS_LITE)
|
|
||||||
response = self.client.post(self.url, {'action': 'prelim'})
|
|
||||||
assert response.context['form'].errors['comments'][0] == (
|
|
||||||
'This field is required.')
|
|
||||||
|
|
||||||
def test_prelim_from_lite_files(self):
|
|
||||||
self.version.files.update(status=amo.STATUS_UNREVIEWED)
|
|
||||||
self.addon.update(status=amo.STATUS_LITE)
|
|
||||||
self.client.post(self.url, self.prelim_dict())
|
|
||||||
assert self.get_addon().status == amo.STATUS_LITE
|
|
||||||
|
|
||||||
@patch('olympia.editors.helpers.sign_file')
|
|
||||||
def test_prelim_from_unreviewed(self, mock_sign):
|
|
||||||
self.version.files.update(status=amo.STATUS_UNREVIEWED)
|
|
||||||
self.addon.update(status=amo.STATUS_UNREVIEWED)
|
|
||||||
response = self.client.post(self.url, self.prelim_dict())
|
|
||||||
assert response.status_code == 302
|
|
||||||
assert self.get_addon().status == amo.STATUS_LITE
|
|
||||||
|
|
||||||
assert mock_sign.called
|
|
||||||
|
|
||||||
def test_prelim_multiple_files(self):
|
|
||||||
file_ = self.version.files.all()[0]
|
|
||||||
file_.pk = None
|
|
||||||
file_.status = amo.STATUS_DISABLED
|
|
||||||
file_.save()
|
|
||||||
self.addon.update(status=amo.STATUS_LITE)
|
|
||||||
data = self.prelim_dict()
|
|
||||||
self.client.post(self.url, data)
|
|
||||||
assert [amo.STATUS_DISABLED, amo.STATUS_LITE] == (
|
|
||||||
[f.status for f in self.version.files.all().order_by('status')])
|
|
||||||
|
|
||||||
|
|
||||||
class TestReviewPending(ReviewBase):
|
class TestReviewPending(ReviewBase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -2809,7 +2684,7 @@ class TestReviewPending(ReviewBase):
|
||||||
def test_pending_to_public(self, mock_sign):
|
def test_pending_to_public(self, mock_sign):
|
||||||
statuses = (self.version.files.values_list('status', flat=True)
|
statuses = (self.version.files.values_list('status', flat=True)
|
||||||
.order_by('status'))
|
.order_by('status'))
|
||||||
assert list(statuses) == [amo.STATUS_UNREVIEWED, amo.STATUS_LITE]
|
assert list(statuses) == [amo.STATUS_UNREVIEWED, amo.STATUS_PUBLIC]
|
||||||
|
|
||||||
response = self.client.post(self.url, self.pending_dict())
|
response = self.client.post(self.url, self.pending_dict())
|
||||||
assert self.get_addon().status == amo.STATUS_PUBLIC
|
assert self.get_addon().status == amo.STATUS_PUBLIC
|
||||||
|
@ -2817,7 +2692,7 @@ class TestReviewPending(ReviewBase):
|
||||||
|
|
||||||
statuses = (self.version.files.values_list('status', flat=True)
|
statuses = (self.version.files.values_list('status', flat=True)
|
||||||
.order_by('status'))
|
.order_by('status'))
|
||||||
assert list(statuses) == [amo.STATUS_PUBLIC, amo.STATUS_LITE]
|
assert list(statuses) == [amo.STATUS_PUBLIC, amo.STATUS_PUBLIC]
|
||||||
|
|
||||||
assert mock_sign.called
|
assert mock_sign.called
|
||||||
|
|
||||||
|
@ -2826,7 +2701,7 @@ class TestReviewPending(ReviewBase):
|
||||||
self.addon.update(is_listed=False)
|
self.addon.update(is_listed=False)
|
||||||
statuses = (self.version.files.values_list('status', flat=True)
|
statuses = (self.version.files.values_list('status', flat=True)
|
||||||
.order_by('status'))
|
.order_by('status'))
|
||||||
assert list(statuses) == [amo.STATUS_UNREVIEWED, amo.STATUS_LITE]
|
assert list(statuses) == [amo.STATUS_UNREVIEWED, amo.STATUS_PUBLIC]
|
||||||
|
|
||||||
self.login_as_admin()
|
self.login_as_admin()
|
||||||
response = self.client.post(self.url, self.pending_dict())
|
response = self.client.post(self.url, self.pending_dict())
|
||||||
|
@ -2835,7 +2710,7 @@ class TestReviewPending(ReviewBase):
|
||||||
|
|
||||||
statuses = (self.version.files.values_list('status', flat=True)
|
statuses = (self.version.files.values_list('status', flat=True)
|
||||||
.order_by('status'))
|
.order_by('status'))
|
||||||
assert list(statuses) == [amo.STATUS_PUBLIC, amo.STATUS_LITE]
|
assert list(statuses) == [amo.STATUS_PUBLIC, amo.STATUS_PUBLIC]
|
||||||
|
|
||||||
assert mock_sign.called
|
assert mock_sign.called
|
||||||
|
|
||||||
|
@ -2948,29 +2823,16 @@ class TestStatusFile(ReviewBase):
|
||||||
r = self.client.get(self.url)
|
r = self.client.get(self.url)
|
||||||
assert pq(r.content)('#review-files .file-info div').text() == expected
|
assert pq(r.content)('#review-files .file-info div').text() == expected
|
||||||
|
|
||||||
def test_status_prelim(self):
|
|
||||||
self.get_file().update(status=amo.STATUS_UNREVIEWED)
|
|
||||||
for status in [amo.STATUS_UNREVIEWED, amo.STATUS_LITE]:
|
|
||||||
self.addon.update(status=status)
|
|
||||||
self.check_status('Pending Preliminary Review')
|
|
||||||
|
|
||||||
def test_status_full(self):
|
def test_status_full(self):
|
||||||
self.get_file().update(status=amo.STATUS_UNREVIEWED)
|
self.get_file().update(status=amo.STATUS_UNREVIEWED)
|
||||||
for status in [amo.STATUS_NOMINATED, amo.STATUS_PUBLIC]:
|
for status in [amo.STATUS_NOMINATED, amo.STATUS_PUBLIC]:
|
||||||
self.addon.update(status=status)
|
self.addon.update(status=status)
|
||||||
self.check_status('Pending Full Review')
|
self.check_status('Awaiting Review')
|
||||||
|
|
||||||
def test_status_upgrade_to_full(self):
|
|
||||||
self.addon.update(status=amo.STATUS_LITE_AND_NOMINATED)
|
|
||||||
for status in [amo.STATUS_UNREVIEWED, amo.STATUS_LITE]:
|
|
||||||
self.get_file().update(status=status)
|
|
||||||
self.check_status('Pending Full Review')
|
|
||||||
|
|
||||||
def test_status_full_reviewed(self):
|
def test_status_full_reviewed(self):
|
||||||
self.get_file().update(status=amo.STATUS_PUBLIC)
|
self.get_file().update(status=amo.STATUS_PUBLIC)
|
||||||
for status in set(amo.UNDER_REVIEW_STATUSES + amo.LITE_STATUSES):
|
self.addon.update(status=amo.STATUS_PUBLIC)
|
||||||
self.addon.update(status=status)
|
self.check_status('Fully Reviewed')
|
||||||
self.check_status('Fully Reviewed')
|
|
||||||
|
|
||||||
def test_other(self):
|
def test_other(self):
|
||||||
self.addon.update(status=amo.STATUS_BETA)
|
self.addon.update(status=amo.STATUS_BETA)
|
||||||
|
|
|
@ -12,8 +12,6 @@ urlpatterns = (
|
||||||
name='editors.queue_nominated'),
|
name='editors.queue_nominated'),
|
||||||
url(r'^queue/pending$', views.queue_pending,
|
url(r'^queue/pending$', views.queue_pending,
|
||||||
name='editors.queue_pending'),
|
name='editors.queue_pending'),
|
||||||
url(r'^queue/preliminary$', views.queue_prelim,
|
|
||||||
name='editors.queue_prelim'),
|
|
||||||
url(r'^queue/reviews$', views.queue_moderated,
|
url(r'^queue/reviews$', views.queue_moderated,
|
||||||
name='editors.queue_moderated'),
|
name='editors.queue_moderated'),
|
||||||
url(r'^queue/application_versions\.json$', views.application_versions_json,
|
url(r'^queue/application_versions\.json$', views.application_versions_json,
|
||||||
|
@ -24,8 +22,6 @@ urlpatterns = (
|
||||||
name='editors.unlisted_queue_nominated'),
|
name='editors.unlisted_queue_nominated'),
|
||||||
url(r'^unlisted_queue/pending$', views.unlisted_queue_pending,
|
url(r'^unlisted_queue/pending$', views.unlisted_queue_pending,
|
||||||
name='editors.unlisted_queue_pending'),
|
name='editors.unlisted_queue_pending'),
|
||||||
url(r'^unlisted_queue/preliminary$', views.unlisted_queue_prelim,
|
|
||||||
name='editors.unlisted_queue_prelim'),
|
|
||||||
url(r'^unlisted_queue/all$', views.unlisted_list,
|
url(r'^unlisted_queue/all$', views.unlisted_list,
|
||||||
name='editors.unlisted_queue_all'),
|
name='editors.unlisted_queue_all'),
|
||||||
url(r'^logs$', views.eventlog, name='editors.eventlog'),
|
url(r'^logs$', views.eventlog, name='editors.eventlog'),
|
||||||
|
|
|
@ -27,15 +27,12 @@ from olympia.devhub.models import ActivityLog, AddonLog, CommentLog
|
||||||
from olympia.editors import forms
|
from olympia.editors import forms
|
||||||
from olympia.editors.models import (
|
from olympia.editors.models import (
|
||||||
AddonCannedResponse, EditorSubscription, EventLog, PerformanceGraph,
|
AddonCannedResponse, EditorSubscription, EventLog, PerformanceGraph,
|
||||||
ReviewerScore, ViewFullReviewQueue, ViewPendingQueue,
|
ReviewerScore, ViewFullReviewQueue, ViewPendingQueue, ViewQueue,
|
||||||
ViewPreliminaryQueue, ViewQueue, ViewUnlistedAllList,
|
ViewUnlistedAllList, ViewUnlistedFullReviewQueue, ViewUnlistedPendingQueue)
|
||||||
ViewUnlistedFullReviewQueue,
|
|
||||||
ViewUnlistedPendingQueue, ViewUnlistedPreliminaryQueue)
|
|
||||||
from olympia.editors.helpers import (
|
from olympia.editors.helpers import (
|
||||||
is_limited_reviewer, ReviewHelper, ViewFullReviewQueueTable,
|
is_limited_reviewer, ReviewHelper, ViewFullReviewQueueTable,
|
||||||
ViewPendingQueueTable, ViewPreliminaryQueueTable, ViewUnlistedAllListTable,
|
ViewPendingQueueTable, ViewUnlistedAllListTable,
|
||||||
ViewUnlistedFullReviewQueueTable, ViewUnlistedPendingQueueTable,
|
ViewUnlistedFullReviewQueueTable, ViewUnlistedPendingQueueTable)
|
||||||
ViewUnlistedPreliminaryQueueTable)
|
|
||||||
from olympia.reviews.forms import ReviewFlagFormSet
|
from olympia.reviews.forms import ReviewFlagFormSet
|
||||||
from olympia.reviews.models import Review, ReviewFlag
|
from olympia.reviews.models import Review, ReviewFlag
|
||||||
from olympia.users.models import UserProfile
|
from olympia.users.models import UserProfile
|
||||||
|
@ -203,7 +200,7 @@ def _editor_progress(unlisted=False, limited_reviewer=False):
|
||||||
"""Return the progress (number of add-ons still unreviewed for a given
|
"""Return the progress (number of add-ons still unreviewed for a given
|
||||||
period of time) and the percentage (out of all add-ons of that type)."""
|
period of time) and the percentage (out of all add-ons of that type)."""
|
||||||
|
|
||||||
types = ['nominated', 'prelim', 'pending']
|
types = ['nominated', 'pending']
|
||||||
progress = {'new': queue_counts(types, days_max=4, unlisted=unlisted,
|
progress = {'new': queue_counts(types, days_max=4, unlisted=unlisted,
|
||||||
admin_reviewer=True,
|
admin_reviewer=True,
|
||||||
limited_reviewer=limited_reviewer),
|
limited_reviewer=limited_reviewer),
|
||||||
|
@ -462,7 +459,6 @@ def queue_counts(type=None, unlisted=False, admin_reviewer=False,
|
||||||
|
|
||||||
counts = {'pending': construct_query(ViewPendingQueue, **kw),
|
counts = {'pending': construct_query(ViewPendingQueue, **kw),
|
||||||
'nominated': construct_query(ViewFullReviewQueue, **kw),
|
'nominated': construct_query(ViewFullReviewQueue, **kw),
|
||||||
'prelim': construct_query(ViewPreliminaryQueue, **kw),
|
|
||||||
'moderated': (
|
'moderated': (
|
||||||
Review.objects.filter(reviewflag__isnull=False,
|
Review.objects.filter(reviewflag__isnull=False,
|
||||||
editorreview=1).count)}
|
editorreview=1).count)}
|
||||||
|
@ -470,7 +466,6 @@ def queue_counts(type=None, unlisted=False, admin_reviewer=False,
|
||||||
counts = {
|
counts = {
|
||||||
'pending': construct_query(ViewUnlistedPendingQueue, **kw),
|
'pending': construct_query(ViewUnlistedPendingQueue, **kw),
|
||||||
'nominated': construct_query(ViewUnlistedFullReviewQueue, **kw),
|
'nominated': construct_query(ViewUnlistedFullReviewQueue, **kw),
|
||||||
'prelim': construct_query(ViewUnlistedPreliminaryQueue, **kw),
|
|
||||||
'all': (ViewUnlistedAllList.objects if admin_reviewer
|
'all': (ViewUnlistedAllList.objects if admin_reviewer
|
||||||
else exclude_admin_only_addons(
|
else exclude_admin_only_addons(
|
||||||
ViewUnlistedAllList.objects)).count}
|
ViewUnlistedAllList.objects)).count}
|
||||||
|
@ -498,11 +493,6 @@ def queue_pending(request):
|
||||||
return _queue(request, ViewPendingQueueTable, 'pending')
|
return _queue(request, ViewPendingQueueTable, 'pending')
|
||||||
|
|
||||||
|
|
||||||
@addons_reviewer_required
|
|
||||||
def queue_prelim(request):
|
|
||||||
return _queue(request, ViewPreliminaryQueueTable, 'prelim')
|
|
||||||
|
|
||||||
|
|
||||||
@addons_reviewer_required
|
@addons_reviewer_required
|
||||||
def queue_moderated(request):
|
def queue_moderated(request):
|
||||||
# In addition to other checks, this only show reviews for public and
|
# In addition to other checks, this only show reviews for public and
|
||||||
|
@ -558,12 +548,6 @@ def unlisted_queue_pending(request):
|
||||||
unlisted=True)
|
unlisted=True)
|
||||||
|
|
||||||
|
|
||||||
@unlisted_addons_reviewer_required
|
|
||||||
def unlisted_queue_prelim(request):
|
|
||||||
return _queue(request, ViewUnlistedPreliminaryQueueTable, 'prelim',
|
|
||||||
unlisted=True)
|
|
||||||
|
|
||||||
|
|
||||||
@addons_reviewer_required
|
@addons_reviewer_required
|
||||||
@post_required
|
@post_required
|
||||||
@json_view
|
@json_view
|
||||||
|
@ -587,8 +571,7 @@ def review(request, addon):
|
||||||
|
|
||||||
form_helper = ReviewHelper(request=request, addon=addon, version=version)
|
form_helper = ReviewHelper(request=request, addon=addon, version=version)
|
||||||
form = forms.ReviewForm(request.POST or None, helper=form_helper)
|
form = forms.ReviewForm(request.POST or None, helper=form_helper)
|
||||||
queue_type = ('prelim' if form.helper.review_type == 'preliminary'
|
queue_type = form.helper.review_type
|
||||||
else form.helper.review_type)
|
|
||||||
if addon.is_listed:
|
if addon.is_listed:
|
||||||
redirect_url = reverse('editors.queue_%s' % queue_type)
|
redirect_url = reverse('editors.queue_%s' % queue_type)
|
||||||
else:
|
else:
|
||||||
|
@ -619,14 +602,11 @@ def review(request, addon):
|
||||||
canned = AddonCannedResponse.objects.all()
|
canned = AddonCannedResponse.objects.all()
|
||||||
actions = form.helper.actions.items()
|
actions = form.helper.actions.items()
|
||||||
|
|
||||||
statuses = [amo.STATUS_PUBLIC, amo.STATUS_LITE,
|
|
||||||
amo.STATUS_LITE_AND_NOMINATED]
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
show_diff = version and (
|
show_diff = version and (
|
||||||
addon.versions.exclude(id=version.id).filter(
|
addon.versions.exclude(id=version.id).filter(
|
||||||
files__isnull=False, created__lt=version.created,
|
files__isnull=False, created__lt=version.created,
|
||||||
files__status__in=statuses).latest())
|
files__status=amo.STATUS_PUBLIC).latest())
|
||||||
except Version.DoesNotExist:
|
except Version.DoesNotExist:
|
||||||
show_diff = None
|
show_diff = None
|
||||||
|
|
||||||
|
@ -832,6 +812,7 @@ def reviewlog(request):
|
||||||
pager = amo.utils.paginate(request, approvals, 50)
|
pager = amo.utils.paginate(request, approvals, 50)
|
||||||
ad = {
|
ad = {
|
||||||
amo.LOG.APPROVE_VERSION.id: _('was approved'),
|
amo.LOG.APPROVE_VERSION.id: _('was approved'),
|
||||||
|
# The log will still show preliminary, even after the migration.
|
||||||
amo.LOG.PRELIMINARY_VERSION.id: _('given preliminary review'),
|
amo.LOG.PRELIMINARY_VERSION.id: _('given preliminary review'),
|
||||||
amo.LOG.REJECT_VERSION.id: _('rejected'),
|
amo.LOG.REJECT_VERSION.id: _('rejected'),
|
||||||
amo.LOG.ESCALATE_VERSION.id: pgettext(
|
amo.LOG.ESCALATE_VERSION.id: pgettext(
|
||||||
|
|
|
@ -278,20 +278,15 @@ class Version(OnChangeMixin, ModelBase):
|
||||||
def current_queue(self):
|
def current_queue(self):
|
||||||
"""Return the current queue, or None if not in a queue."""
|
"""Return the current queue, or None if not in a queue."""
|
||||||
from olympia.editors.models import (
|
from olympia.editors.models import (
|
||||||
ViewFullReviewQueue, ViewPendingQueue, ViewPreliminaryQueue,
|
ViewFullReviewQueue, ViewPendingQueue,
|
||||||
ViewUnlistedFullReviewQueue, ViewUnlistedPendingQueue,
|
ViewUnlistedFullReviewQueue, ViewUnlistedPendingQueue)
|
||||||
ViewUnlistedPreliminaryQueue)
|
|
||||||
|
|
||||||
if self.addon.status in [amo.STATUS_NOMINATED,
|
if self.addon.status == amo.STATUS_NOMINATED:
|
||||||
amo.STATUS_LITE_AND_NOMINATED]:
|
|
||||||
return (ViewFullReviewQueue if self.addon.is_listed
|
return (ViewFullReviewQueue if self.addon.is_listed
|
||||||
else ViewUnlistedFullReviewQueue)
|
else ViewUnlistedFullReviewQueue)
|
||||||
elif self.addon.status == amo.STATUS_PUBLIC:
|
elif self.addon.status == amo.STATUS_PUBLIC:
|
||||||
return (ViewPendingQueue if self.addon.is_listed
|
return (ViewPendingQueue if self.addon.is_listed
|
||||||
else ViewUnlistedPendingQueue)
|
else ViewUnlistedPendingQueue)
|
||||||
elif self.addon.status in [amo.STATUS_LITE, amo.STATUS_UNREVIEWED]:
|
|
||||||
return (ViewPreliminaryQueue if self.addon.is_listed
|
|
||||||
else ViewUnlistedPreliminaryQueue)
|
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
|
@ -28,9 +28,8 @@ from olympia.addons.tests.test_views import TestMobile
|
||||||
from olympia.applications.models import AppVersion
|
from olympia.applications.models import AppVersion
|
||||||
from olympia.devhub.models import ActivityLog
|
from olympia.devhub.models import ActivityLog
|
||||||
from olympia.editors.models import (
|
from olympia.editors.models import (
|
||||||
ViewFullReviewQueue, ViewPendingQueue, ViewPreliminaryQueue,
|
ViewFullReviewQueue, ViewPendingQueue,
|
||||||
ViewUnlistedFullReviewQueue, ViewUnlistedPendingQueue,
|
ViewUnlistedFullReviewQueue, ViewUnlistedPendingQueue,)
|
||||||
ViewUnlistedPreliminaryQueue)
|
|
||||||
from olympia.files.models import File
|
from olympia.files.models import File
|
||||||
from olympia.files.tests.test_models import UploadTest
|
from olympia.files.tests.test_models import UploadTest
|
||||||
from olympia.users.models import UserProfile
|
from olympia.users.models import UserProfile
|
||||||
|
@ -511,27 +510,22 @@ class TestVersion(TestCase):
|
||||||
|
|
||||||
def test_current_queue(self):
|
def test_current_queue(self):
|
||||||
queue_to_status = {
|
queue_to_status = {
|
||||||
ViewFullReviewQueue: [amo.STATUS_NOMINATED,
|
ViewFullReviewQueue: amo.STATUS_NOMINATED,
|
||||||
amo.STATUS_LITE_AND_NOMINATED],
|
ViewPendingQueue: amo.STATUS_PUBLIC
|
||||||
ViewPendingQueue: [amo.STATUS_PUBLIC],
|
}
|
||||||
ViewPreliminaryQueue: [amo.STATUS_LITE, amo.STATUS_UNREVIEWED]}
|
|
||||||
unlisted_queue_to_status = {
|
unlisted_queue_to_status = {
|
||||||
ViewUnlistedFullReviewQueue: [amo.STATUS_NOMINATED,
|
ViewUnlistedFullReviewQueue: amo.STATUS_NOMINATED,
|
||||||
amo.STATUS_LITE_AND_NOMINATED],
|
ViewUnlistedPendingQueue: amo.STATUS_PUBLIC,
|
||||||
ViewUnlistedPendingQueue: [amo.STATUS_PUBLIC],
|
}
|
||||||
ViewUnlistedPreliminaryQueue: [amo.STATUS_LITE,
|
|
||||||
amo.STATUS_UNREVIEWED]}
|
|
||||||
|
|
||||||
for queue, statuses in queue_to_status.iteritems(): # Listed queues.
|
for queue, status in queue_to_status.iteritems(): # Listed queues.
|
||||||
for status in statuses:
|
self.version.addon.update(status=status)
|
||||||
self.version.addon.update(status=status)
|
assert self.version.current_queue == queue
|
||||||
assert self.version.current_queue == queue
|
|
||||||
|
|
||||||
self.version.addon.update(is_listed=False) # Unlisted queues.
|
self.version.addon.update(is_listed=False) # Unlisted queues.
|
||||||
for queue, statuses in unlisted_queue_to_status.iteritems():
|
for queue, status in unlisted_queue_to_status.iteritems():
|
||||||
for status in statuses:
|
self.version.addon.update(status=status)
|
||||||
self.version.addon.update(status=status)
|
assert self.version.current_queue == queue
|
||||||
assert self.version.current_queue == queue
|
|
||||||
|
|
||||||
def test_get_url_path(self):
|
def test_get_url_path(self):
|
||||||
assert self.version.get_url_path() == (
|
assert self.version.get_url_path() == (
|
||||||
|
|
|
@ -272,10 +272,15 @@ ul.tabnav a:hover {
|
||||||
|
|
||||||
.editor-stats-title,
|
.editor-stats-title,
|
||||||
.editor-stats-table {
|
.editor-stats-table {
|
||||||
width: 33.3333%;
|
width: 50%;
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.editor-stats-title.three-col,
|
||||||
|
.editor-stats-table.three-col {
|
||||||
|
width: 33.333333%;
|
||||||
|
}
|
||||||
|
|
||||||
.editor-stats-title span,
|
.editor-stats-title span,
|
||||||
.editor-stats-title a {
|
.editor-stats-title a {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче