This commit is contained in:
Andrew Williamson 2016-09-28 12:06:11 +01:00 коммит произвёл GitHub
Родитель aab1e8cfd8
Коммит 42b82a57c1
21 изменённых файлов: 312 добавлений и 1286 удалений

Просмотреть файл

@ -39,9 +39,7 @@ class Command(BaseCommand):
def get_files(addon_guids):
"""Return the list of files that need approval, given a list of GUIDs.
A file needs approval if:
- it's unreviewed
- it's preliminary reviewed, but its addon is requesting a full review
A file needs approval if it's unreviewed.
"""
# Get all the add-ons that have a GUID from the list, and which are either
# reviewed or awaiting a review.
@ -59,11 +57,7 @@ def get_files(addon_guids):
def approve_files(files_with_review_type):
"""Approve the files (and sign them).
A file will be fully approved if:
- 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
A file will be fully approved if it's waiting for a full review
"""
for file_, review_type in files_with_review_type:
version = file_.version
@ -77,10 +71,6 @@ def approve_files(files_with_review_type):
# Already fully reviewed, or waiting for a full review.
helper.handler.process_public()
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:
log.info(u'File %s (addon %s) not reviewed: '
u'addon status: %s, file status: %s',
@ -88,17 +78,10 @@ def approve_files(files_with_review_type):
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
if addon_status in [amo.STATUS_NOMINATED, amo.STATUS_LITE_AND_NOMINATED]:
# Add-on is waiting for a full review.
if addon_status == amo.STATUS_NOMINATED or (
addon_status == amo.STATUS_PUBLIC and
file_.status == amo.STATUS_UNREVIEWED):
# Add-on or file is waiting for a full review.
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(
params=[(amo.STATUS_UNREVIEWED, amo.STATUS_UNREVIEWED, 'prelim'),
(amo.STATUS_LITE, amo.STATUS_UNREVIEWED, 'prelim'),
(amo.STATUS_NOMINATED, amo.STATUS_UNREVIEWED, 'full'),
(amo.STATUS_PUBLIC, amo.STATUS_UNREVIEWED, 'full'),
(amo.STATUS_LITE_AND_NOMINATED, amo.STATUS_LITE, 'full')],
params=[(amo.STATUS_NOMINATED, amo.STATUS_UNREVIEWED, 'full'),
(amo.STATUS_PUBLIC, amo.STATUS_UNREVIEWED, 'full')],
# ids are used to build better names for the tests using this fixture.
ids=id_function)
def use_case(request, db):
@ -133,11 +130,8 @@ def use_case(request, db):
Addon | File1 and 2 | Review type
==============================================================
waiting for prelim | unreviewed | prelim reviewed
prelim reviewed | unreviewed | prelim reviewed
waiting for full | unreviewed | fully reviewed
fully reviewed | unreviewed | fully reviewed
prelim waiting for full | prelim reviewed | fully reviewed
"""
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
approve_addons.approve_files([(file1, review_type),
(file2, review_type)])
assert file1.reload().status == (
amo.STATUS_LITE if review_type == 'prelim' else amo.STATUS_PUBLIC)
assert file2.reload().status == (
amo.STATUS_LITE if review_type == 'prelim' else amo.STATUS_PUBLIC)
assert file1.reload().status == amo.STATUS_PUBLIC
assert file2.reload().status == amo.STATUS_PUBLIC
logs = AddonLog.objects.filter(addon=addon)
assert len(logs) == 2 # One per file.
file1_log, file2_log = logs

Просмотреть файл

@ -373,7 +373,7 @@ class ReviewForm(happyforms.Form):
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():
action_choices = [[c.response, c.name] for c in responses
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.editors.models import (
ReviewerScore, ViewFullReviewQueue, ViewPendingQueue,
ViewPreliminaryQueue, ViewUnlistedAllList, ViewUnlistedFullReviewQueue,
ViewUnlistedPendingQueue, ViewUnlistedPreliminaryQueue)
ViewUnlistedAllList, ViewUnlistedFullReviewQueue,
ViewUnlistedPendingQueue)
from olympia.lib.crypto.packaged import sign_file
from olympia.users.models import UserProfile
@ -48,19 +48,7 @@ def file_compare(file_obj, version):
@register.function
def file_review_status(addon, file):
# If the file is pending review, check the add-on status
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.status == amo.STATUS_DISABLED:
if file.reviewed is not None:
return _(u'Rejected')
# 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:
queue_id = addon_queue.status
queue_ids = {amo.STATUS_UNREVIEWED: 'prelim',
amo.STATUS_NOMINATED: 'nominated',
amo.STATUS_PUBLIC: 'pending',
amo.STATUS_LITE: 'prelim',
amo.STATUS_LITE_AND_NOMINATED: 'nominated',
amo.STATUS_PENDING: 'pending'}
queue_ids = {amo.STATUS_NOMINATED: 'nominated',
amo.STATUS_PUBLIC: 'pending'}
queue = queue_ids.get(queue_id, 'queue')
@ -128,7 +112,6 @@ def editors_breadcrumbs(context, queue=None, addon_queue=None, items=None,
'queue': _('Queue'),
'pending': _('Pending Updates'),
'nominated': _('Full Reviews'),
'prelim': _('Preliminary Reviews'),
'moderated': _('Moderated Reviews'),
'pending_themes': _('Pending Themes'),
@ -140,7 +123,6 @@ def editors_breadcrumbs(context, queue=None, addon_queue=None, items=None,
'queue': _('Queue'),
'pending': _('Unlisted Pending Updates'),
'nominated': _('Unlisted Full Reviews'),
'prelim': _('Unlisted Preliminary Reviews'),
'all': _('All Unlisted Add-ons'),
}
@ -181,11 +163,6 @@ def queue_tabnav(context):
'Pending Updates ({0})',
counts['pending'])
.format(counts['pending']))),
('prelim', 'queue_prelim',
(ngettext('Preliminary Review ({0})',
'Preliminary Reviews ({0})',
counts['prelim'])
.format(counts['prelim']))),
('moderated', 'queue_moderated',
(ngettext('Moderated Review ({0})',
'Moderated Reviews ({0})',
@ -202,11 +179,6 @@ def queue_tabnav(context):
'Unlisted Pending Updates ({0})',
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',
(ngettext('All Unlisted Add-ons ({0})',
'All Unlisted Add-ons ({0})',
@ -419,12 +391,6 @@ class ViewFullReviewQueueTable(EditorQueueTable):
model = ViewFullReviewQueue
class ViewPreliminaryQueueTable(EditorQueueTable):
class Meta(EditorQueueTable.Meta):
model = ViewPreliminaryQueue
class ViewUnlistedPendingQueueTable(EditorQueueTable):
class Meta(EditorQueueTable.Meta):
@ -437,12 +403,6 @@ class ViewUnlistedFullReviewQueueTable(EditorQueueTable):
model = ViewUnlistedFullReviewQueue
class ViewUnlistedPreliminaryQueueTable(EditorQueueTable):
class Meta(EditorQueueTable.Meta):
model = ViewUnlistedPreliminaryQueue
class ViewUnlistedAllListTable(EditorAllListTable):
class Meta(EditorQueueTable.Meta):
@ -452,8 +412,6 @@ class ViewUnlistedAllListTable(EditorAllListTable):
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,
amo.STATUS_PENDING, amo.STATUS_PUBLIC)
@ -510,17 +468,9 @@ class ReviewHelper:
self.handler.set_data(data)
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.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:
self.review_type = '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
# the actions.
return actions
labels, details = self._review_actions()
reviewable_because_complete = addon.status not in (
amo.STATUS_NULL, amo.STATUS_DELETED)
reviewable_because_admin = (
@ -544,101 +493,51 @@ class ReviewHelper:
addon.latest_version.nomination is not None and
(datetime.datetime.now() - addon.latest_version.nomination >=
datetime.timedelta(hours=REVIEW_LIMITED_DELAY_HOURS))))
reviewable_because_pending = addon.latest_version is not None and (
len(addon.latest_version.is_unreviewed) > 0 or
addon.status == amo.STATUS_LITE_AND_NOMINATED)
reviewable_because_pending = (
addon.latest_version is not None and
len(addon.latest_version.is_unreviewed) > 0)
if (reviewable_because_complete and
reviewable_because_admin and
reviewable_because_submission_time and
reviewable_because_pending):
if self.review_type != 'preliminary':
if addon.is_listed:
label = _lazy('Push to public')
else:
label = _lazy('Grant full review')
actions['public'] = {'method': self.handler.process_public,
'minimal': False,
'label': label}
# An unlisted sideload add-on, which requests a full review, cannot
# be granted a preliminary review.
prelim_allowed = not waffle.flag_is_active(
request, 'no-prelim-review') and addon.is_listed
if prelim_allowed or self.review_type == 'preliminary':
actions['prelim'] = {
'method': self.handler.process_preliminary,
'label': labels['prelim'],
'minimal': False}
actions['reject'] = {'method': self.handler.process_sandbox,
'label': _lazy('Reject'),
'minimal': False}
actions['info'] = {'method': self.handler.request_information,
'label': _lazy('Request more information'),
'minimal': True}
actions['super'] = {'method': self.handler.process_super_review,
'label': _lazy('Request super-review'),
'minimal': True}
actions['comment'] = {'method': self.handler.process_comment,
'label': _lazy('Comment'),
'minimal': True}
for k, v in actions.items():
v['details'] = details.get(k)
actions['public'] = {
'method': self.handler.process_public,
'minimal': False,
'details': _lazy('This will approve, sign, and publish this '
'version. The comments will be sent to the '
'developer.'),
'label': _lazy('Approve')}
actions['reject'] = {
'method': self.handler.process_sandbox,
'label': _lazy('Reject'),
'details': _lazy('This will reject this version and remove it '
'from the queue. The comments will be sent '
'to the developer.'),
'minimal': False}
actions['info'] = {
'method': self.handler.request_information,
'label': _lazy('Request more information'),
'details': _lazy('This will request more information from the '
'developer. You will be notified when they '
'reply.'),
'minimal': True}
actions['super'] = {
'method': self.handler.process_super_review,
'label': _lazy('Request super-review'),
'details': _lazy('If you have concerns about this add-on that an '
'admin reviewer should look into, enter your '
'comments in the area below. They will not be '
'sent to the developer.'),
'minimal': True}
actions['comment'] = {
'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
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):
action = self.handler.data.get('action', '')
if not action:
@ -785,21 +684,11 @@ class ReviewBase(object):
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):
self.data = data
def process_public(self, auto_validation=False):
"""Set an addon to public."""
if self.review_type == 'preliminary':
raise AssertionError('Preliminary addons cannot be made public.')
# Sign addon.
for file_ in self.files:
sign_file(file_, settings.SIGNING_SERVER)
@ -835,13 +724,7 @@ class ReviewAddon(ReviewBase):
# Hold onto the status before we change it.
status = self.addon.status
if (not self.is_upgrade or
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_addon(status=amo.STATUS_NULL)
self.set_files(amo.STATUS_DISABLED, self.files,
hide_disabled_file=True)
@ -860,40 +743,6 @@ class ReviewAddon(ReviewBase):
if self.request:
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):
"""Give an addon super review."""
self.addon.update(admin_review=True)
@ -911,9 +760,6 @@ class ReviewFiles(ReviewBase):
def process_public(self, auto_validation=False):
"""Set an addons files to public."""
if self.review_type == 'preliminary':
raise AssertionError('Preliminary addons cannot be made public.')
# Sign addon.
for file_ in self.files:
sign_file(file_, settings.SIGNING_SERVER)
@ -966,37 +812,8 @@ class ReviewFiles(ReviewBase):
if self.request:
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):
"""Give an addon super review when preliminary."""
"""Give an addon super review."""
self.addon.update(admin_review=True)
self.notify_email('author_super_review',

Просмотреть файл

@ -201,9 +201,7 @@ class ViewFullReviewQueue(ViewQueue):
def base_query(self):
q = super(ViewFullReviewQueue, self).base_query()
q['where'].extend(['files.status <> %s' % amo.STATUS_BETA,
'addons.status IN (%s, %s)' % (
amo.STATUS_NOMINATED,
amo.STATUS_LITE_AND_NOMINATED)])
'addons.status = %s' % amo.STATUS_NOMINATED])
return q
@ -216,17 +214,6 @@ class ViewPendingQueue(ViewQueue):
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):
id = models.IntegerField()
addon_name = models.CharField(max_length=255)
@ -316,10 +303,6 @@ class ViewUnlistedPendingQueue(ViewPendingQueue):
listed = False
class ViewUnlistedPreliminaryQueue(ViewPreliminaryQueue):
listed = False
class ViewUnlistedAllList(ViewAllList):
listed = False
@ -434,9 +417,7 @@ class ReviewerScore(ModelBase):
"""
queue = ''
if status in [amo.STATUS_UNREVIEWED, amo.STATUS_LITE]:
queue = 'PRELIM'
elif status in [amo.STATUS_NOMINATED, amo.STATUS_LITE_AND_NOMINATED]:
if status == amo.STATUS_NOMINATED:
queue = 'FULL'
elif status == amo.STATUS_PUBLIC:
queue = 'UPDATE'

Просмотреть файл

@ -48,8 +48,6 @@
{{ _('Full Reviews') }} ({{ queue_counts['nominated'] }})</a></li>
<li><a href="{{ url('editors.queue_pending') }}">
{{ _('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') }}">
{{ _('Moderated Reviews') }} ({{ queue_counts['moderated'] }})</a></li>
</ul>
@ -63,8 +61,6 @@
{{ _('Full Reviews') }} ({{ unlisted_queue_counts['nominated'] }})</a></li>
<li><a href="{{ url('editors.unlisted_queue_pending') }}">
{{ _('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') }}">
{{ _('All Add-ons') }} ({{ unlisted_queue_counts['all'] }})</a></li>
</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']) }}
</a>
</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 class="editor-stats">
{% for type in ('nominated', 'pending', 'prelim'): %}
{% for type in ('nominated', 'pending'): %}
<div class="editor-stats-table">
<div class="editor-stats-dark">
<strong>{{ _('Current waiting times:') }}</strong>
@ -70,17 +63,10 @@
unlisted_queue_counts['pending'])|f(num=unlisted_queue_counts['pending']) }}
</a>
</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 class="editor-stats">
{% for type in ('nominated', 'pending', 'prelim'): %}
{% for type in ('nominated', 'pending'): %}
<div class="editor-stats-table">
<div class="editor-stats-dark">
<strong>{{ _('Current waiting times:') }}</strong>
@ -106,12 +92,12 @@
<div class="featured" id="editors-stats">
<div class="featured-inner">
<div class="listing-header">
<div class="editor-stats-title"><span>{{ _('Total Reviews') }}</span></div>
<div class="editor-stats-title"><span>{{ _('Reviews This Month') }}</span></div>
<div class="editor-stats-title"><span>{{ _('New Editors') }}</span></div>
<div class="editor-stats-title three-col"><span>{{ _('Total Reviews') }}</span></div>
<div class="editor-stats-title three-col"><span>{{ _('Reviews This Month') }}</span></div>
<div class="editor-stats-title three-col"><span>{{ _('New Editors') }}</span></div>
</div>
<div class="editor-stats">
<div class="editor-stats-table">
<div class="editor-stats-table three-col">
<div>
<table>
{% for row in reviews_total: %}
@ -126,7 +112,7 @@
<div>{{ _("You're #{0} with {1} reviews")|f(reviews_total_position, reviews_total_count) }}</div>
{% endif %}
</div>
<div class="editor-stats-table">
<div class="editor-stats-table three-col">
<div>
<table>
{% for row in reviews_monthly: %}
@ -141,7 +127,7 @@
<div>{{ _("You're #{0} with {1} reviews")|f(reviews_monthly_position, reviews_monthly_count) }}</div>
{% endif %}
</div>
<div class="editor-stats-table">
<div class="editor-stats-table three-col">
<div>
<table>
{% for editors in new_editors %}

Просмотреть файл

@ -2,13 +2,11 @@ import mock
from django.utils.encoding import force_text
from waffle.testutils import override_flag
from olympia import amo
from olympia.amo.tests import TestCase
from olympia.addons.models import Addon
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.users.models import UserProfile
@ -36,48 +34,17 @@ class TestReviewActions(TestCase):
version=self.version))
return form.helper.get_actions(self.request, self.addon)
def test_lite_nominated(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):
def test_nominated_addon(self):
self.addon.update(is_listed=False)
actions = self.set_statuses(addon_status=amo.STATUS_NOMINATED,
file_status=amo.STATUS_UNREVIEWED)
assert 'prelim' not in actions
assert actions['public']['label'] == 'Grant full review'
assert actions['public']['label'] == 'Approve'
def test_reject(self):
reject = self.set_statuses(
addon_status=amo.STATUS_UNREVIEWED,
addon_status=amo.STATUS_NOMINATED,
file_status=amo.STATUS_UNREVIEWED)['reject']['details']
assert force_text(reject).startswith('This will reject the add-on')
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
assert force_text(reject).startswith('This will reject this version')
def test_addon_status_null(self):
# 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
assert len(self.set_statuses(addon_status=amo.STATUS_PUBLIC,
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,
file_status=amo.STATUS_DISABLED)) == 3
@ -106,43 +71,12 @@ class TestReviewActions(TestCase):
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)
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,
status = self.set_statuses(addon_status=amo.STATUS_NOMINATED,
file_status=amo.STATUS_UNREVIEWED)
assert 'public' 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,
status = self.set_statuses(addon_status=amo.STATUS_NOMINATED,
file_status=amo.STATUS_UNREVIEWED)
assert 'public' not in status.keys()

Просмотреть файл

@ -9,7 +9,7 @@ from django.utils import translation
import pytest
from mock import Mock, patch
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.activity.models import ActivityLogToken
@ -24,16 +24,11 @@ from olympia.translations.models import Translation
from olympia.users.models import UserProfile
from olympia.versions.models import Version
from . test_models import create_addon_file
pytestmark = pytest.mark.django_db
REVIEW_ADDON_STATUSES = (amo.STATUS_NOMINATED, amo.STATUS_LITE_AND_NOMINATED,
amo.STATUS_UNREVIEWED)
REVIEW_FILES_STATUSES = (amo.STATUS_PUBLIC,
amo.STATUS_DISABLED, amo.STATUS_LITE)
REVIEW_FILES_STATUSES = (amo.STATUS_PUBLIC, amo.STATUS_DISABLED)
class TestViewPendingQueueTable(TestCase):
@ -256,7 +251,7 @@ class TestReviewHelper(TestCase):
def get_data(self):
return {'comments': 'foo', 'addon_files': self.version.files.all(),
'action': 'prelim', 'operating_systems': 'osx',
'action': 'public', 'operating_systems': 'osx',
'applications': 'Firefox'}
def get_helper(self):
@ -278,11 +273,6 @@ class TestReviewHelper(TestCase):
def test_type_nominated(self):
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):
assert self.setup_type(amo.STATUS_PENDING) == 'pending'
@ -302,9 +292,8 @@ class TestReviewHelper(TestCase):
assert self.helper.handler.__class__ == helpers.ReviewFiles
def test_review_addon(self):
for status in REVIEW_ADDON_STATUSES:
self.setup_data(status=status)
assert self.helper.handler.__class__ == helpers.ReviewAddon
self.setup_data(status=amo.STATUS_NOMINATED)
assert self.helper.handler.__class__ == helpers.ReviewAddon
def test_process_action_none(self):
self.helper.set_data({'action': 'foo'})
@ -338,57 +327,18 @@ class TestReviewHelper(TestCase):
for k, v in actions.items():
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):
self.file.update(status=file_status)
self.addon.update(status=addon_status)
return self.get_helper().actions
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']
assert self.get_review_actions(
addon_status=amo.STATUS_NOMINATED,
file_status=amo.STATUS_UNREVIEWED).keys() == expected
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']
assert self.get_review_actions(
addon_status=amo.STATUS_PUBLIC,
@ -396,45 +346,12 @@ class TestReviewHelper(TestCase):
def test_actions_full_nonpending(self):
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:
assert self.get_review_actions(
addon_status=amo.STATUS_PUBLIC,
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):
self.file.update(datestatuschanged=yesterday)
self.helper.set_data({'addon_files': self.version.files.all()})
@ -471,13 +388,11 @@ class TestReviewHelper(TestCase):
def test_notify_email(self):
self.helper.set_data(self.get_data())
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',
'pending_to_preliminary', 'pending_to_public',
'pending_to_sandbox', 'preliminary_to_preliminary',
'pending_to_public', 'pending_to_sandbox',
'author_super_review', 'unlisted_to_reviewed',
'unlisted_to_reviewed_auto',
'unlisted_to_sandbox']:
'unlisted_to_reviewed_auto', 'unlisted_to_sandbox'):
mail.outbox = []
self.helper.handler.notify_email(template, 'Sample subject %s, %s')
assert len(mail.outbox) == 1
@ -493,13 +408,11 @@ class TestReviewHelper(TestCase):
reply_email = (
'reviewreply+%s@%s' % (uuid, settings.INBOUND_EMAIL_DOMAIN))
for template in ['nominated_to_nominated', 'nominated_to_preliminary',
'nominated_to_public', 'nominated_to_sandbox',
'pending_to_preliminary', 'pending_to_public',
'pending_to_sandbox', 'preliminary_to_preliminary',
'author_super_review', 'unlisted_to_reviewed',
'unlisted_to_reviewed_auto',
'unlisted_to_sandbox']:
for template in ('nominated_to_nominated', 'nominated_to_public',
'nominated_to_sandbox', 'pending_to_public',
'pending_to_sandbox', 'author_super_review',
'unlisted_to_reviewed', 'unlisted_to_reviewed_auto',
'unlisted_to_sandbox'):
mail.outbox = []
self.helper.handler.notify_email(template, 'Sample subject %s, %s')
assert len(mail.outbox) == 1
@ -509,16 +422,12 @@ class TestReviewHelper(TestCase):
def test_email_links(self):
expected = {
'nominated_to_nominated': 'addon_url',
'nominated_to_preliminary': 'addon_url',
'nominated_to_public': 'addon_url',
'nominated_to_sandbox': 'dev_versions_url',
'pending_to_preliminary': 'addon_url',
'pending_to_public': 'addon_url',
'pending_to_sandbox': 'dev_versions_url',
'preliminary_to_preliminary': 'addon_url',
'unlisted_to_reviewed': 'dev_versions_url',
'unlisted_to_reviewed_auto': 'dev_versions_url',
'unlisted_to_sandbox': 'dev_versions_url'
@ -539,7 +448,9 @@ class TestReviewHelper(TestCase):
mail.outbox = []
ActivityLog.objects.for_addons(self.helper.addon).delete()
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()
data = self.get_data().copy()
for key in delete:
@ -595,23 +506,21 @@ class TestReviewHelper(TestCase):
assert 'Your add-on, Delicious Bookmarks ' in mail.outbox[0].body
def test_nomination_to_public_no_files(self):
for status in helpers.NOMINATED_STATUSES:
self.setup_data(status, ['addon_files'])
self.helper.handler.process_public()
self.setup_data(amo.STATUS_NOMINATED, ['addon_files'])
self.helper.handler.process_public()
assert self.addon.versions.all()[0].files.all()[0].status == (
amo.STATUS_PUBLIC)
assert self.addon.versions.all()[0].files.all()[0].status == (
amo.STATUS_PUBLIC)
def test_nomination_to_public_and_current_version(self):
for status in helpers.NOMINATED_STATUSES:
self.setup_data(status, ['addon_files'])
self.addon = Addon.objects.get(pk=3615)
self.addon.update(_current_version=None)
assert not self.addon.current_version
self.setup_data(amo.STATUS_NOMINATED, ['addon_files'])
self.addon = Addon.objects.get(pk=3615)
self.addon.update(_current_version=None)
assert not self.addon.current_version
self.helper.handler.process_public()
self.addon = Addon.objects.get(pk=3615)
assert self.addon.current_version
self.helper.handler.process_public()
self.addon = Addon.objects.get(pk=3615)
assert self.addon.current_version
def test_nomination_to_public_new_addon(self):
""" Make sure new add-ons can be made public (bug 637959) """
@ -643,199 +552,107 @@ class TestReviewHelper(TestCase):
@patch('olympia.editors.helpers.sign_file')
def test_nomination_to_public(self, sign_mock):
for status in helpers.NOMINATED_STATUSES:
sign_mock.reset()
self.setup_data(status)
with self.settings(SIGNING_SERVER='full'):
self.helper.handler.process_public()
sign_mock.reset()
self.setup_data(amo.STATUS_NOMINATED)
with self.settings(SIGNING_SERVER='full'):
self.helper.handler.process_public()
assert self.addon.status == amo.STATUS_PUBLIC
assert self.addon.versions.all()[0].files.all()[0].status == (
amo.STATUS_PUBLIC)
assert self.addon.status == amo.STATUS_PUBLIC
assert self.addon.versions.all()[0].files.all()[0].status == (
amo.STATUS_PUBLIC)
assert len(mail.outbox) == 1
assert mail.outbox[0].subject == (
'%s Fully Reviewed' % self.preamble)
assert 'has been fully reviewed' in mail.outbox[0].body
assert len(mail.outbox) == 1
assert mail.outbox[0].subject == (
'%s Fully Reviewed' % self.preamble)
assert 'has been fully reviewed' in mail.outbox[0].body
sign_mock.assert_called_with(self.file, 'full')
assert storage.exists(self.file.mirror_file_path)
sign_mock.assert_called_with(self.file, 'full')
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')
def test_nomination_to_public_unlisted(self, sign_mock):
for status in helpers.NOMINATED_STATUSES:
sign_mock.reset()
self.setup_data(status, is_listed=False)
with self.settings(SIGNING_SERVER='full'):
self.helper.handler.process_public()
sign_mock.reset()
self.setup_data(amo.STATUS_NOMINATED, is_listed=False)
with self.settings(SIGNING_SERVER='full'):
self.helper.handler.process_public()
assert self.addon.status == amo.STATUS_PUBLIC
assert self.addon.versions.all()[0].files.all()[0].status == (
amo.STATUS_PUBLIC)
assert self.addon.status == amo.STATUS_PUBLIC
assert self.addon.versions.all()[0].files.all()[0].status == (
amo.STATUS_PUBLIC)
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 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, 'full')
assert storage.exists(self.file.mirror_file_path)
sign_mock.assert_called_with(self.file, 'full')
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')
def test_nomination_to_public_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.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)
sign_mock.reset()
self.setup_data(amo.STATUS_NOMINATED)
with self.settings(SIGNING_SERVER='full'):
with self.assertRaises(Exception):
self.helper.handler.process_preliminary()
self.helper.handler.process_public()
# Status unchanged.
assert self.addon.status == status
assert self.addon.versions.all()[0].files.all()[0].status == status
# Status unchanged.
assert self.addon.status == amo.STATUS_NOMINATED
assert self.addon.versions.all()[0].files.all()[0].status == (
amo.STATUS_UNREVIEWED)
assert len(mail.outbox) == 0
assert self.check_log_count(amo.LOG.APPROVE_VERSION.id) == 0
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_sandbox(self, sign_mock):
for status in helpers.NOMINATED_STATUSES:
self.setup_data(status)
self.helper.handler.process_sandbox()
self.setup_data(amo.STATUS_NOMINATED)
self.helper.handler.process_sandbox()
assert self.addon.status == amo.STATUS_NULL
assert self.addon.versions.all()[0].files.all()[0].status == (
amo.STATUS_DISABLED)
assert self.addon.status == amo.STATUS_NULL
assert self.addon.versions.all()[0].files.all()[0].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 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
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_nomination_to_sandbox_unlisted(self, sign_mock):
for status in helpers.NOMINATED_STATUSES:
self.setup_data(status, is_listed=False)
self.helper.handler.process_sandbox()
self.setup_data(amo.STATUS_NOMINATED, is_listed=False)
self.helper.handler.process_sandbox()
assert self.addon.status == amo.STATUS_NULL
assert self.addon.versions.all()[0].files.all()[0].status == (
amo.STATUS_DISABLED)
assert self.addon.status == amo.STATUS_NULL
assert self.addon.versions.all()[0].files.all()[0].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 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
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_email_unicode_monster(self):
self.addon.name = u'TaobaoShopping淘宝网导航按钮'
self.addon.save()
self.setup_data(helpers.NOMINATED_STATUSES[0])
self.setup_data(amo.STATUS_NOMINATED)
self.helper.handler.process_sandbox()
assert u'TaobaoShopping淘宝网导航按钮' in mail.outbox[0].subject
@ -846,221 +663,70 @@ class TestReviewHelper(TestCase):
assert url in mail.outbox[1].body
def test_nomination_to_super_review(self):
for status in helpers.NOMINATED_STATUSES:
self.setup_data(status)
self.helper.handler.process_super_review()
self.setup_data(amo.STATUS_NOMINATED)
self.helper.handler.process_super_review()
assert self.addon.admin_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_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
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):
# Note we are changing the file status here.
for file_status in (amo.STATUS_PENDING, amo.STATUS_UNREVIEWED):
self.setup_data(amo.STATUS_LITE)
self.file.update(status=file_status)
self.helper.handler.process_super_review()
self.setup_data(amo.STATUS_NOMINATED)
self.file.update(status=amo.STATUS_UNREVIEWED)
self.helper.handler.process_super_review()
assert self.addon.admin_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 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
assert self.check_log_count(amo.LOG.REQUEST_SUPER_REVIEW.id) == 1
@patch('olympia.editors.helpers.sign_file')
def test_pending_to_public(self, sign_mock):
for status in [amo.STATUS_NOMINATED, amo.STATUS_LITE_AND_NOMINATED]:
self.setup_data(status)
self.create_paths()
self.helper.handler.process_public()
self.setup_data(amo.STATUS_NOMINATED)
self.create_paths()
self.helper.handler.process_public()
for file in self.helper.handler.data['addon_files']:
assert file.status == amo.STATUS_PUBLIC
for file in self.helper.handler.data['addon_files']:
assert file.status == amo.STATUS_PUBLIC
assert len(mail.outbox) == 1
assert mail.outbox[0].subject == (
'%s Fully Reviewed' % self.preamble)
assert 'has been fully reviewed' in mail.outbox[0].body
assert len(mail.outbox) == 1
assert mail.outbox[0].subject == (
'%s Fully Reviewed' % self.preamble)
assert 'has been fully 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.APPROVE_VERSION.id) == 1
if status == amo.STATUS_PUBLIC:
self._check_score(amo.REVIEWED_ADDON_UPDATE)
assert sign_mock.called
assert storage.exists(self.file.mirror_file_path)
assert self.check_log_count(amo.LOG.APPROVE_VERSION.id) == 1
@patch('olympia.editors.helpers.sign_file')
def test_pending_to_public_unlisted(self, sign_mock):
for status in [amo.STATUS_NOMINATED, amo.STATUS_LITE_AND_NOMINATED]:
self.setup_data(status, is_listed=False)
self.create_paths()
self.helper.handler.process_public()
self.setup_data(amo.STATUS_NOMINATED, is_listed=False)
self.create_paths()
self.helper.handler.process_public()
for file in self.helper.handler.data['addon_files']:
assert file.status == amo.STATUS_PUBLIC
for file in self.helper.handler.data['addon_files']:
assert file.status == amo.STATUS_PUBLIC
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 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.APPROVE_VERSION.id) == 1
if status == amo.STATUS_PUBLIC:
self._check_score(amo.REVIEWED_ADDON_UPDATE)
assert sign_mock.called
assert storage.exists(self.file.mirror_file_path)
assert self.check_log_count(amo.LOG.APPROVE_VERSION.id) == 1
@patch('olympia.editors.helpers.sign_file')
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 '
'Admin Review'))
def test_nominated_review_time_set(self):
for status in REVIEW_ADDON_STATUSES:
for process in ['process_sandbox', 'process_preliminary',
'process_public']:
if (status == amo.STATUS_UNREVIEWED and
process == 'process_public'):
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_nominated_review_time_set_version(self):
for process in ('process_sandbox', 'process_public'):
self.version.update(reviewed=None)
self.setup_data(amo.STATUS_NOMINATED)
getattr(self.helper.handler, process)()
assert self.version.reviewed
def test_preliminary_review_time_set(self):
for status in amo.UNDER_REVIEW_STATUSES:
for process in ['process_sandbox', 'process_preliminary']:
self.file.update(reviewed=None)
self.setup_data(status)
getattr(self.helper.handler, process)()
assert File.objects.get(pk=self.file.pk).reviewed, (
'Reviewed for status %r, %s()' % (status, process))
def test_nominated_review_time_set_file(self):
for process in ('process_sandbox', 'process_public'):
self.file.update(reviewed=None)
self.setup_data(amo.STATUS_NOMINATED)
getattr(self.helper.handler, process)()
assert File.objects.get(pk=self.file.pk).reviewed
def test_page_title_unicode():

Просмотреть файл

@ -16,8 +16,8 @@ from olympia.applications.models import AppVersion
from olympia.editors.models import (
EditorSubscription, RereviewQueueTheme, ReviewerScore, send_notifications,
ViewFullReviewQueue, ViewPendingQueue,
ViewPreliminaryQueue, ViewUnlistedAllList, ViewUnlistedFullReviewQueue,
ViewUnlistedPendingQueue, ViewUnlistedPreliminaryQueue)
ViewUnlistedAllList, ViewUnlistedFullReviewQueue,
ViewUnlistedPendingQueue)
from olympia.users.models import UserProfile
@ -233,16 +233,6 @@ class TestFullReviewQueue(TestQueue):
amo.STATUS_NOMINATED, amo.STATUS_UNREVIEWED,
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):
self.new_file(name='Addon 1', version=u'0.1')
Version.objects.update(nomination=datetime.utcnow())
@ -252,41 +242,6 @@ class TestFullReviewQueue(TestQueue):
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):
Queue = ViewUnlistedPendingQueue
listed = False
@ -297,27 +252,18 @@ class TestUnlistedFullReviewQueue(TestFullReviewQueue):
listed = False
class TestUnlistedPreliminaryQueue(TestPreliminaryQueue):
Queue = ViewUnlistedPreliminaryQueue
listed = False
class TestUnlistedAllList(TestCase):
Queue = ViewUnlistedAllList
listed = False
fixtures = ['base/users']
def new_file(self, name=u'Preliminary', version=u'1.0',
addon_status=amo.STATUS_LITE,
def new_file(self, name=u'Nominated', version=u'1.0',
addon_status=amo.STATUS_NOMINATED,
file_status=amo.STATUS_UNREVIEWED, **kw):
return create_addon_file(name, version, addon_status, file_status,
listed=self.listed, **kw)
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,
file_status=amo.STATUS_PUBLIC)
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,
file_status=amo.STATUS_PUBLIC)['addon'].delete()
assert sorted(q.addon_name for q in self.Queue.objects.all()) == (
['Deleted', 'Lite', 'Nominated', 'Public', 'Unreviewed'])
['Deleted', 'Nominated', 'Public'])
def test_authors(self):
addon = self.new_file()['addon']
@ -341,7 +287,7 @@ class TestUnlistedAllList(TestCase):
today = datetime.today().date()
self.new_file(name='addon123', version='1.0')
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))
self.new_file(name='addon123', version='3.0')
row = self.Queue.objects.all()[0]
@ -357,7 +303,7 @@ class TestUnlistedAllList(TestCase):
assert row.review_version_num is None
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))
row = self.Queue.objects.all()[0]
assert row.review_version_num == '2.0'
@ -371,7 +317,7 @@ class TestUnlistedAllList(TestCase):
def test_no_automatic_reviews(self):
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))
row = self.Queue.objects.all()[0]
assert row.review_version_num is None
@ -491,14 +437,11 @@ class TestReviewerScore(TestCase):
}
statuses = {
amo.STATUS_NULL: None,
amo.STATUS_UNREVIEWED: 'PRELIM',
amo.STATUS_PENDING: None,
amo.STATUS_NOMINATED: 'FULL',
amo.STATUS_PUBLIC: 'UPDATE',
amo.STATUS_DISABLED: None,
amo.STATUS_BETA: None,
amo.STATUS_LITE: 'PRELIM',
amo.STATUS_LITE_AND_NOMINATED: 'FULL',
amo.STATUS_DELETED: None,
amo.STATUS_REJECTED: None,
amo.STATUS_REVIEW_PENDING: None,
@ -523,16 +466,16 @@ class TestReviewerScore(TestCase):
user2 = UserProfile.objects.get(email='admin@mozilla.com')
bonus_days = 2
days = amo.REVIEWED_OVERDUE_LIMIT + bonus_days
addon_objects = create_addon_file(
bonus_addon = create_addon_file(
u'AwardBonus',
u'1.0',
amo.STATUS_NOMINATED,
amo.STATUS_UNREVIEWED,
nomination=(datetime.now() - timedelta(days=days))
)
self._give_points(user2, addon_objects['addon'], 1)
nomination=(datetime.now() - timedelta(days=days, minutes=5))
)['addon']
self._give_points(user2, bonus_addon, amo.STATUS_NOMINATED)
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))
assert score.score == expected
@ -547,11 +490,11 @@ class TestReviewerScore(TestCase):
def test_get_total(self):
user2 = UserProfile.objects.get(email='admin@mozilla.com')
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)
assert ReviewerScore.get_total(self.user) == (
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) == (
amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_FULL])
@ -559,19 +502,19 @@ class TestReviewerScore(TestCase):
user2 = UserProfile.objects.get(email='admin@mozilla.com')
self._give_points()
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)
scores = ReviewerScore.get_recent(self.user)
assert len(scores) == 2
assert scores[0].score == (
amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_PRELIM])
amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_UPDATE])
assert scores[1].score == (
amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_FULL])
def test_get_leaderboards(self):
user2 = UserProfile.objects.get(email='regular@mozilla.com')
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)
leaders = ReviewerScore.get_leaderboards(self.user)
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]['total'] == (
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]['user_id'] == user2.id
assert leaders['leader_top'][1]['total'] == (
@ -596,7 +539,7 @@ class TestReviewerScore(TestCase):
def test_no_admins_or_staff_in_leaderboards(self):
user2 = UserProfile.objects.get(email='admin@mozilla.com')
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)
leaders = ReviewerScore.get_leaderboards(self.user)
assert leaders['user_rank'] == 1
@ -626,12 +569,12 @@ class TestReviewerScore(TestCase):
user2 = UserProfile.objects.get(email='regular@mozilla.com')
amo.REVIEWED_LEVELS[0]['points'] = 180
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)
users = ReviewerScore.all_users_by_score()
assert len(users) == 2
# First user.
assert users[0]['total'] == 180
assert users[0]['total'] == 200
assert users[0]['user_id'] == self.user.id
assert users[0]['level'] == amo.REVIEWED_LEVELS[0]['name']
# Second user.

Просмотреть файл

@ -48,60 +48,15 @@ def addon_with_files(db):
('process_sandbox', amo.STATUS_NOMINATED, amo.STATUS_UNREVIEWED,
helpers.ReviewAddon, 'nominated', amo.STATUS_NULL,
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.
# scenario9: should succeed, files approved.
# scenario2: should succeed, files approved.
('process_public', amo.STATUS_PUBLIC, amo.STATUS_UNREVIEWED,
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,
helpers.ReviewFiles, 'pending', amo.STATUS_NOMINATED,
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,
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)
assert helper.review_type == review_type
helper.set_data({'comments': 'testing review scenarios'})
# Run the action (process_public, process_sandbox, process_preliminary).
# Run the action (process_public, process_sandbox).
try:
getattr(helper.handler, review_action)()
except AssertionError:

Просмотреть файл

@ -540,12 +540,10 @@ class TestHome(EditorTest):
listed_queues_links = [
reverse('editors.queue_nominated'),
reverse('editors.queue_pending'),
reverse('editors.queue_prelim'),
reverse('editors.queue_moderated')]
unlisted_queues_links = [
reverse('editors.unlisted_queue_nominated'),
reverse('editors.unlisted_queue_pending'),
reverse('editors.unlisted_queue_prelim'),
reverse('editors.unlisted_queue_all')]
# Only listed queues for editors.
@ -634,23 +632,13 @@ class QueueTest(EditorTest):
}),
('Nominated Two', {
'version_str': '0.1',
'addon_status': amo.STATUS_LITE_AND_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,
'addon_status': amo.STATUS_NOMINATED,
'file_status': amo.STATUS_UNREVIEWED,
}),
('Public', {
'version_str': '0.1',
'addon_status': amo.STATUS_PUBLIC,
'file_status': amo.STATUS_LITE,
'file_status': amo.STATUS_PUBLIC,
}),
])
results = SortedDict()
@ -819,7 +807,7 @@ class TestQueueBasics(QueueTest):
doc = pq(r.content)
assert doc('#navbar li.top ul').eq(0).text() == (
'Full Reviews (2) Pending Updates (2) '
'Preliminary Reviews (2) Moderated Reviews (0)')
'Moderated Reviews (0)')
def test_legacy_queue_sort(self):
sorts = (
@ -846,13 +834,6 @@ class TestQueueBasics(QueueTest):
for data in self.get_review_data():
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):
# `eq` is the table number (0, 1 or 2).
def style(w):
@ -985,8 +966,7 @@ class TestUnlistedQueueBasics(TestQueueBasics):
assert r.status_code == 200
doc = pq(r.content)
assert doc('#navbar li.top ul').eq(1).text() == (
'Full Reviews (2) Pending Updates (2) Preliminary Reviews (2) '
'All Add-ons (7)')
'Full Reviews (2) Pending Updates (2) All Add-ons (5)')
def test_listed_unlisted_queues(self):
# Make sure the listed addons are displayed in the listed queue, and
@ -1092,28 +1072,6 @@ class TestNominatedQueue(QueueTest):
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):
fixtures = ['base/users', 'reviews/dev-reply']
@ -1246,7 +1204,7 @@ class TestModeratedQueue(QueueTest):
note_key=amo.REVIEWED_ADDON_REVIEW).count() == 1
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):
self._test_breadcrumbs([('Moderated Reviews', None)])
@ -1314,22 +1272,6 @@ class TestUnlistedNominatedQueue(TestNominatedQueue):
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):
listed = False
@ -1339,7 +1281,7 @@ class TestUnlistedAllList(QueueTest):
# We should have all add-ons.
self.expected_addons = self.get_expected_addons_by_names(
['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.
for idx, addon in enumerate(self.expected_addons):
addon.latest_version.update(
@ -1349,14 +1291,14 @@ class TestUnlistedAllList(QueueTest):
self._test_breadcrumbs([('All Unlisted Add-ons', None)])
def test_queue_count(self):
assert Addon.with_unlisted.all().count() == 7
self._test_queue_count(3, 'All Unlisted Add-ons', 7)
assert Addon.with_unlisted.all().count() == 5
self._test_queue_count(2, 'All Unlisted Add-ons', 5)
def test_results(self):
self._test_results()
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],
user=UserProfile.objects.get(pk=999),
@ -1879,11 +1821,11 @@ class TestQueueSearchVersionSpecific(SearchTest):
def setUp(self):
super(TestQueueSearchVersionSpecific, self).setUp()
self.url = reverse('editors.queue_prelim')
self.url = reverse('editors.queue_nominated')
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',
amo.STATUS_LITE, amo.STATUS_UNREVIEWED,
amo.STATUS_NOMINATED, amo.STATUS_UNREVIEWED,
addon_type=amo.ADDON_THEME)
self.bieber = Version.objects.filter(
addon__name__localized_string='Justin Bieber Theme')
@ -2104,7 +2046,7 @@ class TestReview(ReviewBase):
for idx in xrange(comments.length):
td = comments.eq(idx)
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
def generate_deleted_versions(self):
@ -2114,7 +2056,7 @@ class TestReview(ReviewBase):
versions = ({'version': '0.1', 'action': 'comment',
'comments': 'millenium hand and shrimp'},
{'version': '0.1', 'action': 'prelim',
{'version': '0.1', 'action': 'public',
'comments': 'buggrit'},
{'version': '0.2', 'action': 'comment',
'comments': 'I told em'},
@ -2199,7 +2141,7 @@ class TestReview(ReviewBase):
def test_item_history_header(self):
doc = pq(self.client.get(self.url).content)
assert ('Preliminarily Reviewed' in
assert ('Reviewed' in
doc('#review-files .listing-header .light').text())
def test_item_history_comment(self):
@ -2331,16 +2273,8 @@ class TestReview(ReviewBase):
assert Addon.objects.get(pk=self.addon.pk).admin_review
def test_no_public(self):
s = amo.STATUS_PUBLIC
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()
has_public = self.version.files.filter(
status=amo.STATUS_PUBLIC).exists()
assert has_public
response = self.client.get(self.url)
@ -2427,7 +2361,7 @@ class TestReview(ReviewBase):
@patch('olympia.editors.helpers.sign_file')
def review_version(self, version, url, mock_sign):
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')
self.client.post(url, data)
@ -2468,16 +2402,12 @@ class TestReview(ReviewBase):
self.assertContains(r, 'View Privacy Policy')
def test_breadcrumbs_all(self):
queues = {'Full Reviews': [amo.STATUS_NOMINATED,
amo.STATUS_LITE_AND_NOMINATED],
'Preliminary Reviews': [amo.STATUS_UNREVIEWED,
amo.STATUS_LITE],
'Pending Updates': [amo.STATUS_PENDING, amo.STATUS_PUBLIC]}
for text, queue_ids in queues.items():
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
queues = {'Full Reviews': amo.STATUS_NOMINATED,
'Pending Updates': amo.STATUS_PUBLIC}
for text, queue_id in queues.items():
self.addon.update(status=queue_id)
doc = pq(self.client.get(self.url).content)
assert doc('#breadcrumbs li').eq(1).text() == text
def test_viewing(self):
url = reverse('editors.review_viewing')
@ -2739,61 +2669,6 @@ class TestReview(ReviewBase):
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):
def setUp(self):
@ -2809,7 +2684,7 @@ class TestReviewPending(ReviewBase):
def test_pending_to_public(self, mock_sign):
statuses = (self.version.files.values_list('status', flat=True)
.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())
assert self.get_addon().status == amo.STATUS_PUBLIC
@ -2817,7 +2692,7 @@ class TestReviewPending(ReviewBase):
statuses = (self.version.files.values_list('status', flat=True)
.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
@ -2826,7 +2701,7 @@ class TestReviewPending(ReviewBase):
self.addon.update(is_listed=False)
statuses = (self.version.files.values_list('status', flat=True)
.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()
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)
.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
@ -2948,29 +2823,16 @@ class TestStatusFile(ReviewBase):
r = self.client.get(self.url)
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):
self.get_file().update(status=amo.STATUS_UNREVIEWED)
for status in [amo.STATUS_NOMINATED, amo.STATUS_PUBLIC]:
self.addon.update(status=status)
self.check_status('Pending Full 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')
self.check_status('Awaiting Review')
def test_status_full_reviewed(self):
self.get_file().update(status=amo.STATUS_PUBLIC)
for status in set(amo.UNDER_REVIEW_STATUSES + amo.LITE_STATUSES):
self.addon.update(status=status)
self.check_status('Fully Reviewed')
self.addon.update(status=amo.STATUS_PUBLIC)
self.check_status('Fully Reviewed')
def test_other(self):
self.addon.update(status=amo.STATUS_BETA)

Просмотреть файл

@ -12,8 +12,6 @@ urlpatterns = (
name='editors.queue_nominated'),
url(r'^queue/pending$', views.queue_pending,
name='editors.queue_pending'),
url(r'^queue/preliminary$', views.queue_prelim,
name='editors.queue_prelim'),
url(r'^queue/reviews$', views.queue_moderated,
name='editors.queue_moderated'),
url(r'^queue/application_versions\.json$', views.application_versions_json,
@ -24,8 +22,6 @@ urlpatterns = (
name='editors.unlisted_queue_nominated'),
url(r'^unlisted_queue/pending$', views.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,
name='editors.unlisted_queue_all'),
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.models import (
AddonCannedResponse, EditorSubscription, EventLog, PerformanceGraph,
ReviewerScore, ViewFullReviewQueue, ViewPendingQueue,
ViewPreliminaryQueue, ViewQueue, ViewUnlistedAllList,
ViewUnlistedFullReviewQueue,
ViewUnlistedPendingQueue, ViewUnlistedPreliminaryQueue)
ReviewerScore, ViewFullReviewQueue, ViewPendingQueue, ViewQueue,
ViewUnlistedAllList, ViewUnlistedFullReviewQueue, ViewUnlistedPendingQueue)
from olympia.editors.helpers import (
is_limited_reviewer, ReviewHelper, ViewFullReviewQueueTable,
ViewPendingQueueTable, ViewPreliminaryQueueTable, ViewUnlistedAllListTable,
ViewUnlistedFullReviewQueueTable, ViewUnlistedPendingQueueTable,
ViewUnlistedPreliminaryQueueTable)
ViewPendingQueueTable, ViewUnlistedAllListTable,
ViewUnlistedFullReviewQueueTable, ViewUnlistedPendingQueueTable)
from olympia.reviews.forms import ReviewFlagFormSet
from olympia.reviews.models import Review, ReviewFlag
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
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,
admin_reviewer=True,
limited_reviewer=limited_reviewer),
@ -462,7 +459,6 @@ def queue_counts(type=None, unlisted=False, admin_reviewer=False,
counts = {'pending': construct_query(ViewPendingQueue, **kw),
'nominated': construct_query(ViewFullReviewQueue, **kw),
'prelim': construct_query(ViewPreliminaryQueue, **kw),
'moderated': (
Review.objects.filter(reviewflag__isnull=False,
editorreview=1).count)}
@ -470,7 +466,6 @@ def queue_counts(type=None, unlisted=False, admin_reviewer=False,
counts = {
'pending': construct_query(ViewUnlistedPendingQueue, **kw),
'nominated': construct_query(ViewUnlistedFullReviewQueue, **kw),
'prelim': construct_query(ViewUnlistedPreliminaryQueue, **kw),
'all': (ViewUnlistedAllList.objects if admin_reviewer
else exclude_admin_only_addons(
ViewUnlistedAllList.objects)).count}
@ -498,11 +493,6 @@ def queue_pending(request):
return _queue(request, ViewPendingQueueTable, 'pending')
@addons_reviewer_required
def queue_prelim(request):
return _queue(request, ViewPreliminaryQueueTable, 'prelim')
@addons_reviewer_required
def queue_moderated(request):
# In addition to other checks, this only show reviews for public and
@ -558,12 +548,6 @@ def unlisted_queue_pending(request):
unlisted=True)
@unlisted_addons_reviewer_required
def unlisted_queue_prelim(request):
return _queue(request, ViewUnlistedPreliminaryQueueTable, 'prelim',
unlisted=True)
@addons_reviewer_required
@post_required
@json_view
@ -587,8 +571,7 @@ def review(request, addon):
form_helper = ReviewHelper(request=request, addon=addon, version=version)
form = forms.ReviewForm(request.POST or None, helper=form_helper)
queue_type = ('prelim' if form.helper.review_type == 'preliminary'
else form.helper.review_type)
queue_type = form.helper.review_type
if addon.is_listed:
redirect_url = reverse('editors.queue_%s' % queue_type)
else:
@ -619,14 +602,11 @@ def review(request, addon):
canned = AddonCannedResponse.objects.all()
actions = form.helper.actions.items()
statuses = [amo.STATUS_PUBLIC, amo.STATUS_LITE,
amo.STATUS_LITE_AND_NOMINATED]
try:
show_diff = version and (
addon.versions.exclude(id=version.id).filter(
files__isnull=False, created__lt=version.created,
files__status__in=statuses).latest())
files__status=amo.STATUS_PUBLIC).latest())
except Version.DoesNotExist:
show_diff = None
@ -832,6 +812,7 @@ def reviewlog(request):
pager = amo.utils.paginate(request, approvals, 50)
ad = {
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.REJECT_VERSION.id: _('rejected'),
amo.LOG.ESCALATE_VERSION.id: pgettext(

Просмотреть файл

@ -278,20 +278,15 @@ class Version(OnChangeMixin, ModelBase):
def current_queue(self):
"""Return the current queue, or None if not in a queue."""
from olympia.editors.models import (
ViewFullReviewQueue, ViewPendingQueue, ViewPreliminaryQueue,
ViewUnlistedFullReviewQueue, ViewUnlistedPendingQueue,
ViewUnlistedPreliminaryQueue)
ViewFullReviewQueue, ViewPendingQueue,
ViewUnlistedFullReviewQueue, ViewUnlistedPendingQueue)
if self.addon.status in [amo.STATUS_NOMINATED,
amo.STATUS_LITE_AND_NOMINATED]:
if self.addon.status == amo.STATUS_NOMINATED:
return (ViewFullReviewQueue if self.addon.is_listed
else ViewUnlistedFullReviewQueue)
elif self.addon.status == amo.STATUS_PUBLIC:
return (ViewPendingQueue if self.addon.is_listed
else ViewUnlistedPendingQueue)
elif self.addon.status in [amo.STATUS_LITE, amo.STATUS_UNREVIEWED]:
return (ViewPreliminaryQueue if self.addon.is_listed
else ViewUnlistedPreliminaryQueue)
return None

Просмотреть файл

@ -28,9 +28,8 @@ from olympia.addons.tests.test_views import TestMobile
from olympia.applications.models import AppVersion
from olympia.devhub.models import ActivityLog
from olympia.editors.models import (
ViewFullReviewQueue, ViewPendingQueue, ViewPreliminaryQueue,
ViewUnlistedFullReviewQueue, ViewUnlistedPendingQueue,
ViewUnlistedPreliminaryQueue)
ViewFullReviewQueue, ViewPendingQueue,
ViewUnlistedFullReviewQueue, ViewUnlistedPendingQueue,)
from olympia.files.models import File
from olympia.files.tests.test_models import UploadTest
from olympia.users.models import UserProfile
@ -511,27 +510,22 @@ class TestVersion(TestCase):
def test_current_queue(self):
queue_to_status = {
ViewFullReviewQueue: [amo.STATUS_NOMINATED,
amo.STATUS_LITE_AND_NOMINATED],
ViewPendingQueue: [amo.STATUS_PUBLIC],
ViewPreliminaryQueue: [amo.STATUS_LITE, amo.STATUS_UNREVIEWED]}
ViewFullReviewQueue: amo.STATUS_NOMINATED,
ViewPendingQueue: amo.STATUS_PUBLIC
}
unlisted_queue_to_status = {
ViewUnlistedFullReviewQueue: [amo.STATUS_NOMINATED,
amo.STATUS_LITE_AND_NOMINATED],
ViewUnlistedPendingQueue: [amo.STATUS_PUBLIC],
ViewUnlistedPreliminaryQueue: [amo.STATUS_LITE,
amo.STATUS_UNREVIEWED]}
ViewUnlistedFullReviewQueue: amo.STATUS_NOMINATED,
ViewUnlistedPendingQueue: amo.STATUS_PUBLIC,
}
for queue, statuses in queue_to_status.iteritems(): # Listed queues.
for status in statuses:
self.version.addon.update(status=status)
assert self.version.current_queue == queue
for queue, status in queue_to_status.iteritems(): # Listed queues.
self.version.addon.update(status=status)
assert self.version.current_queue == queue
self.version.addon.update(is_listed=False) # Unlisted queues.
for queue, statuses in unlisted_queue_to_status.iteritems():
for status in statuses:
self.version.addon.update(status=status)
assert self.version.current_queue == queue
for queue, status in unlisted_queue_to_status.iteritems():
self.version.addon.update(status=status)
assert self.version.current_queue == queue
def test_get_url_path(self):
assert self.version.get_url_path() == (

Просмотреть файл

@ -272,10 +272,15 @@ ul.tabnav a:hover {
.editor-stats-title,
.editor-stats-table {
width: 33.3333%;
width: 50%;
float: left;
}
.editor-stats-title.three-col,
.editor-stats-table.three-col {
width: 33.333333%;
}
.editor-stats-title span,
.editor-stats-title a {
font-weight: bold;