Merge pull request #3494 from eviljeff/i3088-clean-up-preliminary-review
bye bye preliminary - devhub
This commit is contained in:
Коммит
f73d224ff6
|
@ -630,11 +630,6 @@ class Addon(OnChangeMixin, ModelBase):
|
||||||
# with on a file-by-file basis.
|
# with on a file-by-file basis.
|
||||||
return not self.is_listed
|
return not self.is_listed
|
||||||
|
|
||||||
@property
|
|
||||||
def is_sideload(self):
|
|
||||||
# An add-on can side-load if it has been fully reviewed.
|
|
||||||
return self.status in (amo.STATUS_NOMINATED, amo.STATUS_PUBLIC)
|
|
||||||
|
|
||||||
@amo.cached_property(writable=True)
|
@amo.cached_property(writable=True)
|
||||||
def listed_authors(self):
|
def listed_authors(self):
|
||||||
return UserProfile.objects.filter(
|
return UserProfile.objects.filter(
|
||||||
|
|
|
@ -11,7 +11,6 @@ from django.utils.safestring import mark_safe
|
||||||
from django.utils.translation import ugettext as _, ugettext_lazy as _lazy
|
from django.utils.translation import ugettext as _, ugettext_lazy as _lazy
|
||||||
|
|
||||||
import commonware
|
import commonware
|
||||||
import waffle
|
|
||||||
from quieter_formset.formset import BaseModelFormSet
|
from quieter_formset.formset import BaseModelFormSet
|
||||||
|
|
||||||
from olympia.access import acl
|
from olympia.access import acl
|
||||||
|
@ -538,15 +537,6 @@ class NewAddonForm(AddonUploadForm):
|
||||||
help_text=_lazy(
|
help_text=_lazy(
|
||||||
u'Check this option if you intend to distribute your add-on on '
|
u'Check this option if you intend to distribute your add-on on '
|
||||||
u'your own and only need it to be signed by Mozilla.'))
|
u'your own and only need it to be signed by Mozilla.'))
|
||||||
is_sideload = forms.BooleanField(
|
|
||||||
initial=False,
|
|
||||||
required=False,
|
|
||||||
label=_lazy(u'This add-on will be bundled with an application '
|
|
||||||
u'installer.'),
|
|
||||||
help_text=_lazy(u'Add-ons that are bundled with application '
|
|
||||||
u'installers will be code reviewed '
|
|
||||||
u'by Mozilla before they are signed and are held to a '
|
|
||||||
u'higher quality standard.'))
|
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
if not self.errors:
|
if not self.errors:
|
||||||
|
@ -557,16 +547,6 @@ class NewAddonForm(AddonUploadForm):
|
||||||
|
|
||||||
|
|
||||||
class NewVersionForm(NewAddonForm):
|
class NewVersionForm(NewAddonForm):
|
||||||
nomination_type = forms.TypedChoiceField(
|
|
||||||
choices=(
|
|
||||||
('', ''),
|
|
||||||
(amo.STATUS_NOMINATED, _lazy('Full Review')),
|
|
||||||
(amo.STATUS_UNREVIEWED, _lazy('Preliminary Review')),
|
|
||||||
),
|
|
||||||
coerce=int, empty_value=None, required=False,
|
|
||||||
error_messages={
|
|
||||||
'required': _lazy(u'Please choose a review nomination type')
|
|
||||||
})
|
|
||||||
beta = forms.BooleanField(
|
beta = forms.BooleanField(
|
||||||
required=False,
|
required=False,
|
||||||
help_text=_lazy(u'A file with a version ending with '
|
help_text=_lazy(u'A file with a version ending with '
|
||||||
|
@ -576,9 +556,6 @@ class NewVersionForm(NewAddonForm):
|
||||||
def __init__(self, *args, **kw):
|
def __init__(self, *args, **kw):
|
||||||
self.addon = kw.pop('addon')
|
self.addon = kw.pop('addon')
|
||||||
super(NewVersionForm, self).__init__(*args, **kw)
|
super(NewVersionForm, self).__init__(*args, **kw)
|
||||||
if (not waffle.flag_is_active(self.request, 'no-prelim-review') and
|
|
||||||
self.addon.status == amo.STATUS_NULL):
|
|
||||||
self.fields['nomination_type'].required = True
|
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
if not self.errors:
|
if not self.errors:
|
||||||
|
@ -697,15 +674,6 @@ FileFormSet = modelformset_factory(File, formset=BaseFileFormSet,
|
||||||
form=FileForm, can_delete=True, extra=0)
|
form=FileForm, can_delete=True, extra=0)
|
||||||
|
|
||||||
|
|
||||||
class ReviewTypeForm(forms.Form):
|
|
||||||
_choices = [(k, Addon.STATUS_CHOICES[k]) for k in
|
|
||||||
(amo.STATUS_UNREVIEWED, amo.STATUS_NOMINATED)]
|
|
||||||
review_type = forms.TypedChoiceField(
|
|
||||||
choices=_choices, widget=forms.HiddenInput,
|
|
||||||
coerce=int, empty_value=None,
|
|
||||||
error_messages={'required': _lazy(u'A review type must be selected.')})
|
|
||||||
|
|
||||||
|
|
||||||
class Step3Form(AddonFormBasic):
|
class Step3Form(AddonFormBasic):
|
||||||
description = TransField(widget=TransTextarea, required=False)
|
description = TransField(widget=TransTextarea, required=False)
|
||||||
tags = None
|
tags = None
|
||||||
|
|
|
@ -12,7 +12,6 @@ from olympia.amo.urlresolvers import reverse
|
||||||
from olympia.amo.helpers import breadcrumbs, impala_breadcrumbs, page_title
|
from olympia.amo.helpers import breadcrumbs, impala_breadcrumbs, page_title
|
||||||
from olympia.access import acl
|
from olympia.access import acl
|
||||||
from olympia.addons.helpers import new_context
|
from olympia.addons.helpers import new_context
|
||||||
from olympia.addons.models import Addon
|
|
||||||
from olympia.devhub.models import ActivityLog
|
from olympia.devhub.models import ActivityLog
|
||||||
from olympia.compat.models import CompatReport
|
from olympia.compat.models import CompatReport
|
||||||
from olympia.files.models import File
|
from olympia.files.models import File
|
||||||
|
@ -124,26 +123,9 @@ def source_form_field(field):
|
||||||
return {'field': field}
|
return {'field': field}
|
||||||
|
|
||||||
|
|
||||||
@register.function
|
|
||||||
def status_choices(addon):
|
|
||||||
"""
|
|
||||||
Return a dict like File.STATUS_CHOICES customized for the addon status.
|
|
||||||
"""
|
|
||||||
# Show "awaiting full review" for unreviewed files on that track.
|
|
||||||
choices = dict(File.STATUS_CHOICES)
|
|
||||||
if addon.status in (amo.STATUS_NOMINATED, amo.STATUS_LITE_AND_NOMINATED,
|
|
||||||
amo.STATUS_PUBLIC):
|
|
||||||
choices[amo.STATUS_UNREVIEWED] = (
|
|
||||||
Addon.STATUS_CHOICES[amo.STATUS_NOMINATED])
|
|
||||||
elif addon.status in (amo.STATUS_UNREVIEWED, amo.STATUS_LITE):
|
|
||||||
choices[amo.STATUS_UNREVIEWED] = (
|
|
||||||
Addon.STATUS_CHOICES[amo.STATUS_UNREVIEWED])
|
|
||||||
return choices
|
|
||||||
|
|
||||||
|
|
||||||
@register.inclusion_tag('devhub/versions/file_status_message.html')
|
@register.inclusion_tag('devhub/versions/file_status_message.html')
|
||||||
def file_status_message(file, addon):
|
def file_status_message(file):
|
||||||
choices = status_choices(addon)
|
choices = File.STATUS_CHOICES
|
||||||
return {'fileid': file.id, 'platform': file.get_platform_display(),
|
return {'fileid': file.id, 'platform': file.get_platform_display(),
|
||||||
'created': datetime(file.created),
|
'created': datetime(file.created),
|
||||||
'status': choices[file.status],
|
'status': choices[file.status],
|
||||||
|
@ -152,10 +134,10 @@ def file_status_message(file, addon):
|
||||||
|
|
||||||
|
|
||||||
@register.function
|
@register.function
|
||||||
def dev_files_status(files, addon):
|
def dev_files_status(files):
|
||||||
"""Group files by their status (and files per status)."""
|
"""Group files by their status (and files per status)."""
|
||||||
status_count = defaultdict(int)
|
status_count = defaultdict(int)
|
||||||
choices = status_choices(addon)
|
choices = File.STATUS_CHOICES
|
||||||
|
|
||||||
for file in files:
|
for file in files:
|
||||||
status_count[file.status] += 1
|
status_count[file.status] += 1
|
||||||
|
@ -168,12 +150,9 @@ def dev_files_status(files, addon):
|
||||||
def status_class(addon):
|
def status_class(addon):
|
||||||
classes = {
|
classes = {
|
||||||
amo.STATUS_NULL: 'incomplete',
|
amo.STATUS_NULL: 'incomplete',
|
||||||
amo.STATUS_UNREVIEWED: 'unreviewed',
|
|
||||||
amo.STATUS_NOMINATED: 'nominated',
|
amo.STATUS_NOMINATED: 'nominated',
|
||||||
amo.STATUS_PUBLIC: 'fully-approved',
|
amo.STATUS_PUBLIC: 'fully-approved',
|
||||||
amo.STATUS_DISABLED: 'admin-disabled',
|
amo.STATUS_DISABLED: 'admin-disabled',
|
||||||
amo.STATUS_LITE: 'lite',
|
|
||||||
amo.STATUS_LITE_AND_NOMINATED: 'lite-nom',
|
|
||||||
amo.STATUS_DELETED: 'deleted',
|
amo.STATUS_DELETED: 'deleted',
|
||||||
amo.STATUS_REJECTED: 'rejected',
|
amo.STATUS_REJECTED: 'rejected',
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,31 +62,25 @@ def validate(file_, listed=None, subtask=None):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def validate_and_submit(addon, file_, listed=None,
|
def validate_and_submit(addon, file_, listed=None):
|
||||||
disallow_preliminary_review=False):
|
|
||||||
return validate(
|
return validate(
|
||||||
file_, listed=listed, subtask=submit_file.si(
|
file_, listed=listed, subtask=submit_file.si(addon.pk, file_.pk))
|
||||||
addon.pk, file_.pk,
|
|
||||||
disallow_preliminary_review=disallow_preliminary_review))
|
|
||||||
|
|
||||||
|
|
||||||
@task
|
@task
|
||||||
@write
|
@write
|
||||||
def submit_file(addon_pk, upload_pk, disallow_preliminary_review=False):
|
def submit_file(addon_pk, upload_pk):
|
||||||
addon = Addon.unfiltered.get(pk=addon_pk)
|
addon = Addon.unfiltered.get(pk=addon_pk)
|
||||||
upload = FileUpload.objects.get(pk=upload_pk)
|
upload = FileUpload.objects.get(pk=upload_pk)
|
||||||
if upload.passed_all_validations:
|
if upload.passed_all_validations:
|
||||||
create_version_for_upload(
|
create_version_for_upload(addon, upload)
|
||||||
addon, upload,
|
|
||||||
disallow_preliminary_review=disallow_preliminary_review)
|
|
||||||
else:
|
else:
|
||||||
log.info('Skipping version creation for {upload_uuid} that failed '
|
log.info('Skipping version creation for {upload_uuid} that failed '
|
||||||
'validation'.format(upload_uuid=upload.uuid))
|
'validation'.format(upload_uuid=upload.uuid))
|
||||||
|
|
||||||
|
|
||||||
@atomic
|
@atomic
|
||||||
def create_version_for_upload(addon, upload,
|
def create_version_for_upload(addon, upload):
|
||||||
disallow_preliminary_review=False):
|
|
||||||
fileupload_exists = addon.fileupload_set.filter(
|
fileupload_exists = addon.fileupload_set.filter(
|
||||||
created__gt=upload.created, version=upload.version).exists()
|
created__gt=upload.created, version=upload.version).exists()
|
||||||
version_exists = Version.unfiltered.filter(
|
version_exists = Version.unfiltered.filter(
|
||||||
|
@ -106,13 +100,8 @@ def create_version_for_upload(addon, upload,
|
||||||
# The add-on's status will be STATUS_NULL when its first version is
|
# The add-on's status will be STATUS_NULL when its first version is
|
||||||
# created because the version has no files when it gets added and it
|
# created because the version has no files when it gets added and it
|
||||||
# gets flagged as invalid. We need to manually set the status.
|
# gets flagged as invalid. We need to manually set the status.
|
||||||
# TODO: Handle sideload add-ons. This assumes the user wants a prelim
|
|
||||||
# review since listed and sideload aren't supported for creation yet.
|
|
||||||
if addon.status == amo.STATUS_NULL:
|
if addon.status == amo.STATUS_NULL:
|
||||||
if disallow_preliminary_review:
|
addon.update(status=amo.STATUS_NOMINATED)
|
||||||
addon.update(status=amo.STATUS_NOMINATED)
|
|
||||||
else:
|
|
||||||
addon.update(status=amo.STATUS_LITE)
|
|
||||||
auto_sign_version(version, is_beta=version.is_beta)
|
auto_sign_version(version, is_beta=version.is_beta)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,6 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% if waffle.flag('no-prelim-review') %}
|
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
{{ tip(_("Experimental?"),
|
{{ tip(_("Experimental?"),
|
||||||
|
@ -81,7 +80,6 @@
|
||||||
_("This add-on is ready for general use.")) }}
|
_("This add-on is ready for general use.")) }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endif %}
|
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
{{ tip(_("Categories"),
|
{{ tip(_("Categories"),
|
||||||
|
|
|
@ -46,7 +46,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if addon.is_listed %}
|
{% if addon.is_listed %}
|
||||||
{% if waffle.flag('no-prelim-review') %}
|
|
||||||
<div class="addon-submission-field">
|
<div class="addon-submission-field">
|
||||||
<label for="{{ form.is_experimental.auto_id }}">
|
<label for="{{ form.is_experimental.auto_id }}">
|
||||||
{{ form.is_experimental }}
|
{{ form.is_experimental }}
|
||||||
|
@ -59,7 +58,6 @@
|
||||||
}}">?</span>
|
}}">?</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
|
||||||
<div id="addon-categories-edit" class="addon-submission-field"
|
<div id="addon-categories-edit" class="addon-submission-field"
|
||||||
data-max-categories="{{ amo.MAX_CATEGORIES }}">
|
data-max-categories="{{ amo.MAX_CATEGORIES }}">
|
||||||
{{ cat_form.non_form_errors() }}
|
{{ cat_form.non_form_errors() }}
|
||||||
|
|
|
@ -8,9 +8,7 @@
|
||||||
<h3>{{ _("You're done!") }}</h3>
|
<h3>{{ _("You're done!") }}</h3>
|
||||||
{% if addon.is_listed %}
|
{% if addon.is_listed %}
|
||||||
<p>
|
<p>
|
||||||
{% if addon.status == amo.STATUS_UNREVIEWED %}
|
{% if addon.status == amo.STATUS_NOMINATED %}
|
||||||
{{ _('Your add-on has been submitted to the Preliminary Review queue.') }}
|
|
||||||
{% elif addon.status == amo.STATUS_NOMINATED %}
|
|
||||||
{{ _('Your add-on has been submitted to the Full Review queue.') }}
|
{{ _('Your add-on has been submitted to the Full Review queue.') }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</p>
|
</p>
|
||||||
|
@ -47,7 +45,7 @@
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
{% set signed = addon.status in [amo.STATUS_PUBLIC, amo.STATUS_LITE] %}
|
{% set signed = addon.status == amo.STATUS_PUBLIC %}
|
||||||
{% if signed %}
|
{% if signed %}
|
||||||
<p>
|
<p>
|
||||||
{{ _('Your add-on has been signed and it\'s ready to use. You can download it here:') }}
|
{{ _('Your add-on has been signed and it\'s ready to use. You can download it here:') }}
|
||||||
|
@ -59,9 +57,7 @@
|
||||||
</p>
|
</p>
|
||||||
{% else %}
|
{% else %}
|
||||||
<p>
|
<p>
|
||||||
{% if addon.status == amo.STATUS_UNREVIEWED %}
|
{% if addon.status == amo.STATUS_NOMINATED %}
|
||||||
{{ _('Your add-on has been submitted to the Unlisted Preliminary Review queue.') }}
|
|
||||||
{% elif addon.status == amo.STATUS_NOMINATED %}
|
|
||||||
{{ _('Your add-on has been submitted to the Unlisted Full Review queue.') }}
|
{{ _('Your add-on has been submitted to the Unlisted Full Review queue.') }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -1,68 +0,0 @@
|
||||||
{% extends "devhub/addons/submit/base.html" %}
|
|
||||||
|
|
||||||
{% set learn_more_url = 'https://developer.mozilla.org/en-US/Add-ons/AMO/Policy/Reviews' %}
|
|
||||||
|
|
||||||
{% block title %}{{ dev_page_title(_('Step 6'), addon) }}{% endblock %}
|
|
||||||
|
|
||||||
{% block primary %}
|
|
||||||
<h3>{{ _('Step 6. Select a Review Process') }}</h3>
|
|
||||||
<p>
|
|
||||||
{% trans %}
|
|
||||||
All add-ons hosted in our gallery must be reviewed by an editor before
|
|
||||||
they appear in categories or search results. While waiting for review,
|
|
||||||
your add-on can still be accessed through its direct URL. Please choose
|
|
||||||
the review process below that best fits your add-on.
|
|
||||||
{% endtrans %}
|
|
||||||
</p>
|
|
||||||
<form class="select-review" method="post">
|
|
||||||
{{ csrf() }}
|
|
||||||
{{ review_type_form.non_field_errors() }}
|
|
||||||
{{ review_type_form.review_type }}
|
|
||||||
{{ review_type_form.review_type.errors }}
|
|
||||||
<div class="review-type">
|
|
||||||
<div class="highlight">
|
|
||||||
<h4>{{ _('Full Review') }}</h4>
|
|
||||||
<p>
|
|
||||||
{% trans url=learn_more_url %}
|
|
||||||
A complete review of your add-on's source and functionality.
|
|
||||||
<a href="{{ url }}">Learn more…</a>
|
|
||||||
{% endtrans %}
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li>{{ _('Appropriate for polished add-ons') }}</li>
|
|
||||||
<li>{{ _('Required if add-on is bundled in an installer') }}</li>
|
|
||||||
<li>{{ _('Review should take place within 10 days') }}</li>
|
|
||||||
<li>{{ _('Review of subsequent versions within 5 days') }}</li>
|
|
||||||
<li>{{ _('Warning-free installation and no feature limitations') }}</li>
|
|
||||||
</ul>
|
|
||||||
<p class="submit-buttons">
|
|
||||||
<button type="submit" name="review_type" value="{{ amo.STATUS_NOMINATED }}">
|
|
||||||
{{ _('Choose Full Review') }}
|
|
||||||
</button>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="review-type">
|
|
||||||
<div class="highlight">
|
|
||||||
<h4>{{ _('Preliminary Review') }}</h4>
|
|
||||||
<p>
|
|
||||||
{% trans url=learn_more_url %}
|
|
||||||
A faster review of your add-on's source for any major problems.
|
|
||||||
<a href="{{ url }}">Learn more…</a>
|
|
||||||
{% endtrans %}
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li>{{ _('Appropriate for experimental add-ons') }}</li>
|
|
||||||
<li>{{ _('Review should take place within 3 days') }}</li>
|
|
||||||
<li>{{ _('Some feature limitations') }}</li>
|
|
||||||
<li>{{ _('Binary and obfuscated add-ons ineligible') }}</li>
|
|
||||||
</ul>
|
|
||||||
<p class="submit-buttons">
|
|
||||||
<button type="submit" name="review_type" value="{{ amo.STATUS_UNREVIEWED }}">
|
|
||||||
{{ _('Choose Preliminary Review') }}
|
|
||||||
</button>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
{% endblock %}
|
|
|
@ -4,24 +4,14 @@
|
||||||
{# List of steps: (text, class). A class of 'all' means the step is relevant
|
{# List of steps: (text, class). A class of 'all' means the step is relevant
|
||||||
to listed or unlisted addons, a class of 'listed' means it's only relevant
|
to listed or unlisted addons, a class of 'listed' means it's only relevant
|
||||||
to listed addons, not unlisted ones. #}
|
to listed addons, not unlisted ones. #}
|
||||||
{% if waffle.flag('no-prelim-review') %}
|
{% set NAV = ((_('Getting Started'), 'all'),
|
||||||
{% set NAV = ((_('Getting Started'), 'all'),
|
|
||||||
(_('Upload your add-on'), 'all'),
|
(_('Upload your add-on'), 'all'),
|
||||||
(_('Describe your add-on'), 'all'),
|
(_('Describe your add-on'), 'all'),
|
||||||
(_('Add images'), 'listed'),
|
(_('Add images'), 'listed'),
|
||||||
(_('Select a license'), 'listed'),
|
(_('Select a license'), 'listed'),
|
||||||
(_('n/a'), 'hidden'),
|
|
||||||
(_("You're done!"), 'all')) %}
|
(_("You're done!"), 'all')) %}
|
||||||
{% else %}
|
|
||||||
{% set NAV = ((_('Getting Started'), 'all'),
|
{% set MAX = 6 %}
|
||||||
(_('Upload your add-on'), 'all'),
|
|
||||||
(_('Describe your add-on'), 'all'),
|
|
||||||
(_('Add images'), 'listed'),
|
|
||||||
(_('Select a license'), 'listed'),
|
|
||||||
(_('Select a review process'), 'listed'),
|
|
||||||
(_("You're done!"), 'all')) %}
|
|
||||||
{% endif %}
|
|
||||||
{% set MAX = 7 %}
|
|
||||||
{% set BASE = 'devhub.submit.%s' %}
|
{% set BASE = 'devhub.submit.%s' %}
|
||||||
<div class="highlight">
|
<div class="highlight">
|
||||||
<hgroup>
|
<hgroup>
|
||||||
|
|
|
@ -28,21 +28,12 @@
|
||||||
<span class="tip tooltip"
|
<span class="tip tooltip"
|
||||||
title="{{ new_addon_form.is_unlisted.help_text }}">?</span>
|
title="{{ new_addon_form.is_unlisted.help_text }}">?</span>
|
||||||
</label>
|
</label>
|
||||||
{% if not waffle.flag('no-prelim-review') %}
|
|
||||||
<label for="{{ new_addon_form.is_sideload.auto_id }}">
|
|
||||||
{{ new_addon_form.is_sideload }}
|
|
||||||
{{ new_addon_form.is_sideload.label }}
|
|
||||||
<span class="tip tooltip"
|
|
||||||
title="{{ new_addon_form.is_sideload.help_text }}">?</span>
|
|
||||||
</label>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<input type="file" id="upload-addon"
|
<input type="file" id="upload-addon"
|
||||||
data-upload-url="{{ url('devhub.upload') }}"
|
data-upload-url="{{ url('devhub.upload') }}"
|
||||||
data-upload-url-listed="{{ url('devhub.upload') }}"
|
data-upload-url-listed="{{ url('devhub.upload') }}"
|
||||||
data-upload-url-unlisted="{{ url('devhub.upload_unlisted') }}"
|
data-upload-url-unlisted="{{ url('devhub.upload_unlisted') }}">
|
||||||
data-upload-url-sideload="{{ url('devhub.upload_sideload') }}">
|
|
||||||
|
|
||||||
{{ new_addon_form.non_field_errors() }}
|
{{ new_addon_form.non_field_errors() }}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
{% if full_review %}
|
|
||||||
<p>Thanks for submitting your {{ app }} Add-on to <a href="https://addons.mozilla.org">addons.mozilla.org</a> (AMO)! Your add-on has been added to the Full Review queue.</p>
|
<p>Thanks for submitting your {{ app }} Add-on to <a href="https://addons.mozilla.org">addons.mozilla.org</a> (AMO)! Your add-on has been added to the Full Review queue.</p>
|
||||||
{% else %}
|
|
||||||
<p>Thanks for submitting your {{ app }} Add-on to <a href="https://addons.mozilla.org">addons.mozilla.org</a> (AMO)! Your add-on has been added to the Preliminary Review queue.</p>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<p>We will contact you if we need more information. After it is reviewed, you will receive an email notification and your add-on will appear in categories and search results. While awaiting review, your add-on can still be accessed and installed directly from its detail page:</p>
|
<p>We will contact you if we need more information. After it is reviewed, you will receive an email notification and your add-on will appear in categories and search results. While awaiting review, your add-on can still be accessed and installed directly from its detail page:</p>
|
||||||
|
|
||||||
|
|
|
@ -26,16 +26,6 @@
|
||||||
{% elif addon.status == amo.STATUS_NULL %}
|
{% elif addon.status == amo.STATUS_NULL %}
|
||||||
{{ status_and_tip(addon, _('Please complete your add-on.'),
|
{{ status_and_tip(addon, _('Please complete your add-on.'),
|
||||||
url=url('devhub.submit.resume', addon.slug)) }}
|
url=url('devhub.submit.resume', addon.slug)) }}
|
||||||
{% elif addon.status == amo.STATUS_PENDING %}
|
|
||||||
{{ status_and_tip(addon, _('You will receive an email when the review is complete.')) }}
|
|
||||||
{% elif addon.status == amo.STATUS_UNREVIEWED %}
|
|
||||||
{{ status_and_tip(addon,
|
|
||||||
_("You will receive an email when the review is complete. Until "
|
|
||||||
"then, your add-on is not listed in our gallery but can be "
|
|
||||||
"accessed directly from its details page.")
|
|
||||||
if addon.is_listed else
|
|
||||||
_("You will receive an email when the review is "
|
|
||||||
"complete and your add-on is signed.")) }}
|
|
||||||
{% elif addon.status == amo.STATUS_NOMINATED %}
|
{% elif addon.status == amo.STATUS_NOMINATED %}
|
||||||
{{ status_and_tip(addon,
|
{{ status_and_tip(addon,
|
||||||
_("You will receive an email when the review is complete. Until "
|
_("You will receive an email when the review is complete. Until "
|
||||||
|
@ -57,23 +47,6 @@
|
||||||
"longer shown in our gallery. If you have any questions, "
|
"longer shown in our gallery. If you have any questions, "
|
||||||
"please email amo-admins@mozilla.org."),
|
"please email amo-admins@mozilla.org."),
|
||||||
url=(addon.get_dev_url('versions') + '#version-upload')) }}
|
url=(addon.get_dev_url('versions') + '#version-upload')) }}
|
||||||
{% elif addon.status == amo.STATUS_LITE %}
|
|
||||||
{{ status_and_tip(addon,
|
|
||||||
_("Your add-on is displayed in our gallery as experimental "
|
|
||||||
"and users are receiving automatic updates. Some features "
|
|
||||||
"are unavailable to your add-on.")
|
|
||||||
if addon.is_listed else
|
|
||||||
_('Your add-on has been signed.')) }}
|
|
||||||
{% elif addon.status == amo.STATUS_LITE_AND_NOMINATED %}
|
|
||||||
{{ status_and_tip(addon,
|
|
||||||
_("You will receive an email when the full review is complete. "
|
|
||||||
"Until then, your add-on is displayed in our gallery as "
|
|
||||||
"experimental and users are receiving automatic updates. "
|
|
||||||
"Some features are unavailable to your add-on.")
|
|
||||||
if addon.is_listed else
|
|
||||||
_("You will receive an email when the full review is "
|
|
||||||
"complete, making you able to bundle your add-on with an "
|
|
||||||
"application installer.")) }}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</strong>
|
</strong>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
</td>
|
</td>
|
||||||
<td>{{ file.size|filesizeformat }}</td>
|
<td>{{ file.size|filesizeformat }}</td>
|
||||||
<td>{{ form.platform }}</td>
|
<td>{{ form.platform }}</td>
|
||||||
<td>{{ status_choices(addon)[file.status] }}</td>
|
<td>{{ choices[file.status] }}</td>
|
||||||
<td>
|
<td>
|
||||||
<span class="js-hidden">
|
<span class="js-hidden">
|
||||||
<span class="delete">{{ form.DELETE }}</span>
|
<span class="delete">{{ form.DELETE }}</span>
|
||||||
|
|
|
@ -47,20 +47,13 @@
|
||||||
<span class="tip tooltip"
|
<span class="tip tooltip"
|
||||||
title="{{ new_addon_form.is_unlisted.help_text }}">?</span>
|
title="{{ new_addon_form.is_unlisted.help_text }}">?</span>
|
||||||
</label>
|
</label>
|
||||||
<label for="{{ new_addon_form.is_sideload.auto_id }}">
|
|
||||||
{{ new_addon_form.is_sideload }}
|
|
||||||
{{ new_addon_form.is_sideload.label }}
|
|
||||||
<span class="tip tooltip"
|
|
||||||
title="{{ new_addon_form.is_sideload.help_text }}">?</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input type="file" id="upload-addon"
|
<input type="file" id="upload-addon"
|
||||||
data-upload-url="{{ url('devhub.standalone_upload') }}"
|
data-upload-url="{{ url('devhub.standalone_upload') }}"
|
||||||
data-upload-url-listed="{{ url('devhub.standalone_upload') }}"
|
data-upload-url-listed="{{ url('devhub.standalone_upload') }}"
|
||||||
data-upload-url-unlisted="{{ url('devhub.standalone_upload_unlisted') }}"
|
data-upload-url-unlisted="{{ url('devhub.standalone_upload_unlisted') }}"">
|
||||||
data-upload-url-sideload="{{ url('devhub.standalone_upload_sideload') }}">
|
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<div class="add-file-modal upload-file modal hidden">
|
<div class="add-file-modal upload-file modal hidden">
|
||||||
<form method="post" id="upload-file" class="new-addon-file" action="{{ action }}" enctype="multipart/form-data"
|
<form method="post" id="upload-file" class="new-addon-file" action="{{ action }}" enctype="multipart/form-data"
|
||||||
data-addon-is-listed="{% if addon.is_listed %}true{% else %}false{% endif %}"
|
data-addon-is-listed="{% if addon.is_listed %}true{% else %}false{% endif %}">
|
||||||
data-addon-is-sideload="{% if not addon.is_listed and addon.status in [amo.STATUS_PUBLIC, amo.STATUS_NOMINATED] %}true{% else %}false{% endif %}">
|
|
||||||
<h3>{{ title }}</h3>
|
<h3>{{ title }}</h3>
|
||||||
<div class="upload-file-box">
|
<div class="upload-file-box">
|
||||||
<p>
|
<p>
|
||||||
|
@ -30,12 +29,6 @@
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% if not waffle.flag('no-prelim-review') and addon.status == amo.STATUS_NULL %}
|
|
||||||
<div class="nomination-type">
|
|
||||||
<label>{{ _('Which review type would you like to nominate for?') }}</label>
|
|
||||||
{{ new_file_form.nomination_type }}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<div class="beta-status hide">
|
<div class="beta-status hide">
|
||||||
<label>{{ new_file_form.beta }} {{ _('Only publish this version to my beta channel.') }}</label>
|
<label>{{ new_file_form.beta }} {{ _('Only publish this version to my beta channel.') }}</label>
|
||||||
<span class="tip tooltip" title="{{ new_file_form.beta.help_text }}">?</span>
|
<span class="tip tooltip" title="{{ new_file_form.beta.help_text }}">?</span>
|
||||||
|
|
|
@ -101,7 +101,7 @@
|
||||||
<ul>
|
<ul>
|
||||||
{% for file in version.all_files %}
|
{% for file in version.all_files %}
|
||||||
<li>
|
<li>
|
||||||
{{ file_status_message(file, addon) }}
|
{{ file_status_message(file) }}
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="file-status">
|
<td class="file-status">
|
||||||
{% for count, status in dev_files_status(version.all_files, addon) %}
|
{% for count, status in dev_files_status(version.all_files) %}
|
||||||
<div>
|
<div>
|
||||||
{# L10n: {0} is the number of files #}
|
{# L10n: {0} is the number of files #}
|
||||||
{{ status }} ({{ ngettext('{0} file', '{0} files', count)|f(count) }})
|
{{ status }} ({{ ngettext('{0} file', '{0} files', count)|f(count) }})
|
||||||
|
@ -77,22 +77,19 @@
|
||||||
<a href="#" class="remove" data-version="{{ version.id }}" data-is-current="{{ (version == addon.current_version)|int }}">x</a>
|
<a href="#" class="remove" data-version="{{ version.id }}" data-is-current="{{ (version == addon.current_version)|int }}">x</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% set no_prelim = waffle.flag('no-prelim-review') %}
|
{% set request_reviews=addon.can_request_review(disallow_preliminary_review=True) %}
|
||||||
{% set request_reviews=addon.can_request_review(no_prelim) %}
|
{% set can_cancel=(not addon.is_disabled and addon.status==amo.STATUS_NOMINATED) %}
|
||||||
{% set can_cancel=(not addon.is_disabled and addon.is_under_review) %}
|
|
||||||
{% if full_info and check_addon_ownership(request, addon, dev=True) and (request_reviews or can_cancel) %}
|
{% if full_info and check_addon_ownership(request, addon, dev=True) and (request_reviews or can_cancel) %}
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="0" class="version-status-actions item-actions">
|
<td colspan="0" class="version-status-actions item-actions">
|
||||||
{% set req = {amo.STATUS_PUBLIC: _('Request Full Review'),
|
|
||||||
amo.STATUS_LITE: _('Request Preliminary Review')} %}
|
|
||||||
{% for status in request_reviews %}
|
{% for status in request_reviews %}
|
||||||
<form method="post"
|
<form method="post"
|
||||||
action="{{ url('devhub.request-review', addon.slug, status) }}"
|
action="{{ url('devhub.request-review', addon.slug) }}"
|
||||||
{% if not addon.is_listed and status == amo.STATUS_PUBLIC %}
|
{% if not addon.is_listed and status == amo.STATUS_PUBLIC %}
|
||||||
data-confirm="#modal-full-review"
|
data-confirm="#modal-full-review"
|
||||||
{% endif %}>
|
{% endif %}>
|
||||||
{{ csrf() }}
|
{{ csrf() }}
|
||||||
<button class="link" type="submit">{{ req[status] }}</button> ·
|
<button class="link" type="submit">{{ _('Request Full Review') }}</button> ·
|
||||||
</form>
|
</form>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% if can_cancel %}
|
{% if can_cancel %}
|
||||||
|
@ -364,23 +361,16 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
{% if not addon.is_disabled and addon.is_under_review %}
|
{% if not addon.is_disabled and addon.status == amo.STATUS_NOMINATED %}
|
||||||
<div id="modal-cancel" class="modal">
|
<div id="modal-cancel" class="modal">
|
||||||
<form method="post" action="{{ url('devhub.addons.cancel', addon.slug) }}">
|
<form method="post" action="{{ url('devhub.addons.cancel', addon.slug) }}">
|
||||||
<h3>{{ _('Cancel Review Request') }}</h3>
|
<h3>{{ _('Cancel Review Request') }}</h3>
|
||||||
<p>
|
<p>
|
||||||
{% if addon.status == amo.STATUS_LITE_AND_NOMINATED %}
|
{% trans %}
|
||||||
{% trans %}
|
|
||||||
Canceling your review request will leave your
|
|
||||||
add-on as preliminarily reviewed.
|
|
||||||
{% endtrans %}
|
|
||||||
{% else %}
|
|
||||||
{% trans %}
|
|
||||||
Canceling your review request will mark your add-on incomplete.
|
Canceling your review request will mark your add-on incomplete.
|
||||||
If you do not complete your add-on after several days
|
If you do not complete your add-on after several days
|
||||||
by re-requesting review, it will be deleted.
|
by re-requesting review, it will be deleted.
|
||||||
{% endtrans %}
|
{% endtrans %}
|
||||||
{% endif %}
|
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
{% trans %}
|
{% trans %}
|
||||||
|
|
|
@ -163,41 +163,26 @@ class TestDevFilesStatus(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestDevFilesStatus, self).setUp()
|
super(TestDevFilesStatus, self).setUp()
|
||||||
self.addon = Addon.objects.create(type=1, status=amo.STATUS_UNREVIEWED)
|
self.addon = Addon.objects.create(type=1, status=amo.STATUS_NOMINATED)
|
||||||
self.version = Version.objects.create(addon=self.addon)
|
self.version = Version.objects.create(addon=self.addon)
|
||||||
self.file = File.objects.create(version=self.version,
|
self.file = File.objects.create(version=self.version,
|
||||||
platform=amo.PLATFORM_ALL.id,
|
platform=amo.PLATFORM_ALL.id,
|
||||||
status=amo.STATUS_UNREVIEWED)
|
status=amo.STATUS_UNREVIEWED)
|
||||||
|
|
||||||
def expect(self, expected):
|
def expect(self, expected):
|
||||||
cnt, msg = helpers.dev_files_status([self.file], self.addon)[0]
|
cnt, msg = helpers.dev_files_status([self.file])[0]
|
||||||
assert cnt == 1
|
assert cnt == 1
|
||||||
assert msg == unicode(expected)
|
assert msg == unicode(expected)
|
||||||
|
|
||||||
def test_unreviewed_lite(self):
|
|
||||||
self.addon.status = amo.STATUS_LITE
|
|
||||||
self.file.status = amo.STATUS_UNREVIEWED
|
|
||||||
self.expect(Addon.STATUS_CHOICES[amo.STATUS_UNREVIEWED])
|
|
||||||
|
|
||||||
def test_unreviewed_public(self):
|
def test_unreviewed_public(self):
|
||||||
self.addon.status = amo.STATUS_PUBLIC
|
self.addon.status = amo.STATUS_PUBLIC
|
||||||
self.file.status = amo.STATUS_UNREVIEWED
|
self.file.status = amo.STATUS_UNREVIEWED
|
||||||
self.expect(Addon.STATUS_CHOICES[amo.STATUS_NOMINATED])
|
self.expect(File.STATUS_CHOICES[amo.STATUS_UNREVIEWED])
|
||||||
|
|
||||||
def test_unreviewed_nominated(self):
|
def test_unreviewed_nominated(self):
|
||||||
self.addon.status = amo.STATUS_NOMINATED
|
self.addon.status = amo.STATUS_NOMINATED
|
||||||
self.file.status = amo.STATUS_UNREVIEWED
|
self.file.status = amo.STATUS_UNREVIEWED
|
||||||
self.expect(Addon.STATUS_CHOICES[amo.STATUS_NOMINATED])
|
self.expect(File.STATUS_CHOICES[amo.STATUS_UNREVIEWED])
|
||||||
|
|
||||||
def test_unreviewed_lite_and_nominated(self):
|
|
||||||
self.addon.status = amo.STATUS_LITE_AND_NOMINATED
|
|
||||||
self.file.status = amo.STATUS_UNREVIEWED
|
|
||||||
self.expect(Addon.STATUS_CHOICES[amo.STATUS_NOMINATED])
|
|
||||||
|
|
||||||
def test_reviewed_lite(self):
|
|
||||||
self.addon.status = amo.STATUS_LITE
|
|
||||||
self.file.status = amo.STATUS_LITE
|
|
||||||
self.expect(File.STATUS_CHOICES[amo.STATUS_LITE])
|
|
||||||
|
|
||||||
def test_reviewed_public(self):
|
def test_reviewed_public(self):
|
||||||
self.addon.status = amo.STATUS_PUBLIC
|
self.addon.status = amo.STATUS_PUBLIC
|
||||||
|
|
|
@ -681,10 +681,8 @@ class TestSubmitFile(TestCase):
|
||||||
@mock.patch('olympia.devhub.tasks.FileUpload.passed_all_validations', True)
|
@mock.patch('olympia.devhub.tasks.FileUpload.passed_all_validations', True)
|
||||||
def test_file_passed_all_validations(self):
|
def test_file_passed_all_validations(self):
|
||||||
upload = self.create_upload()
|
upload = self.create_upload()
|
||||||
tasks.submit_file(self.addon.pk, upload.pk,
|
tasks.submit_file(self.addon.pk, upload.pk)
|
||||||
disallow_preliminary_review=False)
|
self.create_version_for_upload.assert_called_with(self.addon, upload)
|
||||||
self.create_version_for_upload.assert_called_with(
|
|
||||||
self.addon, upload, disallow_preliminary_review=False)
|
|
||||||
|
|
||||||
@mock.patch('olympia.devhub.tasks.FileUpload.passed_all_validations',
|
@mock.patch('olympia.devhub.tasks.FileUpload.passed_all_validations',
|
||||||
False)
|
False)
|
||||||
|
|
|
@ -669,7 +669,7 @@ class TestValidationAnnotatorListed(TestValidationAnnotatorBase):
|
||||||
self.file_1_1.update(status=amo.STATUS_UNREVIEWED)
|
self.file_1_1.update(status=amo.STATUS_UNREVIEWED)
|
||||||
self.check_upload(self.file)
|
self.check_upload(self.file)
|
||||||
|
|
||||||
# We can't prevent matching against prelim or beta versions
|
# We can't prevent matching against beta versions
|
||||||
# until we change the file upload process to allow flagging
|
# until we change the file upload process to allow flagging
|
||||||
# beta versions prior to validation.
|
# beta versions prior to validation.
|
||||||
|
|
||||||
|
@ -681,7 +681,7 @@ class TestValidationAnnotatorListed(TestValidationAnnotatorBase):
|
||||||
|
|
||||||
self.check_file(self.file_1_1, self.file)
|
self.check_file(self.file_1_1, self.file)
|
||||||
|
|
||||||
for status in amo.STATUS_UNREVIEWED, amo.STATUS_LITE, amo.STATUS_BETA:
|
for status in amo.STATUS_UNREVIEWED, amo.STATUS_BETA:
|
||||||
self.validate_file.reset_mock()
|
self.validate_file.reset_mock()
|
||||||
self.save_file.reset_mock()
|
self.save_file.reset_mock()
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@ import waffle
|
||||||
from jingo.helpers import datetime as datetime_filter
|
from jingo.helpers import datetime as datetime_filter
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from pyquery import PyQuery as pq
|
from pyquery import PyQuery as pq
|
||||||
from waffle.testutils import override_flag
|
|
||||||
|
|
||||||
from olympia import amo, paypal, files
|
from olympia import amo, paypal, files
|
||||||
from olympia.amo.tests import TestCase, version_factory
|
from olympia.amo.tests import TestCase, version_factory
|
||||||
|
@ -852,8 +851,7 @@ class TestHome(TestCase):
|
||||||
|
|
||||||
def test_my_addons(self):
|
def test_my_addons(self):
|
||||||
statuses = [(amo.STATUS_NOMINATED, amo.STATUS_UNREVIEWED),
|
statuses = [(amo.STATUS_NOMINATED, amo.STATUS_UNREVIEWED),
|
||||||
(amo.STATUS_PUBLIC, amo.STATUS_UNREVIEWED),
|
(amo.STATUS_PUBLIC, amo.STATUS_UNREVIEWED)]
|
||||||
(amo.STATUS_LITE, amo.STATUS_UNREVIEWED)]
|
|
||||||
|
|
||||||
for addon_status in statuses:
|
for addon_status in statuses:
|
||||||
file = self.addon.latest_version.files.all()[0]
|
file = self.addon.latest_version.files.all()[0]
|
||||||
|
@ -1336,8 +1334,6 @@ class TestSubmitStep2(TestCase):
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
doc = pq(response.content)
|
doc = pq(response.content)
|
||||||
assert doc('.list-addon input#id_is_unlisted[type=checkbox]')
|
assert doc('.list-addon input#id_is_unlisted[type=checkbox]')
|
||||||
# There also is a checkbox to select full review (side-load) or prelim.
|
|
||||||
assert doc('.list-addon input#id_is_sideload[type=checkbox]')
|
|
||||||
|
|
||||||
|
|
||||||
class TestSubmitStep3(TestSubmitBase):
|
class TestSubmitStep3(TestSubmitBase):
|
||||||
|
@ -1412,7 +1408,7 @@ class TestSubmitStep3(TestSubmitBase):
|
||||||
'slug': 'unlisted-addon',
|
'slug': 'unlisted-addon',
|
||||||
'summary': 'summary'})
|
'summary': 'summary'})
|
||||||
assert response.status_code == 302
|
assert response.status_code == 302
|
||||||
assert response.url.endswith(reverse('devhub.submit.7',
|
assert response.url.endswith(reverse('devhub.submit.6',
|
||||||
args=['unlisted-addon']))
|
args=['unlisted-addon']))
|
||||||
# Unlisted addons don't need much info, and their queue is chosen
|
# Unlisted addons don't need much info, and their queue is chosen
|
||||||
# automatically on step 2, so we skip steps 4, 5 and 6. We thus have no
|
# automatically on step 2, so we skip steps 4, 5 and 6. We thus have no
|
||||||
|
@ -1722,11 +1718,11 @@ class TestSubmitStep4(TestSubmitBase):
|
||||||
assert self.get_step().step == 5
|
assert self.get_step().step == 5
|
||||||
|
|
||||||
|
|
||||||
class TestSubmitStep5_with_prelim(TestSubmitBase):
|
class TestSubmitStep5(TestSubmitBase):
|
||||||
"""License submission."""
|
"""License submission."""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestSubmitStep5_with_prelim, self).setUp()
|
super(TestSubmitStep5, self).setUp()
|
||||||
SubmitStep.objects.create(addon_id=self.addon.id, step=5)
|
SubmitStep.objects.create(addon_id=self.addon.id, step=5)
|
||||||
self.url = reverse('devhub.submit.5', args=['a3615'])
|
self.url = reverse('devhub.submit.5', args=['a3615'])
|
||||||
self.next_step = reverse('devhub.submit.6', args=['a3615'])
|
self.next_step = reverse('devhub.submit.6', args=['a3615'])
|
||||||
|
@ -1735,57 +1731,6 @@ class TestSubmitStep5_with_prelim(TestSubmitBase):
|
||||||
def test_get(self):
|
def test_get(self):
|
||||||
assert self.client.get(self.url).status_code == 200
|
assert self.client.get(self.url).status_code == 200
|
||||||
|
|
||||||
def test_set_license(self):
|
|
||||||
r = self.client.post(self.url, {'builtin': 3})
|
|
||||||
self.assert3xx(r, self.next_step)
|
|
||||||
assert self.get_addon().current_version.license.builtin == 3
|
|
||||||
assert self.get_step().step == 6
|
|
||||||
log_items = ActivityLog.objects.for_addons(self.get_addon())
|
|
||||||
assert not log_items.filter(action=amo.LOG.CHANGE_LICENSE.id), (
|
|
||||||
"Initial license choice:6 needn't be logged.")
|
|
||||||
|
|
||||||
def test_license_error(self):
|
|
||||||
r = self.client.post(self.url, {'builtin': 4})
|
|
||||||
assert r.status_code == 200
|
|
||||||
self.assertFormError(r, 'license_form', 'builtin',
|
|
||||||
'Select a valid choice. 4 is not one of '
|
|
||||||
'the available choices.')
|
|
||||||
assert self.get_step().step == 5
|
|
||||||
|
|
||||||
def test_set_eula(self):
|
|
||||||
self.get_addon().update(eula=None, privacy_policy=None)
|
|
||||||
r = self.client.post(self.url, dict(builtin=3, has_eula=True,
|
|
||||||
eula='xxx'))
|
|
||||||
self.assert3xx(r, self.next_step)
|
|
||||||
assert unicode(self.get_addon().eula) == 'xxx'
|
|
||||||
assert self.get_step().step == 6
|
|
||||||
|
|
||||||
def test_set_eula_nomsg(self):
|
|
||||||
"""
|
|
||||||
You should not get punished with a 500 for not writing your EULA...
|
|
||||||
but perhaps you should feel shame for lying to us. This test does not
|
|
||||||
test for shame.
|
|
||||||
"""
|
|
||||||
self.get_addon().update(eula=None, privacy_policy=None)
|
|
||||||
r = self.client.post(self.url, dict(builtin=3, has_eula=True))
|
|
||||||
self.assert3xx(r, self.next_step)
|
|
||||||
assert self.get_step().step == 6
|
|
||||||
|
|
||||||
|
|
||||||
@override_flag('no-prelim-review', active=True)
|
|
||||||
class TestSubmitStep5_no_prelim(TestSubmitBase):
|
|
||||||
"""License submission."""
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(TestSubmitStep5_no_prelim, self).setUp()
|
|
||||||
SubmitStep.objects.create(addon_id=self.addon.id, step=5)
|
|
||||||
self.url = reverse('devhub.submit.5', args=['a3615'])
|
|
||||||
self.next_step = reverse('devhub.submit.7', args=['a3615'])
|
|
||||||
License.objects.create(builtin=3, on_form=True)
|
|
||||||
|
|
||||||
def test_get(self):
|
|
||||||
assert self.client.get(self.url).status_code == 200
|
|
||||||
|
|
||||||
def test_set_license(self):
|
def test_set_license(self):
|
||||||
r = self.client.post(self.url, {'builtin': 3})
|
r = self.client.post(self.url, {'builtin': 3})
|
||||||
self.assert3xx(r, self.next_step)
|
self.assert3xx(r, self.next_step)
|
||||||
|
@ -1844,62 +1789,7 @@ class TestSubmitStep6(TestSubmitBase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestSubmitStep6, self).setUp()
|
super(TestSubmitStep6, self).setUp()
|
||||||
SubmitStep.objects.create(addon_id=3615, step=6)
|
self.url = reverse('devhub.submit.6', args=[self.addon.slug])
|
||||||
self.url = reverse('devhub.submit.6', args=['a3615'])
|
|
||||||
|
|
||||||
def test_get(self):
|
|
||||||
r = self.client.get(self.url)
|
|
||||||
assert r.status_code == 200
|
|
||||||
|
|
||||||
def test_require_review_type(self):
|
|
||||||
r = self.client.post(self.url, {'dummy': 'text'})
|
|
||||||
assert r.status_code == 200
|
|
||||||
self.assertFormError(r, 'review_type_form', 'review_type',
|
|
||||||
'A review type must be selected.')
|
|
||||||
|
|
||||||
def test_bad_review_type(self):
|
|
||||||
d = dict(review_type='jetsfool')
|
|
||||||
r = self.client.post(self.url, d)
|
|
||||||
assert r.status_code == 200
|
|
||||||
self.assertFormError(r, 'review_type_form', 'review_type',
|
|
||||||
'Select a valid choice. jetsfool is not one of '
|
|
||||||
'the available choices.')
|
|
||||||
|
|
||||||
def test_prelim_review(self):
|
|
||||||
d = dict(review_type=amo.STATUS_UNREVIEWED)
|
|
||||||
r = self.client.post(self.url, d)
|
|
||||||
assert r.status_code == 302
|
|
||||||
assert self.get_addon().status == amo.STATUS_UNREVIEWED
|
|
||||||
pytest.raises(SubmitStep.DoesNotExist, self.get_step)
|
|
||||||
|
|
||||||
def test_full_review(self):
|
|
||||||
self.get_version().update(nomination=None)
|
|
||||||
d = dict(review_type=amo.STATUS_NOMINATED)
|
|
||||||
r = self.client.post(self.url, d)
|
|
||||||
assert r.status_code == 302
|
|
||||||
addon = self.get_addon()
|
|
||||||
assert addon.status == amo.STATUS_NOMINATED
|
|
||||||
self.assertCloseToNow(self.get_version().nomination)
|
|
||||||
pytest.raises(SubmitStep.DoesNotExist, self.get_step)
|
|
||||||
|
|
||||||
def test_nomination_date_is_only_set_once(self):
|
|
||||||
# This was a regression, see bug 632191.
|
|
||||||
# Nominate:
|
|
||||||
r = self.client.post(self.url, dict(review_type=amo.STATUS_NOMINATED))
|
|
||||||
assert r.status_code == 302
|
|
||||||
nomdate = datetime.now() - timedelta(days=5)
|
|
||||||
self.get_version().update(nomination=nomdate, _signal=False)
|
|
||||||
# Update something else in the addon:
|
|
||||||
self.get_addon().update(slug='foobar')
|
|
||||||
assert self.get_version().nomination.timetuple()[0:5] == (
|
|
||||||
nomdate.timetuple()[0:5])
|
|
||||||
|
|
||||||
|
|
||||||
class TestSubmitStep7(TestSubmitBase):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(TestSubmitStep7, self).setUp()
|
|
||||||
self.url = reverse('devhub.submit.7', args=[self.addon.slug])
|
|
||||||
|
|
||||||
@mock.patch.object(settings, 'SITE_URL', 'http://b.ro')
|
@mock.patch.object(settings, 'SITE_URL', 'http://b.ro')
|
||||||
@mock.patch('olympia.devhub.tasks.send_welcome_email.delay')
|
@mock.patch('olympia.devhub.tasks.send_welcome_email.delay')
|
||||||
|
@ -1949,7 +1839,7 @@ class TestSubmitStep7(TestSubmitBase):
|
||||||
|
|
||||||
@mock.patch('olympia.devhub.tasks.send_welcome_email.delay', new=mock.Mock)
|
@mock.patch('olympia.devhub.tasks.send_welcome_email.delay', new=mock.Mock)
|
||||||
def test_finish_submitting_unlisted_addon(self):
|
def test_finish_submitting_unlisted_addon(self):
|
||||||
self.addon.update(is_listed=False, status=amo.STATUS_UNREVIEWED)
|
self.addon.update(is_listed=False, status=amo.STATUS_NOMINATED)
|
||||||
|
|
||||||
r = self.client.get(self.url)
|
r = self.client.get(self.url)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
@ -1984,7 +1874,7 @@ class TestSubmitStep7(TestSubmitBase):
|
||||||
# mac-only Add-on:
|
# mac-only Add-on:
|
||||||
addon = Addon.objects.get(name__localized_string='Cooliris')
|
addon = Addon.objects.get(name__localized_string='Cooliris')
|
||||||
addon.addonuser_set.create(user_id=55021)
|
addon.addonuser_set.create(user_id=55021)
|
||||||
r = self.client.get(reverse('devhub.submit.7', args=[addon.slug]))
|
r = self.client.get(reverse('devhub.submit.6', args=[addon.slug]))
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
next_steps = pq(r.content)('.done-next-steps li a')
|
next_steps = pq(r.content)('.done-next-steps li a')
|
||||||
|
|
||||||
|
@ -1997,16 +1887,6 @@ class TestSubmitStep7(TestSubmitBase):
|
||||||
# edit listing of freshly submitted add-on...
|
# edit listing of freshly submitted add-on...
|
||||||
assert next_steps.eq(1).attr('href') == addon.get_dev_url()
|
assert next_steps.eq(1).attr('href') == addon.get_dev_url()
|
||||||
|
|
||||||
@mock.patch('olympia.devhub.tasks.send_welcome_email.delay', new=mock.Mock)
|
|
||||||
def test_finish_addon_for_prelim_review(self):
|
|
||||||
self.addon.update(status=amo.STATUS_UNREVIEWED)
|
|
||||||
|
|
||||||
response = self.client.get(self.url)
|
|
||||||
assert response.status_code == 200
|
|
||||||
doc = pq(response.content)
|
|
||||||
intro = doc('.addon-submission-process p').text().strip()
|
|
||||||
assert 'Preliminary Review' in intro, ('Unexpected intro: %s' % intro)
|
|
||||||
|
|
||||||
@mock.patch('olympia.devhub.tasks.send_welcome_email.delay', new=mock.Mock)
|
@mock.patch('olympia.devhub.tasks.send_welcome_email.delay', new=mock.Mock)
|
||||||
def test_finish_addon_for_full_review(self):
|
def test_finish_addon_for_full_review(self):
|
||||||
self.addon.update(status=amo.STATUS_NOMINATED)
|
self.addon.update(status=amo.STATUS_NOMINATED)
|
||||||
|
@ -2035,7 +1915,7 @@ class TestSubmitStep7(TestSubmitBase):
|
||||||
def test_display_non_ascii_url(self):
|
def test_display_non_ascii_url(self):
|
||||||
u = 'フォクすけといっしょ'
|
u = 'フォクすけといっしょ'
|
||||||
self.addon.update(slug=u)
|
self.addon.update(slug=u)
|
||||||
r = self.client.get(reverse('devhub.submit.7', args=[u]))
|
r = self.client.get(reverse('devhub.submit.6', args=[u]))
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
# The meta charset will always be utf-8.
|
# The meta charset will always be utf-8.
|
||||||
doc = pq(r.content.decode('utf-8'))
|
doc = pq(r.content.decode('utf-8'))
|
||||||
|
@ -2056,7 +1936,7 @@ class TestResumeStep(TestSubmitBase):
|
||||||
|
|
||||||
def test_step_redirects(self):
|
def test_step_redirects(self):
|
||||||
SubmitStep.objects.create(addon_id=3615, step=1)
|
SubmitStep.objects.create(addon_id=3615, step=1)
|
||||||
for i in xrange(3, 7):
|
for i in xrange(3, 6):
|
||||||
SubmitStep.objects.filter(addon=self.get_addon()).update(step=i)
|
SubmitStep.objects.filter(addon=self.get_addon()).update(step=i)
|
||||||
r = self.client.get(self.url, follow=True)
|
r = self.client.get(self.url, follow=True)
|
||||||
self.assert3xx(r, reverse('devhub.submit.%s' % i,
|
self.assert3xx(r, reverse('devhub.submit.%s' % i,
|
||||||
|
@ -2098,7 +1978,7 @@ class TestSubmitSteps(TestCase):
|
||||||
def assert_linked(self, doc, numbers):
|
def assert_linked(self, doc, numbers):
|
||||||
"""Check that the nth <li> in the steps list is a link."""
|
"""Check that the nth <li> in the steps list is a link."""
|
||||||
lis = doc('.submit-addon-progress li')
|
lis = doc('.submit-addon-progress li')
|
||||||
assert len(lis) == 7
|
assert len(lis) == 6
|
||||||
for idx, li in enumerate(lis):
|
for idx, li in enumerate(lis):
|
||||||
links = pq(li)('a')
|
links = pq(li)('a')
|
||||||
if (idx + 1) in numbers:
|
if (idx + 1) in numbers:
|
||||||
|
@ -2117,25 +1997,25 @@ class TestSubmitSteps(TestCase):
|
||||||
r = self.client.get(reverse('devhub.submit.1'))
|
r = self.client.get(reverse('devhub.submit.1'))
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
def test_on_step_6(self):
|
def test_on_step_5(self):
|
||||||
# Hitting the step we're supposed to be on is a 200.
|
# Hitting the step we're supposed to be on is a 200.
|
||||||
SubmitStep.objects.create(addon_id=3615, step=6)
|
SubmitStep.objects.create(addon_id=3615, step=5)
|
||||||
r = self.client.get(reverse('devhub.submit.6',
|
r = self.client.get(reverse('devhub.submit.5',
|
||||||
args=['a3615']))
|
args=['a3615']))
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
def test_skip_step_6(self):
|
def test_skip_step_5(self):
|
||||||
# We get bounced back to step 3.
|
# We get bounced back to step 3.
|
||||||
SubmitStep.objects.create(addon_id=3615, step=3)
|
SubmitStep.objects.create(addon_id=3615, step=3)
|
||||||
r = self.client.get(reverse('devhub.submit.6',
|
r = self.client.get(reverse('devhub.submit.5',
|
||||||
args=['a3615']), follow=True)
|
args=['a3615']), follow=True)
|
||||||
self.assert3xx(r, reverse('devhub.submit.3', args=['a3615']))
|
self.assert3xx(r, reverse('devhub.submit.3', args=['a3615']))
|
||||||
|
|
||||||
def test_all_done(self):
|
def test_all_done(self):
|
||||||
# There's no SubmitStep, so we must be done.
|
# There's no SubmitStep, so we must be done.
|
||||||
r = self.client.get(reverse('devhub.submit.6',
|
r = self.client.get(reverse('devhub.submit.5',
|
||||||
args=['a3615']), follow=True)
|
args=['a3615']), follow=True)
|
||||||
self.assert3xx(r, reverse('devhub.submit.7', args=['a3615']))
|
self.assert3xx(r, reverse('devhub.submit.6', args=['a3615']))
|
||||||
|
|
||||||
def test_menu_step_1(self):
|
def test_menu_step_1(self):
|
||||||
self.user.update(read_dev_agreement=None)
|
self.user.update(read_dev_agreement=None)
|
||||||
|
@ -2156,51 +2036,32 @@ class TestSubmitSteps(TestCase):
|
||||||
self.assert_linked(doc, [3])
|
self.assert_linked(doc, [3])
|
||||||
self.assert_highlight(doc, 3)
|
self.assert_highlight(doc, 3)
|
||||||
|
|
||||||
def test_menu_step_3_from_6(self):
|
def test_menu_step_3_from_5(self):
|
||||||
SubmitStep.objects.create(addon_id=3615, step=6)
|
SubmitStep.objects.create(addon_id=3615, step=5)
|
||||||
url = reverse('devhub.submit.3', args=['a3615'])
|
url = reverse('devhub.submit.3', args=['a3615'])
|
||||||
doc = pq(self.client.get(url).content)
|
doc = pq(self.client.get(url).content)
|
||||||
self.assert_linked(doc, [3, 4, 5, 6])
|
self.assert_linked(doc, [3, 4, 5])
|
||||||
self.assert_highlight(doc, 3)
|
self.assert_highlight(doc, 3)
|
||||||
|
|
||||||
def test_menu_step_6(self):
|
def test_menu_step_6(self):
|
||||||
SubmitStep.objects.create(addon_id=3615, step=6)
|
|
||||||
url = reverse('devhub.submit.6', args=['a3615'])
|
url = reverse('devhub.submit.6', args=['a3615'])
|
||||||
doc = pq(self.client.get(url).content)
|
doc = pq(self.client.get(url).content)
|
||||||
self.assert_linked(doc, [3, 4, 5, 6])
|
self.assert_linked(doc, [])
|
||||||
self.assert_highlight(doc, 6)
|
self.assert_highlight(doc, 6)
|
||||||
|
|
||||||
def test_menu_step_7(self):
|
def test_menu_step_6_unlisted(self):
|
||||||
url = reverse('devhub.submit.7', args=['a3615'])
|
SubmitStep.objects.create(addon_id=3615, step=6)
|
||||||
doc = pq(self.client.get(url).content)
|
|
||||||
self.assert_linked(doc, [])
|
|
||||||
self.assert_highlight(doc, 7)
|
|
||||||
|
|
||||||
def test_menu_step_7_unlisted(self):
|
|
||||||
SubmitStep.objects.create(addon_id=3615, step=7)
|
|
||||||
Addon.objects.get(pk=3615).update(is_listed=False)
|
Addon.objects.get(pk=3615).update(is_listed=False)
|
||||||
url = reverse('devhub.submit.7', args=['a3615'])
|
url = reverse('devhub.submit.6', args=['a3615'])
|
||||||
doc = pq(self.client.get(url).content)
|
doc = pq(self.client.get(url).content)
|
||||||
self.assert_linked(doc, []) # Last step: no previous step linked.
|
self.assert_linked(doc, []) # Last step: no previous step linked.
|
||||||
# Skipped from step 3 to 7, as unlisted add-ons don't need listing
|
# Skipped from step 3 to 6, as unlisted add-ons don't need listing
|
||||||
# information. Thus none of the steps from 4 to 6 should be there.
|
# information. Thus none of the steps from 4 to 5 should be there.
|
||||||
# For reference, the steps that are with the "listed" class (instead of
|
# For reference, the steps that are with the "listed" class (instead of
|
||||||
# "all") aren't displayed.
|
# "all") aren't displayed.
|
||||||
assert len(doc('.submit-addon-progress li.all')) == 4
|
assert len(doc('.submit-addon-progress li.all')) == 4
|
||||||
# The step 7 is thus the 4th visible in the list.
|
# The step 6 is thus the 4th visible in the list.
|
||||||
self.assert_highlight(doc, 7) # Current step is still the 7th.
|
self.assert_highlight(doc, 6) # Current step is still the 6th.
|
||||||
|
|
||||||
@override_flag('no-prelim-review', active=True)
|
|
||||||
def test_menu_step_7_no_prelim(self):
|
|
||||||
SubmitStep.objects.create(addon_id=3615, step=7)
|
|
||||||
url = reverse('devhub.submit.7', args=['a3615'])
|
|
||||||
doc = pq(self.client.get(url).content)
|
|
||||||
self.assert_linked(doc, []) # Last step: no previous step linked.
|
|
||||||
# Skipped step 6, so we're one short, as no review selection.
|
|
||||||
assert (len(doc('.submit-addon-progress li.all')) +
|
|
||||||
len(doc('.submit-addon-progress li.listed'))) == 6
|
|
||||||
# The step 7 is thus the 6th visible in the list.
|
|
||||||
self.assert_highlight(doc, 7) # Current step is still the 7th.
|
|
||||||
|
|
||||||
|
|
||||||
class TestUpload(BaseUploadTest):
|
class TestUpload(BaseUploadTest):
|
||||||
|
@ -2527,8 +2388,7 @@ class TestQueuePosition(UploadTest):
|
||||||
|
|
||||||
def test_in_queue(self):
|
def test_in_queue(self):
|
||||||
statuses = [(amo.STATUS_NOMINATED, amo.STATUS_UNREVIEWED),
|
statuses = [(amo.STATUS_NOMINATED, amo.STATUS_UNREVIEWED),
|
||||||
(amo.STATUS_PUBLIC, amo.STATUS_UNREVIEWED),
|
(amo.STATUS_PUBLIC, amo.STATUS_UNREVIEWED)]
|
||||||
(amo.STATUS_LITE, amo.STATUS_UNREVIEWED)]
|
|
||||||
|
|
||||||
for addon_status in statuses:
|
for addon_status in statuses:
|
||||||
self.addon.status = addon_status[0]
|
self.addon.status = addon_status[0]
|
||||||
|
@ -2561,6 +2421,7 @@ class TestVersionAddFile(UploadTest):
|
||||||
version_files = self.version.files.all()[0]
|
version_files = self.version.files.all()[0]
|
||||||
version_files.update(platform=amo.PLATFORM_LINUX.id,
|
version_files.update(platform=amo.PLATFORM_LINUX.id,
|
||||||
status=amo.STATUS_UNREVIEWED)
|
status=amo.STATUS_UNREVIEWED)
|
||||||
|
self.addon.update(status=amo.STATUS_NOMINATED)
|
||||||
# We need to clear the cached properties for platform change above.
|
# We need to clear the cached properties for platform change above.
|
||||||
del self.version.supported_platforms
|
del self.version.supported_platforms
|
||||||
del self.version.all_files
|
del self.version.all_files
|
||||||
|
@ -2760,60 +2621,12 @@ class TestVersionAddFile(UploadTest):
|
||||||
assert response.status_code == 400
|
assert response.status_code == 400
|
||||||
assert 'source' in json.loads(response.content)
|
assert 'source' in json.loads(response.content)
|
||||||
|
|
||||||
@mock.patch('olympia.editors.helpers.sign_file')
|
|
||||||
def test_unlisted_addon_sideload_fail_validation(self, mock_sign_file):
|
|
||||||
"""Sideloadable unlisted addons are also auto signed/reviewed."""
|
|
||||||
self.version.all_files[0].update(status=amo.STATUS_PUBLIC)
|
|
||||||
self.addon.update(is_listed=False, status=amo.STATUS_PUBLIC)
|
|
||||||
# Make sure the file has validation warnings or errors.
|
|
||||||
self.upload.update(
|
|
||||||
validation='{"notices": 2, "errors": 0, "messages": [],'
|
|
||||||
' "metadata": {}, "warnings": 1,'
|
|
||||||
' "signing_summary": {"trivial": 1, "low": 1,'
|
|
||||||
' "medium": 0, "high": 0},'
|
|
||||||
' "passed_auto_validation": 1}')
|
|
||||||
self.post()
|
|
||||||
file_ = File.objects.latest()
|
|
||||||
# Status is changed to fully reviewed and the file is signed.
|
|
||||||
assert self.addon.status == amo.STATUS_PUBLIC
|
|
||||||
assert file_.status == amo.STATUS_PUBLIC
|
|
||||||
assert mock_sign_file.called
|
|
||||||
# There is a log for that unlisted file signature (with failed
|
|
||||||
# validation).
|
|
||||||
log = ActivityLog.objects.order_by('pk').last()
|
|
||||||
expected = amo.LOG.UNLISTED_SIDELOAD_SIGNED_VALIDATION_FAILED.id
|
|
||||||
assert log.action == expected
|
|
||||||
|
|
||||||
@mock.patch('olympia.editors.helpers.sign_file')
|
|
||||||
def test_unlisted_addon_sideload_pass_validation(self, mock_sign_file):
|
|
||||||
"""Sideloadable unlisted addons are also auto signed/reviewed."""
|
|
||||||
self.version.all_files[0].update(status=amo.STATUS_PUBLIC)
|
|
||||||
self.addon.update(is_listed=False, status=amo.STATUS_PUBLIC)
|
|
||||||
# Make sure the file has no validation signing related messages.
|
|
||||||
self.upload.update(
|
|
||||||
validation='{"notices": 2, "errors": 0, "messages": [],'
|
|
||||||
' "metadata": {}, "warnings": 1,'
|
|
||||||
' "signing_summary": {"trivial": 1, "low": 0,'
|
|
||||||
' "medium": 0, "high": 0},'
|
|
||||||
' "passed_auto_validation": 1}')
|
|
||||||
self.post()
|
|
||||||
file_ = File.objects.latest()
|
|
||||||
# Status is changed to fully reviewed and the file is signed.
|
|
||||||
assert self.addon.status == amo.STATUS_PUBLIC
|
|
||||||
assert file_.status == amo.STATUS_PUBLIC
|
|
||||||
assert mock_sign_file.called
|
|
||||||
# There is a log for that unlisted file signature (with failed
|
|
||||||
# validation).
|
|
||||||
log = ActivityLog.objects.order_by('pk').last()
|
|
||||||
expected = amo.LOG.UNLISTED_SIDELOAD_SIGNED_VALIDATION_PASSED.id
|
|
||||||
assert log.action == expected
|
|
||||||
|
|
||||||
@mock.patch('olympia.editors.helpers.sign_file')
|
@mock.patch('olympia.editors.helpers.sign_file')
|
||||||
def test_unlisted_addon_fail_validation(self, mock_sign_file):
|
def test_unlisted_addon_fail_validation(self, mock_sign_file):
|
||||||
"""Files that fail validation are also auto signed/reviewed."""
|
"""Files that fail validation are also auto signed/reviewed."""
|
||||||
self.addon.update(
|
self.version.all_files[0].update(status=amo.STATUS_PUBLIC)
|
||||||
is_listed=False, status=amo.STATUS_LITE)
|
self.addon.update(is_listed=False, status=amo.STATUS_PUBLIC)
|
||||||
assert self.addon.status == amo.STATUS_LITE # Preliminary reviewed.
|
assert self.addon.status == amo.STATUS_PUBLIC
|
||||||
# Make sure the file has validation warnings or errors.
|
# Make sure the file has validation warnings or errors.
|
||||||
self.upload.update(
|
self.upload.update(
|
||||||
validation='{"notices": 2, "errors": 0, "messages": [],'
|
validation='{"notices": 2, "errors": 0, "messages": [],'
|
||||||
|
@ -2823,68 +2636,18 @@ class TestVersionAddFile(UploadTest):
|
||||||
' "passed_auto_validation": 1}')
|
' "passed_auto_validation": 1}')
|
||||||
self.post()
|
self.post()
|
||||||
file_ = File.objects.latest()
|
file_ = File.objects.latest()
|
||||||
# Status is changed to preliminary reviewed and the file is signed.
|
# Status is changed to reviewed and the file is signed.
|
||||||
assert self.addon.status == amo.STATUS_LITE
|
assert self.addon.status == amo.STATUS_PUBLIC
|
||||||
assert file_.status == amo.STATUS_LITE
|
assert file_.status == amo.STATUS_PUBLIC
|
||||||
assert mock_sign_file.called
|
assert mock_sign_file.called
|
||||||
# There is a log for that unlisted file signature (with failed
|
# There is a log for that unlisted file signature (with failed
|
||||||
# validation).
|
# validation).
|
||||||
log = ActivityLog.objects.order_by('pk').last()
|
log = ActivityLog.objects.order_by('pk').last()
|
||||||
assert log.action == amo.LOG.UNLISTED_SIGNED_VALIDATION_FAILED.id
|
expected = amo.LOG.UNLISTED_SIGNED_VALIDATION_FAILED.id
|
||||||
|
assert log.action == expected
|
||||||
|
|
||||||
@mock.patch('olympia.editors.helpers.sign_file')
|
@mock.patch('olympia.editors.helpers.sign_file')
|
||||||
def test_unlisted_addon_pass_validation(self, mock_sign_file):
|
def test_unlisted_addon_pass_validation(self, mock_sign_file):
|
||||||
"""Files that pass validation are automatically signed/reviewed."""
|
|
||||||
self.addon.update(
|
|
||||||
is_listed=False, status=amo.STATUS_LITE)
|
|
||||||
# Make sure the file has no validation signing related messages.
|
|
||||||
self.upload.update(
|
|
||||||
validation='{"notices": 2, "errors": 0, "messages": [],'
|
|
||||||
' "metadata": {}, "warnings": 1,'
|
|
||||||
' "signing_summary": {"trivial": 1, "low": 0,'
|
|
||||||
' "medium": 0, "high": 0},'
|
|
||||||
' "passed_auto_validation": 1}')
|
|
||||||
assert self.addon.status == amo.STATUS_LITE # Preliminary reviewed.
|
|
||||||
self.post()
|
|
||||||
file_ = File.objects.latest()
|
|
||||||
# Status is changed to preliminary reviewed and the file is signed.
|
|
||||||
assert self.addon.status == amo.STATUS_LITE
|
|
||||||
assert file_.status == amo.STATUS_LITE
|
|
||||||
assert mock_sign_file.called
|
|
||||||
# There is a log for that unlisted file signature (with passed
|
|
||||||
# validation).
|
|
||||||
log = ActivityLog.objects.order_by('pk').last()
|
|
||||||
assert log.action == amo.LOG.UNLISTED_SIGNED_VALIDATION_PASSED.id
|
|
||||||
|
|
||||||
@override_flag('no-prelim-review', active=True)
|
|
||||||
@mock.patch('olympia.editors.helpers.sign_file')
|
|
||||||
def test_unlisted_addon_fail_validation_no_prelim(self, mock_sign_file):
|
|
||||||
"""Files that fail validation are also auto signed/reviewed."""
|
|
||||||
self.version.all_files[0].update(status=amo.STATUS_PUBLIC)
|
|
||||||
self.addon.update(is_listed=False, status=amo.STATUS_PUBLIC)
|
|
||||||
assert self.addon.status == amo.STATUS_PUBLIC
|
|
||||||
# Make sure the file has validation warnings or errors.
|
|
||||||
self.upload.update(
|
|
||||||
validation='{"notices": 2, "errors": 0, "messages": [],'
|
|
||||||
' "metadata": {}, "warnings": 1,'
|
|
||||||
' "signing_summary": {"trivial": 1, "low": 1,'
|
|
||||||
' "medium": 0, "high": 0},'
|
|
||||||
' "passed_auto_validation": 1}')
|
|
||||||
self.post()
|
|
||||||
file_ = File.objects.latest()
|
|
||||||
# Status is changed to reviewed and the file is signed.
|
|
||||||
assert self.addon.status == amo.STATUS_PUBLIC
|
|
||||||
assert file_.status == amo.STATUS_PUBLIC
|
|
||||||
assert mock_sign_file.called
|
|
||||||
# There is a log for that unlisted file signature (with failed
|
|
||||||
# validation).
|
|
||||||
log = ActivityLog.objects.order_by('pk').last()
|
|
||||||
expected = amo.LOG.UNLISTED_SIDELOAD_SIGNED_VALIDATION_FAILED.id
|
|
||||||
assert log.action == expected
|
|
||||||
|
|
||||||
@override_flag('no-prelim-review', active=True)
|
|
||||||
@mock.patch('olympia.editors.helpers.sign_file')
|
|
||||||
def test_unlisted_addon_pass_validation_noprelim(self, mock_sign_file):
|
|
||||||
"""Files that pass validation are automatically signed/reviewed."""
|
"""Files that pass validation are automatically signed/reviewed."""
|
||||||
self.version.all_files[0].update(status=amo.STATUS_PUBLIC)
|
self.version.all_files[0].update(status=amo.STATUS_PUBLIC)
|
||||||
self.addon.update(is_listed=False, status=amo.STATUS_PUBLIC)
|
self.addon.update(is_listed=False, status=amo.STATUS_PUBLIC)
|
||||||
|
@ -2905,7 +2668,7 @@ class TestVersionAddFile(UploadTest):
|
||||||
# There is a log for that unlisted file signature (with passed
|
# There is a log for that unlisted file signature (with passed
|
||||||
# validation).
|
# validation).
|
||||||
log = ActivityLog.objects.order_by('pk').last()
|
log = ActivityLog.objects.order_by('pk').last()
|
||||||
expected = amo.LOG.UNLISTED_SIDELOAD_SIGNED_VALIDATION_PASSED.id
|
expected = amo.LOG.UNLISTED_SIGNED_VALIDATION_PASSED.id
|
||||||
assert log.action == expected
|
assert log.action == expected
|
||||||
|
|
||||||
@mock.patch('olympia.devhub.views.sign_file')
|
@mock.patch('olympia.devhub.views.sign_file')
|
||||||
|
@ -3071,8 +2834,7 @@ class TestAddVersion(AddVersionTest):
|
||||||
# versions has been deleted either.
|
# versions has been deleted either.
|
||||||
self.version.update(version='0.1')
|
self.version.update(version='0.1')
|
||||||
self.version.delete()
|
self.version.delete()
|
||||||
r = self.post(expected_status=400,
|
r = self.post(expected_status=400)
|
||||||
nomination_type=amo.STATUS_NOMINATED)
|
|
||||||
assert_json_error(
|
assert_json_error(
|
||||||
r, None, 'Version 0.1 already exists, or was uploaded before.')
|
r, None, 'Version 0.1 already exists, or was uploaded before.')
|
||||||
|
|
||||||
|
@ -3083,8 +2845,7 @@ class TestAddVersion(AddVersionTest):
|
||||||
reverse('devhub.versions.edit',
|
reverse('devhub.versions.edit',
|
||||||
args=[self.addon.slug, version.id]))
|
args=[self.addon.slug, version.id]))
|
||||||
|
|
||||||
@override_flag('no-prelim-review', active=True)
|
def test_incomplete_addon_now_nominated(self):
|
||||||
def test_incomplete_addon_now_nominated_when_no_prelim(self):
|
|
||||||
"""Uploading a new version for an incomplete addon should set it to
|
"""Uploading a new version for an incomplete addon should set it to
|
||||||
nominated."""
|
nominated."""
|
||||||
self.version.delete()
|
self.version.delete()
|
||||||
|
@ -3147,62 +2908,12 @@ class TestAddVersion(AddVersionTest):
|
||||||
f = File.objects.latest()
|
f = File.objects.latest()
|
||||||
assert f.status != amo.STATUS_BETA
|
assert f.status != amo.STATUS_BETA
|
||||||
|
|
||||||
@mock.patch('olympia.editors.helpers.sign_file')
|
|
||||||
def test_unlisted_addon_sideload_fail_validation(self, mock_sign_file):
|
|
||||||
"""Sideloadable unlisted addons also get auto signed/reviewed."""
|
|
||||||
assert self.addon.status == amo.STATUS_PUBLIC # Fully reviewed.
|
|
||||||
self.addon.update(is_listed=False)
|
|
||||||
# Make sure the file has validation warnings or errors.
|
|
||||||
self.upload.update(
|
|
||||||
validation=json.dumps({
|
|
||||||
"notices": 2, "errors": 0, "messages": [],
|
|
||||||
"metadata": {}, "warnings": 1,
|
|
||||||
"signing_summary": {"trivial": 1, "low": 1,
|
|
||||||
"medium": 0, "high": 0},
|
|
||||||
"passed_auto_validation": 0}))
|
|
||||||
self.post()
|
|
||||||
file_ = File.objects.latest()
|
|
||||||
# Status is changed to fully reviewed and the file is signed.
|
|
||||||
assert self.addon.status == amo.STATUS_PUBLIC
|
|
||||||
assert file_.status == amo.STATUS_PUBLIC
|
|
||||||
assert mock_sign_file.called
|
|
||||||
# There is a log for that unlisted file signature (with failed
|
|
||||||
# validation).
|
|
||||||
log = ActivityLog.objects.order_by('pk').last()
|
|
||||||
expected = amo.LOG.UNLISTED_SIDELOAD_SIGNED_VALIDATION_FAILED.id
|
|
||||||
assert log.action == expected
|
|
||||||
|
|
||||||
@mock.patch('olympia.editors.helpers.sign_file')
|
|
||||||
def test_unlisted_addon_sideload_pass_validation(self, mock_sign_file):
|
|
||||||
"""Sideloadable unlisted addons also get auto signed/reviewed."""
|
|
||||||
assert self.addon.status == amo.STATUS_PUBLIC # Fully reviewed.
|
|
||||||
self.addon.update(is_listed=False)
|
|
||||||
# Make sure the file has no validation warnings nor errors.
|
|
||||||
self.upload.update(
|
|
||||||
validation=json.dumps({
|
|
||||||
"notices": 2, "errors": 0, "messages": [],
|
|
||||||
"metadata": {}, "warnings": 1,
|
|
||||||
"signing_summary": {"trivial": 1, "low": 0,
|
|
||||||
"medium": 0, "high": 0},
|
|
||||||
"passed_auto_validation": 1}))
|
|
||||||
self.post()
|
|
||||||
file_ = File.objects.latest()
|
|
||||||
# Status is changed to fully reviewed and the file is signed.
|
|
||||||
assert self.addon.status == amo.STATUS_PUBLIC
|
|
||||||
assert file_.status == amo.STATUS_PUBLIC
|
|
||||||
assert mock_sign_file.called
|
|
||||||
# There is a log for that unlisted file signature (with failed
|
|
||||||
# validation).
|
|
||||||
log = ActivityLog.objects.order_by('pk').last()
|
|
||||||
expected = amo.LOG.UNLISTED_SIDELOAD_SIGNED_VALIDATION_PASSED.id
|
|
||||||
assert log.action == expected
|
|
||||||
|
|
||||||
@mock.patch('olympia.editors.helpers.sign_file')
|
@mock.patch('olympia.editors.helpers.sign_file')
|
||||||
def test_unlisted_addon_fail_validation(self, mock_sign_file):
|
def test_unlisted_addon_fail_validation(self, mock_sign_file):
|
||||||
"""Files that fail validation are also auto signed/reviewed."""
|
"""Files that fail validation are also auto signed/reviewed."""
|
||||||
self.addon.update(
|
self.addon.update(
|
||||||
is_listed=False, status=amo.STATUS_LITE)
|
is_listed=False, status=amo.STATUS_PUBLIC)
|
||||||
assert self.addon.status == amo.STATUS_LITE # Preliminary reviewed.
|
assert self.addon.status == amo.STATUS_PUBLIC
|
||||||
# Make sure the file has validation warnings or errors.
|
# Make sure the file has validation warnings or errors.
|
||||||
self.upload.update(
|
self.upload.update(
|
||||||
validation=json.dumps({
|
validation=json.dumps({
|
||||||
|
@ -3213,9 +2924,9 @@ class TestAddVersion(AddVersionTest):
|
||||||
"passed_auto_validation": 0}))
|
"passed_auto_validation": 0}))
|
||||||
self.post()
|
self.post()
|
||||||
file_ = File.objects.latest()
|
file_ = File.objects.latest()
|
||||||
# Status is changed to preliminary reviewed and the file is signed.
|
# Status is changed to reviewed and the file is signed.
|
||||||
assert self.addon.status == amo.STATUS_LITE
|
assert self.addon.status == amo.STATUS_PUBLIC
|
||||||
assert file_.status == amo.STATUS_LITE
|
assert file_.status == amo.STATUS_PUBLIC
|
||||||
assert mock_sign_file.called
|
assert mock_sign_file.called
|
||||||
# There is a log for that unlisted file signature (with failed
|
# There is a log for that unlisted file signature (with failed
|
||||||
# validation).
|
# validation).
|
||||||
|
@ -3226,7 +2937,7 @@ class TestAddVersion(AddVersionTest):
|
||||||
def test_unlisted_addon_pass_validation(self, mock_sign_file):
|
def test_unlisted_addon_pass_validation(self, mock_sign_file):
|
||||||
"""Files that pass validation are automatically signed/reviewed."""
|
"""Files that pass validation are automatically signed/reviewed."""
|
||||||
self.addon.update(
|
self.addon.update(
|
||||||
is_listed=False, status=amo.STATUS_LITE)
|
is_listed=False, status=amo.STATUS_PUBLIC)
|
||||||
# Make sure the file has no validation warnings nor errors.
|
# Make sure the file has no validation warnings nor errors.
|
||||||
self.upload.update(
|
self.upload.update(
|
||||||
validation=json.dumps({
|
validation=json.dumps({
|
||||||
|
@ -3235,12 +2946,12 @@ class TestAddVersion(AddVersionTest):
|
||||||
"signing_summary": {"trivial": 1, "low": 0,
|
"signing_summary": {"trivial": 1, "low": 0,
|
||||||
"medium": 0, "high": 0},
|
"medium": 0, "high": 0},
|
||||||
"passed_auto_validation": 1}))
|
"passed_auto_validation": 1}))
|
||||||
assert self.addon.status == amo.STATUS_LITE # Preliminary reviewed.
|
assert self.addon.status == amo.STATUS_PUBLIC
|
||||||
self.post()
|
self.post()
|
||||||
file_ = File.objects.latest()
|
file_ = File.objects.latest()
|
||||||
# Status is changed to preliminary reviewed and the file is signed.
|
# Status is changed to reviewed and the file is signed.
|
||||||
assert self.addon.status == amo.STATUS_LITE
|
assert self.addon.status == amo.STATUS_PUBLIC
|
||||||
assert file_.status == amo.STATUS_LITE
|
assert file_.status == amo.STATUS_PUBLIC
|
||||||
assert mock_sign_file.called
|
assert mock_sign_file.called
|
||||||
# There is a log for that unlisted file signature (with passed
|
# There is a log for that unlisted file signature (with passed
|
||||||
# validation).
|
# validation).
|
||||||
|
@ -3428,10 +3139,10 @@ class TestVersionXSS(UploadTest):
|
||||||
class UploadAddon(object):
|
class UploadAddon(object):
|
||||||
|
|
||||||
def post(self, supported_platforms=[amo.PLATFORM_ALL], expect_errors=False,
|
def post(self, supported_platforms=[amo.PLATFORM_ALL], expect_errors=False,
|
||||||
source=None, is_listed=True, is_sideload=False, status_code=200):
|
source=None, is_listed=True, status_code=200):
|
||||||
d = dict(upload=self.upload.uuid.hex, source=source,
|
d = dict(upload=self.upload.uuid.hex, source=source,
|
||||||
supported_platforms=[p.id for p in supported_platforms],
|
supported_platforms=[p.id for p in supported_platforms],
|
||||||
is_unlisted=not is_listed, is_sideload=is_sideload)
|
is_unlisted=not is_listed)
|
||||||
r = self.client.post(self.url, d, follow=True)
|
r = self.client.post(self.url, d, follow=True)
|
||||||
assert r.status_code == status_code
|
assert r.status_code == status_code
|
||||||
if not expect_errors:
|
if not expect_errors:
|
||||||
|
@ -3514,7 +3225,7 @@ class TestCreateAddon(BaseUploadTest, UploadAddon, TestCase):
|
||||||
self.post(is_listed=False)
|
self.post(is_listed=False)
|
||||||
addon = Addon.with_unlisted.get()
|
addon = Addon.with_unlisted.get()
|
||||||
assert not addon.is_listed
|
assert not addon.is_listed
|
||||||
assert addon.status == amo.STATUS_LITE # Automatic signing.
|
assert addon.status == amo.STATUS_PUBLIC
|
||||||
assert mock_sign_file.called
|
assert mock_sign_file.called
|
||||||
|
|
||||||
@mock.patch('olympia.editors.helpers.sign_file')
|
@mock.patch('olympia.editors.helpers.sign_file')
|
||||||
|
@ -3532,56 +3243,6 @@ class TestCreateAddon(BaseUploadTest, UploadAddon, TestCase):
|
||||||
self.post(is_listed=False)
|
self.post(is_listed=False)
|
||||||
addon = Addon.with_unlisted.get()
|
addon = Addon.with_unlisted.get()
|
||||||
assert not addon.is_listed
|
assert not addon.is_listed
|
||||||
assert addon.status == amo.STATUS_LITE # Prelim review.
|
|
||||||
assert mock_sign_file.called
|
|
||||||
|
|
||||||
@override_flag('no-prelim-review', active=True)
|
|
||||||
@mock.patch('olympia.editors.helpers.sign_file')
|
|
||||||
def test_success_unlisted_no_prelim(self, mock_sign_file):
|
|
||||||
"""Sign automatically."""
|
|
||||||
assert Addon.with_unlisted.count() == 0
|
|
||||||
# No validation errors or warning.
|
|
||||||
self.upload = self.get_upload(
|
|
||||||
'extension.xpi',
|
|
||||||
validation=json.dumps(dict(errors=0, warnings=0, notices=2,
|
|
||||||
metadata={}, messages=[],
|
|
||||||
signing_summary={
|
|
||||||
'trivial': 1, 'low': 0, 'medium': 0,
|
|
||||||
'high': 0},
|
|
||||||
passed_auto_validation=True
|
|
||||||
)))
|
|
||||||
self.post(is_listed=False)
|
|
||||||
addon = Addon.with_unlisted.get()
|
|
||||||
assert not addon.is_listed
|
|
||||||
assert addon.status == amo.STATUS_PUBLIC # Automatic signing.
|
|
||||||
assert mock_sign_file.called
|
|
||||||
|
|
||||||
@override_flag('no-prelim-review', active=True)
|
|
||||||
@mock.patch('olympia.editors.helpers.sign_file')
|
|
||||||
def test_success_unlisted_fail_validation_no_prelim(self, mock_sign_file):
|
|
||||||
assert Addon.with_unlisted.count() == 0
|
|
||||||
self.upload = self.get_upload(
|
|
||||||
'extension.xpi',
|
|
||||||
validation=json.dumps(dict(errors=0, warnings=0, notices=2,
|
|
||||||
metadata={}, messages=[],
|
|
||||||
signing_summary={
|
|
||||||
'trivial': 0, 'low': 1, 'medium': 0,
|
|
||||||
'high': 0},
|
|
||||||
passed_auto_validation=False
|
|
||||||
)))
|
|
||||||
self.post(is_listed=False)
|
|
||||||
addon = Addon.with_unlisted.get()
|
|
||||||
assert not addon.is_listed
|
|
||||||
assert addon.status == amo.STATUS_PUBLIC
|
|
||||||
assert mock_sign_file.called
|
|
||||||
|
|
||||||
@mock.patch('olympia.editors.helpers.sign_file')
|
|
||||||
def test_success_unlisted_sideload(self, mock_sign_file):
|
|
||||||
assert Addon.with_unlisted.count() == 0
|
|
||||||
self.post(is_listed=False, is_sideload=True)
|
|
||||||
addon = Addon.with_unlisted.get()
|
|
||||||
assert not addon.is_listed
|
|
||||||
# Full review for sideload addons.
|
|
||||||
assert addon.status == amo.STATUS_PUBLIC
|
assert addon.status == amo.STATUS_PUBLIC
|
||||||
assert mock_sign_file.called
|
assert mock_sign_file.called
|
||||||
|
|
||||||
|
@ -3663,10 +3324,8 @@ class TestRequestReview(TestCase):
|
||||||
self.file = File.objects.create(version=self.version,
|
self.file = File.objects.create(version=self.version,
|
||||||
platform=amo.PLATFORM_ALL.id)
|
platform=amo.PLATFORM_ALL.id)
|
||||||
self.redirect_url = self.addon.get_dev_url('versions')
|
self.redirect_url = self.addon.get_dev_url('versions')
|
||||||
self.lite_url = reverse('devhub.request-review',
|
|
||||||
args=[self.addon.slug, amo.STATUS_LITE])
|
|
||||||
self.public_url = reverse('devhub.request-review',
|
self.public_url = reverse('devhub.request-review',
|
||||||
args=[self.addon.slug, amo.STATUS_PUBLIC])
|
args=[self.addon.slug])
|
||||||
assert self.client.login(username='admin@mozilla.com',
|
assert self.client.login(username='admin@mozilla.com',
|
||||||
password='password')
|
password='password')
|
||||||
|
|
||||||
|
@ -3686,40 +3345,8 @@ class TestRequestReview(TestCase):
|
||||||
r = self.client.post(url)
|
r = self.client.post(url)
|
||||||
assert r.status_code == 400
|
assert r.status_code == 400
|
||||||
|
|
||||||
def test_404(self):
|
|
||||||
bad_url = self.public_url.replace(str(amo.STATUS_PUBLIC), '0')
|
|
||||||
assert self.client.post(bad_url).status_code == 404
|
|
||||||
|
|
||||||
def test_public(self):
|
def test_public(self):
|
||||||
self.addon.update(status=amo.STATUS_PUBLIC)
|
self.addon.update(status=amo.STATUS_PUBLIC)
|
||||||
self.check_400(self.lite_url)
|
|
||||||
self.check_400(self.public_url)
|
|
||||||
|
|
||||||
def test_disabled_by_user_to_lite(self):
|
|
||||||
self.addon.update(disabled_by_user=True)
|
|
||||||
self.check_400(self.lite_url)
|
|
||||||
|
|
||||||
def test_disabled_by_admin(self):
|
|
||||||
self.addon.update(status=amo.STATUS_DISABLED)
|
|
||||||
self.check_400(self.lite_url)
|
|
||||||
|
|
||||||
def test_lite_to_lite(self):
|
|
||||||
self.addon.update(status=amo.STATUS_LITE)
|
|
||||||
self.check_400(self.lite_url)
|
|
||||||
|
|
||||||
def test_lite_to_public(self):
|
|
||||||
assert self.version.nomination is None
|
|
||||||
self.check(amo.STATUS_LITE, self.public_url,
|
|
||||||
amo.STATUS_LITE_AND_NOMINATED)
|
|
||||||
self.assertCloseToNow(self.get_version().nomination)
|
|
||||||
|
|
||||||
def test_lite_and_nominated_to_public(self):
|
|
||||||
self.addon.update(status=amo.STATUS_LITE_AND_NOMINATED)
|
|
||||||
self.check_400(self.public_url)
|
|
||||||
|
|
||||||
def test_lite_and_nominated(self):
|
|
||||||
self.addon.update(status=amo.STATUS_LITE_AND_NOMINATED)
|
|
||||||
self.check_400(self.lite_url)
|
|
||||||
self.check_400(self.public_url)
|
self.check_400(self.public_url)
|
||||||
|
|
||||||
def test_renominate_for_full_review(self):
|
def test_renominate_for_full_review(self):
|
||||||
|
@ -3736,14 +3363,14 @@ class TestRequestReview(TestCase):
|
||||||
|
|
||||||
def test_renomination_doesnt_reset_nomination_date(self):
|
def test_renomination_doesnt_reset_nomination_date(self):
|
||||||
# Nominate:
|
# Nominate:
|
||||||
self.addon.update(status=amo.STATUS_LITE_AND_NOMINATED)
|
self.addon.update(status=amo.STATUS_NOMINATED)
|
||||||
# Pretend it was nominated in the past:
|
# Pretend it was nominated in the past:
|
||||||
orig_date = datetime.now() - timedelta(days=30)
|
orig_date = datetime.now() - timedelta(days=30)
|
||||||
self.version.update(nomination=orig_date, _signal=False)
|
self.version.update(nomination=orig_date, _signal=False)
|
||||||
# Reject it:
|
# Reject it:
|
||||||
self.addon.update(status=amo.STATUS_NULL)
|
self.addon.update(status=amo.STATUS_NULL)
|
||||||
# Re-nominate:
|
# Re-nominate:
|
||||||
self.addon.update(status=amo.STATUS_LITE_AND_NOMINATED)
|
self.addon.update(status=amo.STATUS_NOMINATED)
|
||||||
assert self.get_version().nomination.timetuple()[0:5] == (
|
assert self.get_version().nomination.timetuple()[0:5] == (
|
||||||
orig_date.timetuple()[0:5])
|
orig_date.timetuple()[0:5])
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@ from django.test.utils import override_settings
|
||||||
import mock
|
import mock
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from pyquery import PyQuery as pq
|
from pyquery import PyQuery as pq
|
||||||
from waffle.testutils import override_flag
|
|
||||||
|
|
||||||
from olympia import amo
|
from olympia import amo
|
||||||
from olympia.amo.tests import TestCase
|
from olympia.amo.tests import TestCase
|
||||||
|
@ -504,14 +503,12 @@ class TestEditBasic(TestEdit):
|
||||||
activity_url)
|
activity_url)
|
||||||
assert doc('.view-stats').length == 1
|
assert doc('.view-stats').length == 1
|
||||||
|
|
||||||
@override_flag('no-prelim-review', active=True)
|
|
||||||
def test_not_experimental_flag(self):
|
def test_not_experimental_flag(self):
|
||||||
r = self.client.get(self.url)
|
r = self.client.get(self.url)
|
||||||
doc = pq(r.content)
|
doc = pq(r.content)
|
||||||
assert doc('#experimental-edit').text() == (
|
assert doc('#experimental-edit').text() == (
|
||||||
'This add-on is ready for general use.')
|
'This add-on is ready for general use.')
|
||||||
|
|
||||||
@override_flag('no-prelim-review', active=True)
|
|
||||||
def test_experimental_flag(self):
|
def test_experimental_flag(self):
|
||||||
self.get_addon().update(is_experimental=True)
|
self.get_addon().update(is_experimental=True)
|
||||||
r = self.client.get(self.url)
|
r = self.client.get(self.url)
|
||||||
|
@ -519,12 +516,6 @@ class TestEditBasic(TestEdit):
|
||||||
assert doc('#experimental-edit').text() == (
|
assert doc('#experimental-edit').text() == (
|
||||||
'This add-on is experimental.')
|
'This add-on is experimental.')
|
||||||
|
|
||||||
def test_experimental_flag_hidden(self):
|
|
||||||
# Shouldn't see anything with the waffle off.
|
|
||||||
r = self.client.get(self.url)
|
|
||||||
doc = pq(r.content)
|
|
||||||
assert not doc('#experimental-edit')
|
|
||||||
|
|
||||||
def get_l10n_urls(self):
|
def get_l10n_urls(self):
|
||||||
paths = ('devhub.addons.edit', 'devhub.addons.profile',
|
paths = ('devhub.addons.edit', 'devhub.addons.profile',
|
||||||
'devhub.addons.owner')
|
'devhub.addons.owner')
|
||||||
|
@ -1236,8 +1227,8 @@ class TestEditTechnical(TestEdit):
|
||||||
def test_dependencies_no_add_unreviewed_persona(self):
|
def test_dependencies_no_add_unreviewed_persona(self):
|
||||||
"""Ensure that unreviewed Personas cannot be made as dependencies."""
|
"""Ensure that unreviewed Personas cannot be made as dependencies."""
|
||||||
addon = Addon.objects.get(id=15663)
|
addon = Addon.objects.get(id=15663)
|
||||||
addon.update(status=amo.STATUS_UNREVIEWED)
|
addon.update(status=amo.STATUS_PENDING)
|
||||||
assert addon.status == amo.STATUS_UNREVIEWED
|
assert addon.status == amo.STATUS_PENDING
|
||||||
assert addon not in list(Addon.objects.reviewed())
|
assert addon not in list(Addon.objects.reviewed())
|
||||||
d = self.dep_formset({'dependent_addon': addon.id})
|
d = self.dep_formset({'dependent_addon': addon.id})
|
||||||
r = self.client.post(self.technical_edit_url, d)
|
r = self.client.post(self.technical_edit_url, d)
|
||||||
|
|
|
@ -350,21 +350,9 @@ class TestValidateAddon(TestCase):
|
||||||
self.client.post(self.url, {'upload': data})
|
self.client.post(self.url, {'upload': data})
|
||||||
# Make sure it was called with listed=False.
|
# Make sure it was called with listed=False.
|
||||||
assert not validate_mock.call_args[1]['listed']
|
assert not validate_mock.call_args[1]['listed']
|
||||||
# Automated signing enabled for unlisted, non-sideload add-ons.
|
# Automated signing enabled for unlisted add-ons.
|
||||||
assert FileUpload.objects.get().automated_signing is True
|
assert FileUpload.objects.get().automated_signing is True
|
||||||
|
|
||||||
@mock.patch('validator.validate.validate')
|
|
||||||
def test_upload_sideload_addon(self, validate_mock):
|
|
||||||
"""Sideload addons are validated as "self-hosted" addons."""
|
|
||||||
validate_mock.return_value = json.dumps(amo.VALIDATOR_SKELETON_RESULTS)
|
|
||||||
self.url = reverse('devhub.upload_sideload')
|
|
||||||
data = open(get_image_path('animated.png'), 'rb')
|
|
||||||
self.client.post(self.url, {'upload': data})
|
|
||||||
# Make sure it was called with listed=False.
|
|
||||||
assert not validate_mock.call_args[1]['listed']
|
|
||||||
# No automated signing for sideload add-ons.
|
|
||||||
assert FileUpload.objects.get().automated_signing is False
|
|
||||||
|
|
||||||
|
|
||||||
class TestUploadURLs(TestCase):
|
class TestUploadURLs(TestCase):
|
||||||
fixtures = ('base/users',)
|
fixtures = ('base/users',)
|
||||||
|
@ -427,9 +415,6 @@ class TestUploadURLs(TestCase):
|
||||||
self.upload('devhub.standalone_upload_unlisted'),
|
self.upload('devhub.standalone_upload_unlisted'),
|
||||||
self.expect_validation(listed=False, automated_signing=True)
|
self.expect_validation(listed=False, automated_signing=True)
|
||||||
|
|
||||||
self.upload('devhub.standalone_upload_sideload'),
|
|
||||||
self.expect_validation(listed=False, automated_signing=False)
|
|
||||||
|
|
||||||
def test_upload_submit(self):
|
def test_upload_submit(self):
|
||||||
"""Test that the add-on creation upload URLs result in file uploads
|
"""Test that the add-on creation upload URLs result in file uploads
|
||||||
with the correct flags."""
|
with the correct flags."""
|
||||||
|
@ -439,9 +424,6 @@ class TestUploadURLs(TestCase):
|
||||||
self.upload('devhub.upload_unlisted'),
|
self.upload('devhub.upload_unlisted'),
|
||||||
self.expect_validation(listed=False, automated_signing=True)
|
self.expect_validation(listed=False, automated_signing=True)
|
||||||
|
|
||||||
self.upload('devhub.upload_sideload'),
|
|
||||||
self.expect_validation(listed=False, automated_signing=False)
|
|
||||||
|
|
||||||
def test_upload_addon_version(self):
|
def test_upload_addon_version(self):
|
||||||
"""Test that the add-on update upload URLs result in file uploads
|
"""Test that the add-on update upload URLs result in file uploads
|
||||||
with the correct flags."""
|
with the correct flags."""
|
||||||
|
@ -449,9 +431,6 @@ class TestUploadURLs(TestCase):
|
||||||
self.upload_addon(listed=True, status=status)
|
self.upload_addon(listed=True, status=status)
|
||||||
self.expect_validation(listed=True, automated_signing=False)
|
self.expect_validation(listed=True, automated_signing=False)
|
||||||
|
|
||||||
self.upload_addon(listed=False, status=amo.STATUS_LITE)
|
|
||||||
self.expect_validation(listed=False, automated_signing=True)
|
|
||||||
|
|
||||||
self.upload_addon(listed=False, status=amo.STATUS_PUBLIC)
|
self.upload_addon(listed=False, status=amo.STATUS_PUBLIC)
|
||||||
self.expect_validation(listed=False, automated_signing=True)
|
self.expect_validation(listed=False, automated_signing=True)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ import re
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
from pyquery import PyQuery as pq
|
from pyquery import PyQuery as pq
|
||||||
from waffle.testutils import override_flag
|
|
||||||
|
|
||||||
from django.core.files import temp
|
from django.core.files import temp
|
||||||
|
|
||||||
|
@ -92,7 +91,7 @@ class TestVersion(TestCase):
|
||||||
|
|
||||||
def test_delete_message_if_bits_are_messy(self):
|
def test_delete_message_if_bits_are_messy(self):
|
||||||
"""Make sure we warn krupas of the pain they will feel."""
|
"""Make sure we warn krupas of the pain they will feel."""
|
||||||
self.addon.status = amo.STATUS_UNREVIEWED
|
self.addon.status = amo.STATUS_NOMINATED
|
||||||
self.addon.save()
|
self.addon.save()
|
||||||
|
|
||||||
r = self.client.get(self.url)
|
r = self.client.get(self.url)
|
||||||
|
@ -122,7 +121,7 @@ class TestVersion(TestCase):
|
||||||
action=amo.LOG.DELETE_VERSION.id).count() == 1
|
action=amo.LOG.DELETE_VERSION.id).count() == 1
|
||||||
|
|
||||||
def test_delete_version_then_detail(self):
|
def test_delete_version_then_detail(self):
|
||||||
version, file = self._extra_version_and_file(amo.STATUS_LITE)
|
version, file = self._extra_version_and_file(amo.STATUS_PUBLIC)
|
||||||
self.client.post(self.delete_url, self.delete_data)
|
self.client.post(self.delete_url, self.delete_data)
|
||||||
res = self.client.get(reverse('addons.detail', args=[self.addon.slug]))
|
res = self.client.get(reverse('addons.detail', args=[self.addon.slug]))
|
||||||
assert res.status_code == 200
|
assert res.status_code == 200
|
||||||
|
@ -151,7 +150,7 @@ class TestVersion(TestCase):
|
||||||
|
|
||||||
def test_reenable_version(self):
|
def test_reenable_version(self):
|
||||||
Version.objects.get(pk=81551).all_files[0].update(
|
Version.objects.get(pk=81551).all_files[0].update(
|
||||||
status=amo.STATUS_DISABLED, original_status=amo.STATUS_LITE)
|
status=amo.STATUS_DISABLED, original_status=amo.STATUS_PUBLIC)
|
||||||
self.reenable_url = reverse('devhub.versions.reenable', args=['a3615'])
|
self.reenable_url = reverse('devhub.versions.reenable', args=['a3615'])
|
||||||
response = self.client.post(
|
response = self.client.post(
|
||||||
self.reenable_url, self.delete_data, follow=True)
|
self.reenable_url, self.delete_data, follow=True)
|
||||||
|
@ -401,7 +400,7 @@ class TestVersion(TestCase):
|
||||||
def test_cancel_wrong_status(self):
|
def test_cancel_wrong_status(self):
|
||||||
cancel_url = reverse('devhub.addons.cancel', args=['a3615'])
|
cancel_url = reverse('devhub.addons.cancel', args=['a3615'])
|
||||||
for status in Addon.STATUS_CHOICES:
|
for status in Addon.STATUS_CHOICES:
|
||||||
if status in amo.UNDER_REVIEW_STATUSES + (amo.STATUS_DELETED,):
|
if status in (amo.STATUS_NOMINATED, amo.STATUS_DELETED):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.addon.update(status=status)
|
self.addon.update(status=status)
|
||||||
|
@ -410,14 +409,9 @@ class TestVersion(TestCase):
|
||||||
|
|
||||||
def test_cancel(self):
|
def test_cancel(self):
|
||||||
cancel_url = reverse('devhub.addons.cancel', args=['a3615'])
|
cancel_url = reverse('devhub.addons.cancel', args=['a3615'])
|
||||||
self.addon.update(status=amo.STATUS_LITE_AND_NOMINATED)
|
self.addon.update(status=amo.STATUS_NOMINATED)
|
||||||
self.client.post(cancel_url)
|
self.client.post(cancel_url)
|
||||||
assert Addon.objects.get(id=3615).status == amo.STATUS_LITE
|
assert Addon.objects.get(id=3615).status == amo.STATUS_NULL
|
||||||
|
|
||||||
for status in (amo.STATUS_UNREVIEWED, amo.STATUS_NOMINATED):
|
|
||||||
self.addon.update(status=status)
|
|
||||||
self.client.post(cancel_url)
|
|
||||||
assert Addon.objects.get(id=3615).status == amo.STATUS_NULL
|
|
||||||
|
|
||||||
def test_not_cancel(self):
|
def test_not_cancel(self):
|
||||||
self.client.logout()
|
self.client.logout()
|
||||||
|
@ -429,7 +423,7 @@ class TestVersion(TestCase):
|
||||||
|
|
||||||
def test_cancel_button(self):
|
def test_cancel_button(self):
|
||||||
for status in Addon.STATUS_CHOICES:
|
for status in Addon.STATUS_CHOICES:
|
||||||
if status not in amo.UNDER_REVIEW_STATUSES:
|
if status != amo.STATUS_NOMINATED:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.addon.update(status=status)
|
self.addon.update(status=status)
|
||||||
|
@ -440,23 +434,16 @@ class TestVersion(TestCase):
|
||||||
|
|
||||||
def test_not_cancel_button(self):
|
def test_not_cancel_button(self):
|
||||||
for status in Addon.STATUS_CHOICES:
|
for status in Addon.STATUS_CHOICES:
|
||||||
if status in amo.UNDER_REVIEW_STATUSES:
|
if status == amo.STATUS_NOMINATED:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.addon.update(status=status)
|
self.addon.update(status=status)
|
||||||
res = self.client.get(self.url)
|
res = self.client.get(self.url)
|
||||||
doc = pq(res.content)
|
doc = pq(res.content)
|
||||||
assert not doc('#cancel-review')
|
assert not doc('#cancel-review'), status
|
||||||
assert not doc('#modal-cancel')
|
assert not doc('#modal-cancel'), status
|
||||||
|
|
||||||
def test_incomplete_request_review(self):
|
def test_incomplete_request_review(self):
|
||||||
self.addon.update(status=amo.STATUS_NULL)
|
|
||||||
doc = pq(self.client.get(self.url).content)
|
|
||||||
buttons = doc('.version-status-actions form button').text()
|
|
||||||
assert buttons == 'Request Preliminary Review Request Full Review'
|
|
||||||
|
|
||||||
@override_flag('no-prelim-review', active=True)
|
|
||||||
def test_incomplete_request_review_no_prelim(self):
|
|
||||||
self.addon.update(status=amo.STATUS_NULL)
|
self.addon.update(status=amo.STATUS_NULL)
|
||||||
doc = pq(self.client.get(self.url).content)
|
doc = pq(self.client.get(self.url).content)
|
||||||
buttons = doc('.version-status-actions form button').text()
|
buttons = doc('.version-status-actions form button').text()
|
||||||
|
|
|
@ -14,12 +14,11 @@ PACKAGE_NAME = '(?P<package_name>[_\w]+)'
|
||||||
# These will all start with /addon/<addon_id>/submit/
|
# These will all start with /addon/<addon_id>/submit/
|
||||||
submit_patterns = patterns(
|
submit_patterns = patterns(
|
||||||
'',
|
'',
|
||||||
url('^$', lambda r, addon_id: redirect('devhub.submit.7', addon_id)),
|
url('^$', lambda r, addon_id: redirect('devhub.submit.6', addon_id)),
|
||||||
url('^3$', views.submit_describe, name='devhub.submit.3'),
|
url('^3$', views.submit_describe, name='devhub.submit.3'),
|
||||||
url('^4$', views.submit_media, name='devhub.submit.4'),
|
url('^4$', views.submit_media, name='devhub.submit.4'),
|
||||||
url('^5$', views.submit_license, name='devhub.submit.5'),
|
url('^5$', views.submit_license, name='devhub.submit.5'),
|
||||||
url('^6$', views.submit_select_review, name='devhub.submit.6'),
|
url('^6$', views.submit_done, name='devhub.submit.6'),
|
||||||
url('^7$', views.submit_done, name='devhub.submit.7'),
|
|
||||||
url('^bump$', views.submit_bump, name='devhub.submit.bump'),
|
url('^bump$', views.submit_bump, name='devhub.submit.bump'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -104,8 +103,7 @@ detail_patterns = patterns(
|
||||||
|
|
||||||
url('^submit/', include(submit_patterns)),
|
url('^submit/', include(submit_patterns)),
|
||||||
url('^submit/resume$', views.submit_resume, name='devhub.submit.resume'),
|
url('^submit/resume$', views.submit_resume, name='devhub.submit.resume'),
|
||||||
url('^request-review/(?P<status>[%s])$'
|
url('^request-review$',
|
||||||
% ''.join(map(str, views.REQUEST_REVIEW)),
|
|
||||||
views.request_review, name='devhub.request-review'),
|
views.request_review, name='devhub.request-review'),
|
||||||
url('^rmlocale$', views.remove_locale, name='devhub.addons.remove-locale'),
|
url('^rmlocale$', views.remove_locale, name='devhub.addons.remove-locale'),
|
||||||
)
|
)
|
||||||
|
@ -178,8 +176,6 @@ urlpatterns = decorate(write, patterns(
|
||||||
url('^feed/%s$' % ADDON_ID, views.feed, name='devhub.feed'),
|
url('^feed/%s$' % ADDON_ID, views.feed, name='devhub.feed'),
|
||||||
|
|
||||||
url('^upload$', views.upload, name='devhub.upload'),
|
url('^upload$', views.upload, name='devhub.upload'),
|
||||||
url('^upload/sideload$', partial(views.upload, is_listed=False),
|
|
||||||
name='devhub.upload_sideload'),
|
|
||||||
url('^upload/unlisted$',
|
url('^upload/unlisted$',
|
||||||
partial(views.upload, is_listed=False, automated=True),
|
partial(views.upload, is_listed=False, automated=True),
|
||||||
name='devhub.upload_unlisted'),
|
name='devhub.upload_unlisted'),
|
||||||
|
@ -194,10 +190,6 @@ urlpatterns = decorate(write, patterns(
|
||||||
partial(views.upload, is_standalone=True, is_listed=False,
|
partial(views.upload, is_standalone=True, is_listed=False,
|
||||||
automated=True),
|
automated=True),
|
||||||
name='devhub.standalone_upload_unlisted'),
|
name='devhub.standalone_upload_unlisted'),
|
||||||
url('^standalone-upload-sideload$',
|
|
||||||
partial(views.upload, is_standalone=True, is_listed=False),
|
|
||||||
name='devhub.standalone_upload_sideload'),
|
|
||||||
|
|
||||||
url('^standalone-upload/([^/]+)$', views.standalone_upload_detail,
|
url('^standalone-upload/([^/]+)$', views.standalone_upload_detail,
|
||||||
name='devhub.standalone_upload_detail'),
|
name='devhub.standalone_upload_detail'),
|
||||||
|
|
||||||
|
|
|
@ -314,8 +314,6 @@ class ValidationAnnotator(object):
|
||||||
return
|
return
|
||||||
|
|
||||||
version = Version(version)
|
version = Version(version)
|
||||||
statuses = (amo.STATUS_PUBLIC, amo.STATUS_LITE)
|
|
||||||
|
|
||||||
# Find any previous version of this add-on with the correct status
|
# Find any previous version of this add-on with the correct status
|
||||||
# to match the given file.
|
# to match the given file.
|
||||||
files = File.objects.filter(version__addon=self.addon)
|
files = File.objects.filter(version__addon=self.addon)
|
||||||
|
@ -325,13 +323,9 @@ class ValidationAnnotator(object):
|
||||||
# TODO: We'll also need to implement this for FileUploads
|
# TODO: We'll also need to implement this for FileUploads
|
||||||
# when we can accurately determine whether a new upload
|
# when we can accurately determine whether a new upload
|
||||||
# is a beta version.
|
# is a beta version.
|
||||||
if self.addon.status in (amo.STATUS_PUBLIC, amo.STATUS_NOMINATED,
|
files = files.filter(status=amo.STATUS_PUBLIC)
|
||||||
amo.STATUS_LITE_AND_NOMINATED):
|
|
||||||
files = files.filter(status=amo.STATUS_PUBLIC)
|
|
||||||
else:
|
|
||||||
files = files.filter(status__in=statuses)
|
|
||||||
else:
|
else:
|
||||||
files = files.filter(Q(status__in=statuses) |
|
files = files.filter(Q(status=amo.STATUS_PUBLIC) |
|
||||||
Q(status=amo.STATUS_BETA, is_signed=True))
|
Q(status=amo.STATUS_BETA, is_signed=True))
|
||||||
|
|
||||||
if self.file:
|
if self.file:
|
||||||
|
|
|
@ -20,7 +20,6 @@ from django.views.decorators.cache import never_cache
|
||||||
from django.views.decorators.csrf import csrf_exempt
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
|
|
||||||
import commonware.log
|
import commonware.log
|
||||||
import waffle
|
|
||||||
from django_statsd.clients import statsd
|
from django_statsd.clients import statsd
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
|
@ -380,11 +379,8 @@ def enable(request, addon_id, addon):
|
||||||
@dev_required(owner_for_post=True)
|
@dev_required(owner_for_post=True)
|
||||||
@post_required
|
@post_required
|
||||||
def cancel(request, addon_id, addon):
|
def cancel(request, addon_id, addon):
|
||||||
if addon.status in amo.UNDER_REVIEW_STATUSES:
|
if addon.status == amo.STATUS_NOMINATED:
|
||||||
if addon.status == amo.STATUS_LITE_AND_NOMINATED:
|
addon.update(status=amo.STATUS_NULL)
|
||||||
addon.update(status=amo.STATUS_LITE)
|
|
||||||
else:
|
|
||||||
addon.update(status=amo.STATUS_NULL)
|
|
||||||
amo.log(amo.LOG.CHANGE_STATUS, addon.get_status_display(), addon)
|
amo.log(amo.LOG.CHANGE_STATUS, addon.get_status_display(), addon)
|
||||||
return redirect(addon.get_dev_url('versions'))
|
return redirect(addon.get_dev_url('versions'))
|
||||||
|
|
||||||
|
@ -607,7 +603,7 @@ def check_addon_compatibility(request):
|
||||||
|
|
||||||
def handle_upload(filedata, user, app_id=None, version_id=None, addon=None,
|
def handle_upload(filedata, user, app_id=None, version_id=None, addon=None,
|
||||||
is_standalone=False, is_listed=True, automated=False,
|
is_standalone=False, is_listed=True, automated=False,
|
||||||
submit=False, disallow_preliminary_review=False):
|
submit=False):
|
||||||
if addon:
|
if addon:
|
||||||
# TODO: Handle betas.
|
# TODO: Handle betas.
|
||||||
automated = addon.automated_signing
|
automated = addon.automated_signing
|
||||||
|
@ -626,9 +622,7 @@ def handle_upload(filedata, user, app_id=None, version_id=None, addon=None,
|
||||||
ver = get_object_or_404(AppVersion, pk=version_id)
|
ver = get_object_or_404(AppVersion, pk=version_id)
|
||||||
tasks.compatibility_check.delay(upload.pk, app.guid, ver.version)
|
tasks.compatibility_check.delay(upload.pk, app.guid, ver.version)
|
||||||
elif submit:
|
elif submit:
|
||||||
tasks.validate_and_submit(
|
tasks.validate_and_submit(addon, upload, listed=is_listed)
|
||||||
addon, upload, listed=is_listed,
|
|
||||||
disallow_preliminary_review=disallow_preliminary_review)
|
|
||||||
else:
|
else:
|
||||||
tasks.validate(upload, listed=is_listed)
|
tasks.validate(upload, listed=is_listed)
|
||||||
|
|
||||||
|
@ -642,12 +636,10 @@ def upload(request, addon=None, is_standalone=False, is_listed=True,
|
||||||
filedata = request.FILES['upload']
|
filedata = request.FILES['upload']
|
||||||
app_id = request.POST.get('app_id')
|
app_id = request.POST.get('app_id')
|
||||||
version_id = request.POST.get('version_id')
|
version_id = request.POST.get('version_id')
|
||||||
no_prelim = waffle.flag_is_active(request, 'no-prelim-review')
|
|
||||||
upload = handle_upload(
|
upload = handle_upload(
|
||||||
filedata=filedata, user=request.user, app_id=app_id,
|
filedata=filedata, user=request.user, app_id=app_id,
|
||||||
version_id=version_id, addon=addon, is_standalone=is_standalone,
|
version_id=version_id, addon=addon, is_standalone=is_standalone,
|
||||||
is_listed=is_listed, automated=automated,
|
is_listed=is_listed, automated=automated)
|
||||||
disallow_preliminary_review=no_prelim)
|
|
||||||
if addon:
|
if addon:
|
||||||
return redirect('devhub.upload_detail_for_addon',
|
return redirect('devhub.upload_detail_for_addon',
|
||||||
addon.slug, upload.uuid.hex)
|
addon.slug, upload.uuid.hex)
|
||||||
|
@ -1174,7 +1166,7 @@ def version_edit(request, addon_id, addon, version_id):
|
||||||
return redirect('devhub.versions.edit', addon.slug, version_id)
|
return redirect('devhub.versions.edit', addon.slug, version_id)
|
||||||
|
|
||||||
data.update(addon=addon, version=version, new_file_form=new_file_form,
|
data.update(addon=addon, version=version, new_file_form=new_file_form,
|
||||||
is_admin=is_admin)
|
is_admin=is_admin, choices=File.STATUS_CHOICES)
|
||||||
return render(request, 'devhub/versions/edit.html', data)
|
return render(request, 'devhub/versions/edit.html', data)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1249,20 +1241,11 @@ def auto_sign_file(file_, is_beta=False):
|
||||||
# Provide the file to review/sign to the helper.
|
# Provide the file to review/sign to the helper.
|
||||||
helper.set_data({'addon_files': [file_],
|
helper.set_data({'addon_files': [file_],
|
||||||
'comments': 'automatic validation'})
|
'comments': 'automatic validation'})
|
||||||
if addon.is_sideload:
|
helper.handler.process_public(auto_validation=True)
|
||||||
helper.handler.process_public(auto_validation=True)
|
if validation.passed_auto_validation:
|
||||||
if validation.passed_auto_validation:
|
amo.log(amo.LOG.UNLISTED_SIGNED_VALIDATION_PASSED, file_)
|
||||||
amo.log(amo.LOG.UNLISTED_SIDELOAD_SIGNED_VALIDATION_PASSED,
|
|
||||||
file_)
|
|
||||||
else:
|
|
||||||
amo.log(amo.LOG.UNLISTED_SIDELOAD_SIGNED_VALIDATION_FAILED,
|
|
||||||
file_)
|
|
||||||
else:
|
else:
|
||||||
helper.handler.process_preliminary(auto_validation=True)
|
amo.log(amo.LOG.UNLISTED_SIGNED_VALIDATION_FAILED, file_)
|
||||||
if validation.passed_auto_validation:
|
|
||||||
amo.log(amo.LOG.UNLISTED_SIGNED_VALIDATION_PASSED, file_)
|
|
||||||
else:
|
|
||||||
amo.log(amo.LOG.UNLISTED_SIGNED_VALIDATION_FAILED, file_)
|
|
||||||
|
|
||||||
|
|
||||||
def auto_sign_version(version, **kwargs):
|
def auto_sign_version(version, **kwargs):
|
||||||
|
@ -1306,12 +1289,8 @@ def version_add(request, addon_id, addon):
|
||||||
log.info('Version created: %s for: %s' %
|
log.info('Version created: %s for: %s' %
|
||||||
(version.pk, form.cleaned_data['upload']))
|
(version.pk, form.cleaned_data['upload']))
|
||||||
check_validation_override(request, form, addon, version)
|
check_validation_override(request, form, addon, version)
|
||||||
if waffle.flag_is_active(request, 'no-prelim-review'):
|
if addon.status == amo.STATUS_NULL:
|
||||||
if addon.status == amo.STATUS_NULL:
|
addon.update(status=amo.STATUS_NOMINATED)
|
||||||
addon.update(status=amo.STATUS_NOMINATED)
|
|
||||||
elif (addon.status == amo.STATUS_NULL and
|
|
||||||
form.cleaned_data['nomination_type']):
|
|
||||||
addon.update(status=form.cleaned_data['nomination_type'])
|
|
||||||
url = reverse('devhub.versions.edit',
|
url = reverse('devhub.versions.edit',
|
||||||
args=[addon.slug, str(version.id)])
|
args=[addon.slug, str(version.id)])
|
||||||
|
|
||||||
|
@ -1346,7 +1325,8 @@ def version_add_file(request, addon_id, addon, version_id):
|
||||||
auto_sign_file(new_file, is_beta=is_beta)
|
auto_sign_file(new_file, is_beta=is_beta)
|
||||||
|
|
||||||
return render(request, 'devhub/includes/version_file.html',
|
return render(request, 'devhub/includes/version_file.html',
|
||||||
{'form': form[0], 'addon': addon})
|
{'form': form[0], 'addon': addon,
|
||||||
|
'choices': File.STATUS_CHOICES})
|
||||||
|
|
||||||
|
|
||||||
@dev_required
|
@dev_required
|
||||||
|
@ -1405,7 +1385,7 @@ def submit_step(outer_step):
|
||||||
@functools.wraps(f)
|
@functools.wraps(f)
|
||||||
def wrapper(request, *args, **kw):
|
def wrapper(request, *args, **kw):
|
||||||
step = outer_step
|
step = outer_step
|
||||||
max_step = 7
|
max_step = 6
|
||||||
# We only bounce on pages with an addon id.
|
# We only bounce on pages with an addon id.
|
||||||
if 'addon' in kw:
|
if 'addon' in kw:
|
||||||
addon = kw['addon']
|
addon = kw['addon']
|
||||||
|
@ -1417,7 +1397,7 @@ def submit_step(outer_step):
|
||||||
return redirect(_step_url(max_step), addon.slug)
|
return redirect(_step_url(max_step), addon.slug)
|
||||||
elif step != max_step:
|
elif step != max_step:
|
||||||
# We couldn't find a step, so we must be done.
|
# We couldn't find a step, so we must be done.
|
||||||
return redirect(_step_url(7), addon.slug)
|
return redirect(_step_url(6), addon.slug)
|
||||||
kw['step'] = Step(step, max_step)
|
kw['step'] = Step(step, max_step)
|
||||||
return f(request, *args, **kw)
|
return f(request, *args, **kw)
|
||||||
# Tell @dev_required that this is a function in the submit flow so it
|
# Tell @dev_required that this is a function in the submit flow so it
|
||||||
|
@ -1464,11 +1444,7 @@ def submit_addon(request, step):
|
||||||
check_validation_override(request, form, addon,
|
check_validation_override(request, form, addon,
|
||||||
addon.current_version)
|
addon.current_version)
|
||||||
if not addon.is_listed: # Not listed? Automatically choose queue.
|
if not addon.is_listed: # Not listed? Automatically choose queue.
|
||||||
no_prelim = waffle.flag_is_active(request, 'no-prelim-review')
|
addon.update(status=amo.STATUS_NOMINATED)
|
||||||
if data.get('is_sideload') or no_prelim: # Full review needed.
|
|
||||||
addon.update(status=amo.STATUS_NOMINATED)
|
|
||||||
else: # Otherwise, simply do a prelim review.
|
|
||||||
addon.update(status=amo.STATUS_UNREVIEWED)
|
|
||||||
# Sign all the files submitted, one for each platform.
|
# Sign all the files submitted, one for each platform.
|
||||||
auto_sign_version(addon.versions.get())
|
auto_sign_version(addon.versions.get())
|
||||||
SubmitStep.objects.create(addon=addon, step=3)
|
SubmitStep.objects.create(addon=addon, step=3)
|
||||||
|
@ -1498,7 +1474,7 @@ def submit_describe(request, addon_id, addon, step):
|
||||||
else: # Finished for unlisted addons.
|
else: # Finished for unlisted addons.
|
||||||
submit_step.delete()
|
submit_step.delete()
|
||||||
signals.submission_done.send(sender=addon)
|
signals.submission_done.send(sender=addon)
|
||||||
return redirect('devhub.submit.7', addon.slug)
|
return redirect('devhub.submit.6', addon.slug)
|
||||||
return render(request, 'devhub/addons/submit/describe.html',
|
return render(request, 'devhub/addons/submit/describe.html',
|
||||||
{'form': form, 'cat_form': cat_form, 'addon': addon,
|
{'form': form, 'cat_form': cat_form, 'addon': addon,
|
||||||
'step': step})
|
'step': step})
|
||||||
|
@ -1545,14 +1521,11 @@ def submit_license(request, addon_id, addon, step):
|
||||||
if license_form in fs:
|
if license_form in fs:
|
||||||
license_form.save(log=False)
|
license_form.save(log=False)
|
||||||
policy_form.save()
|
policy_form.save()
|
||||||
if waffle.flag_is_active(request, 'no-prelim-review'):
|
|
||||||
addon.update(status=amo.STATUS_NOMINATED)
|
addon.update(status=amo.STATUS_NOMINATED)
|
||||||
SubmitStep.objects.filter(addon=addon).delete()
|
SubmitStep.objects.filter(addon=addon).delete()
|
||||||
signals.submission_done.send(sender=addon)
|
signals.submission_done.send(sender=addon)
|
||||||
return redirect('devhub.submit.7', addon.slug)
|
return redirect('devhub.submit.6', addon.slug)
|
||||||
else:
|
|
||||||
SubmitStep.objects.filter(addon=addon).update(step=6)
|
|
||||||
return redirect('devhub.submit.6', addon.slug)
|
|
||||||
ctx.update(addon=addon, policy_form=policy_form, step=step)
|
ctx.update(addon=addon, policy_form=policy_form, step=step)
|
||||||
|
|
||||||
return render(request, 'devhub/addons/submit/license.html', ctx)
|
return render(request, 'devhub/addons/submit/license.html', ctx)
|
||||||
|
@ -1560,26 +1533,6 @@ def submit_license(request, addon_id, addon, step):
|
||||||
|
|
||||||
@dev_required
|
@dev_required
|
||||||
@submit_step(6)
|
@submit_step(6)
|
||||||
def submit_select_review(request, addon_id, addon, step):
|
|
||||||
review_type_form = forms.ReviewTypeForm(request.POST or None)
|
|
||||||
updated_status = None
|
|
||||||
|
|
||||||
if request.method == 'POST' and review_type_form.is_valid():
|
|
||||||
updated_status = review_type_form.cleaned_data['review_type']
|
|
||||||
|
|
||||||
if updated_status:
|
|
||||||
addon.update(status=updated_status)
|
|
||||||
SubmitStep.objects.filter(addon=addon).delete()
|
|
||||||
signals.submission_done.send(sender=addon)
|
|
||||||
return redirect('devhub.submit.7', addon.slug)
|
|
||||||
|
|
||||||
return render(request, 'devhub/addons/submit/select-review.html',
|
|
||||||
{'addon': addon, 'review_type_form': review_type_form,
|
|
||||||
'step': step})
|
|
||||||
|
|
||||||
|
|
||||||
@dev_required
|
|
||||||
@submit_step(7)
|
|
||||||
def submit_done(request, addon_id, addon, step):
|
def submit_done(request, addon_id, addon, step):
|
||||||
# Bounce to the versions page if they don't have any versions.
|
# Bounce to the versions page if they don't have any versions.
|
||||||
if not addon.versions.exists():
|
if not addon.versions.exists():
|
||||||
|
@ -1689,32 +1642,15 @@ def remove_locale(request, addon_id, addon, theme):
|
||||||
return http.HttpResponseBadRequest()
|
return http.HttpResponseBadRequest()
|
||||||
|
|
||||||
|
|
||||||
# You can only request one of the new review tracks.
|
|
||||||
REQUEST_REVIEW = (amo.STATUS_PUBLIC, amo.STATUS_LITE)
|
|
||||||
|
|
||||||
|
|
||||||
@dev_required
|
@dev_required
|
||||||
@post_required
|
@post_required
|
||||||
def request_review(request, addon_id, addon, status):
|
def request_review(request, addon_id, addon):
|
||||||
status_req = int(status)
|
if amo.STATUS_PUBLIC not in addon.can_request_review(
|
||||||
no_prelim = waffle.flag_is_active(request, 'no-prelim-review')
|
disallow_preliminary_review=True):
|
||||||
if status_req not in addon.can_request_review(no_prelim):
|
|
||||||
return http.HttpResponseBadRequest()
|
return http.HttpResponseBadRequest()
|
||||||
elif status_req == amo.STATUS_PUBLIC:
|
|
||||||
if addon.status == amo.STATUS_LITE:
|
|
||||||
new_status = amo.STATUS_LITE_AND_NOMINATED
|
|
||||||
else:
|
|
||||||
new_status = amo.STATUS_NOMINATED
|
|
||||||
elif status_req == amo.STATUS_LITE:
|
|
||||||
if addon.status in (amo.STATUS_PUBLIC, amo.STATUS_LITE_AND_NOMINATED):
|
|
||||||
new_status = amo.STATUS_LITE
|
|
||||||
else:
|
|
||||||
new_status = amo.STATUS_UNREVIEWED
|
|
||||||
|
|
||||||
addon.update(status=new_status)
|
addon.update(status=amo.STATUS_NOMINATED)
|
||||||
msg = {amo.STATUS_LITE: _('Preliminary Review Requested.'),
|
messages.success(request, _('Full Review Requested.'))
|
||||||
amo.STATUS_PUBLIC: _('Full Review Requested.')}
|
|
||||||
messages.success(request, msg[status_req])
|
|
||||||
amo.log(amo.LOG.CHANGE_STATUS, addon.get_status_display(), addon)
|
amo.log(amo.LOG.CHANGE_STATUS, addon.get_status_display(), addon)
|
||||||
return redirect(addon.get_dev_url('versions'))
|
return redirect(addon.get_dev_url('versions'))
|
||||||
|
|
||||||
|
|
|
@ -173,7 +173,7 @@ class File(OnChangeMixin, ModelBase):
|
||||||
file_.is_experiment = parse_data.get('is_experiment', False)
|
file_.is_experiment = parse_data.get('is_experiment', False)
|
||||||
file_.is_webextension = parse_data.get('is_webextension', False)
|
file_.is_webextension = parse_data.get('is_webextension', False)
|
||||||
|
|
||||||
if is_beta and addon.status == amo.STATUS_PUBLIC:
|
if is_beta and addon.status == amo.STATUS_PUBLIC and addon.is_listed:
|
||||||
file_.status = amo.STATUS_BETA
|
file_.status = amo.STATUS_BETA
|
||||||
|
|
||||||
file_.hash = file_.generate_hash(upload.path)
|
file_.hash = file_.generate_hash(upload.path)
|
||||||
|
|
|
@ -112,7 +112,7 @@ class TestUploadVersion(BaseUploadVersionCase):
|
||||||
addon = qs.get()
|
addon = qs.get()
|
||||||
assert addon.has_author(self.user)
|
assert addon.has_author(self.user)
|
||||||
assert not addon.is_listed
|
assert not addon.is_listed
|
||||||
assert addon.status == amo.STATUS_LITE
|
assert addon.status == amo.STATUS_NOMINATED
|
||||||
self.auto_sign_version.assert_called_with(
|
self.auto_sign_version.assert_called_with(
|
||||||
addon.latest_version, is_beta=False)
|
addon.latest_version, is_beta=False)
|
||||||
|
|
||||||
|
@ -211,7 +211,7 @@ class TestUploadVersion(BaseUploadVersionCase):
|
||||||
addon = qs.get()
|
addon = qs.get()
|
||||||
assert addon.has_author(self.user)
|
assert addon.has_author(self.user)
|
||||||
assert not addon.is_listed
|
assert not addon.is_listed
|
||||||
assert addon.status == amo.STATUS_LITE
|
assert addon.status == amo.STATUS_NOMINATED
|
||||||
self.auto_sign_version.assert_called_with(
|
self.auto_sign_version.assert_called_with(
|
||||||
addon.latest_version, is_beta=False)
|
addon.latest_version, is_beta=False)
|
||||||
|
|
||||||
|
@ -230,7 +230,7 @@ class TestUploadVersion(BaseUploadVersionCase):
|
||||||
|
|
||||||
def test_version_is_beta_unlisted(self):
|
def test_version_is_beta_unlisted(self):
|
||||||
Addon.objects.get(guid=self.guid).update(
|
Addon.objects.get(guid=self.guid).update(
|
||||||
status=amo.STATUS_LITE, is_listed=False)
|
status=amo.STATUS_PUBLIC, is_listed=False)
|
||||||
version_string = '4.0-beta1'
|
version_string = '4.0-beta1'
|
||||||
qs = Version.objects.filter(
|
qs = Version.objects.filter(
|
||||||
addon__guid=self.guid, version=version_string)
|
addon__guid=self.guid, version=version_string)
|
||||||
|
@ -246,7 +246,7 @@ class TestUploadVersion(BaseUploadVersionCase):
|
||||||
assert version.addon.guid == self.guid
|
assert version.addon.guid == self.guid
|
||||||
assert version.version == version_string
|
assert version.version == version_string
|
||||||
assert version.statuses[0][1] == amo.STATUS_UNREVIEWED
|
assert version.statuses[0][1] == amo.STATUS_UNREVIEWED
|
||||||
assert version.addon.status == amo.STATUS_LITE
|
assert version.addon.status == amo.STATUS_PUBLIC
|
||||||
assert not version.is_beta
|
assert not version.is_beta
|
||||||
self.auto_sign_version.assert_called_with(version, is_beta=False)
|
self.auto_sign_version.assert_called_with(version, is_beta=False)
|
||||||
|
|
||||||
|
@ -355,7 +355,7 @@ class TestUploadVersionWebextension(BaseUploadVersionCase):
|
||||||
assert version.files.all()[0].is_webextension is True
|
assert version.files.all()[0].is_webextension is True
|
||||||
assert addon.has_author(self.user)
|
assert addon.has_author(self.user)
|
||||||
assert not addon.is_listed
|
assert not addon.is_listed
|
||||||
assert addon.status == amo.STATUS_LITE
|
assert addon.status == amo.STATUS_NOMINATED
|
||||||
self.auto_sign_version.assert_called_with(
|
self.auto_sign_version.assert_called_with(
|
||||||
addon.latest_version, is_beta=False)
|
addon.latest_version, is_beta=False)
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ from django import forms
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
import waffle
|
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
from rest_framework.permissions import IsAuthenticated
|
from rest_framework.permissions import IsAuthenticated
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
@ -156,10 +155,8 @@ class VersionView(APIView):
|
||||||
else:
|
else:
|
||||||
created = False
|
created = False
|
||||||
|
|
||||||
no_prelim = waffle.flag_is_active(request, 'no-prelim-review')
|
|
||||||
file_upload = handle_upload(
|
file_upload = handle_upload(
|
||||||
filedata=filedata, user=request.user, addon=addon, submit=True,
|
filedata=filedata, user=request.user, addon=addon, submit=True)
|
||||||
disallow_preliminary_review=no_prelim)
|
|
||||||
|
|
||||||
return file_upload, created
|
return file_upload, created
|
||||||
|
|
||||||
|
|
|
@ -303,7 +303,6 @@
|
||||||
|
|
||||||
var $newForm = $('.new-addon-file');
|
var $newForm = $('.new-addon-file');
|
||||||
var $isUnlistedCheckbox = $('#id_is_unlisted');
|
var $isUnlistedCheckbox = $('#id_is_unlisted');
|
||||||
var $isSideloadCheckbox = $('#id_is_sideload');
|
|
||||||
|
|
||||||
function isUnlisted() {
|
function isUnlisted() {
|
||||||
// True if there's a '#id_is_unlisted' checkbox that is checked, or a
|
// True if there's a '#id_is_unlisted' checkbox that is checked, or a
|
||||||
|
@ -312,19 +311,11 @@
|
||||||
(typeof($newForm.data('addon-is-listed')) != 'undefined' && !$newForm.data('addon-is-listed')));
|
(typeof($newForm.data('addon-is-listed')) != 'undefined' && !$newForm.data('addon-is-listed')));
|
||||||
}
|
}
|
||||||
|
|
||||||
function isSideload() {
|
|
||||||
// True if there's a '#id_is_sideload' checkbox that is checked, or a
|
|
||||||
// 'addon-is-sideload' data on the new file form that is true.
|
|
||||||
return (($isSideloadCheckbox.length && $isSideloadCheckbox.is(':checked')) ||
|
|
||||||
(typeof($newForm.data('addon-is-sideload')) != 'undefined' && $newForm.data('addon-is-sideload')));
|
|
||||||
}
|
|
||||||
|
|
||||||
// is_unlisted checkbox: should the add-on be listed on AMO? If not,
|
// is_unlisted checkbox: should the add-on be listed on AMO? If not,
|
||||||
// change the addon upload button's data-upload-url.
|
// change the addon upload button's data-upload-url.
|
||||||
// If this add-on is unlisted, then tell the upload view so
|
// If this add-on is unlisted, then tell the upload view so
|
||||||
// it'll run the validator with the "listed=False"
|
// it'll run the validator with the "listed=False"
|
||||||
// parameter.
|
// parameter.
|
||||||
var $isSideloadLabel = $('label[for=id_is_sideload]');
|
|
||||||
var $submitAddonProgress = $('.submit-addon-progress');
|
var $submitAddonProgress = $('.submit-addon-progress');
|
||||||
function updateListedStatus() {
|
function updateListedStatus() {
|
||||||
if (!isUnlisted()) { // It's a listed add-on.
|
if (!isUnlisted()) { // It's a listed add-on.
|
||||||
|
@ -334,16 +325,9 @@
|
||||||
// doesn't upload to the correct url. Using
|
// doesn't upload to the correct url. Using
|
||||||
// .attr('data-upload-url', val) instead fixes that.
|
// .attr('data-upload-url', val) instead fixes that.
|
||||||
$upload_field.attr('data-upload-url', $upload_field.data('upload-url-listed'));
|
$upload_field.attr('data-upload-url', $upload_field.data('upload-url-listed'));
|
||||||
$isSideloadLabel.hide();
|
|
||||||
$isSideloadCheckbox.prop('checked', false);
|
|
||||||
$submitAddonProgress.removeClass('unlisted');
|
$submitAddonProgress.removeClass('unlisted');
|
||||||
} else { // It's an unlisted add-on.
|
} else { // It's an unlisted add-on.
|
||||||
if (isSideload()) { // It's a sideload add-on.
|
$upload_field.attr('data-upload-url', $upload_field.data('upload-url-unlisted'));
|
||||||
$upload_field.attr('data-upload-url', $upload_field.data('upload-url-sideload'));
|
|
||||||
} else {
|
|
||||||
$upload_field.attr('data-upload-url', $upload_field.data('upload-url-unlisted'));
|
|
||||||
}
|
|
||||||
$isSideloadLabel.show();
|
|
||||||
$submitAddonProgress.addClass('unlisted');
|
$submitAddonProgress.addClass('unlisted');
|
||||||
}
|
}
|
||||||
/* Don't allow submitting, need to reupload/revalidate the file. */
|
/* Don't allow submitting, need to reupload/revalidate the file. */
|
||||||
|
@ -353,7 +337,6 @@
|
||||||
$('.upload-status').remove();
|
$('.upload-status').remove();
|
||||||
}
|
}
|
||||||
$isUnlistedCheckbox.bind('change', updateListedStatus);
|
$isUnlistedCheckbox.bind('change', updateListedStatus);
|
||||||
$isSideloadCheckbox.bind('change', updateListedStatus);
|
|
||||||
updateListedStatus();
|
updateListedStatus();
|
||||||
|
|
||||||
$('#id_is_manual_review').bind('change', function() {
|
$('#id_is_manual_review').bind('change', function() {
|
||||||
|
@ -444,7 +427,6 @@
|
||||||
$("<strong>").text(message).appendTo(upload_results);
|
$("<strong>").text(message).appendTo(upload_results);
|
||||||
|
|
||||||
// Specific messages for unlisted addons.
|
// Specific messages for unlisted addons.
|
||||||
var isSideload = $('#id_is_sideload').is(':checked') || $newForm.data('addon-is-sideload');
|
|
||||||
if (isUnlisted()) {
|
if (isUnlisted()) {
|
||||||
$("<p>").text(gettext("Your submission will be automatically signed.")).appendTo(upload_results);
|
$("<p>").text(gettext("Your submission will be automatically signed.")).appendTo(upload_results);
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче