Show modal warning at submission time when Android compatibility is checked (#21224)

* Show modal warning at submission time when Android compatibility is checked
This commit is contained in:
Mathieu Pillard 2023-10-04 10:32:12 +02:00 коммит произвёл GitHub
Родитель 15edba7187
Коммит 3122b60698
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
14 изменённых файлов: 112 добавлений и 25 удалений

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

@ -1545,6 +1545,16 @@ class Addon(OnChangeMixin, ModelBase):
def can_set_compatibility(self):
return self.type_can_set_compatibility(self.type)
@property
def can_be_compatible_with_all_fenix_versions(self):
"""Whether or not the addon is allowed to be compatible with all Fenix
versions (i.e. it's a recommended/line extension for Android)."""
return (
self.promoted
and self.promoted.group.can_be_compatible_with_all_fenix_versions
and amo.ANDROID in self.promoted.approved_applications
)
def has_author(self, user):
"""True if ``user`` is an author of the add-on."""
if user is None or user.is_anonymous:

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

@ -1847,6 +1847,25 @@ class TestAddonModels(TestCase):
AddonGUID.objects.create(addon=addon, guid='not-a-guid')
assert list(addon.blocklistsubmissions) == [submission]
def test_can_be_compatible_with_all_fenix_versions_property(self):
addon = addon_factory()
assert not addon.can_be_compatible_with_all_fenix_versions
# It's promoted but nothing has been approved.
promoted = PromotedAddon.objects.create(addon=addon, group_id=LINE.id)
assert not addon.can_be_compatible_with_all_fenix_versions
# The latest version is approved.
promoted.approve_for_version(addon.current_version)
del addon.promoted
assert addon.can_be_compatible_with_all_fenix_versions
addon.promoted.update(application_id=amo.FIREFOX.id)
assert not addon.can_be_compatible_with_all_fenix_versions
addon.promoted.update(application_id=amo.ANDROID.id)
assert addon.can_be_compatible_with_all_fenix_versions
class TestAddonUser(TestCase):
def test_delete(self):

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

@ -22,7 +22,7 @@ _PromotedSuperClass = namedtuple(
'can_primary_hero',
'immediate_approval',
'flag_for_human_review',
'can_be_compatible_with_fenix', # Note: we also check it's promoted for Android
'can_be_compatible_with_all_fenix_versions', # If addon is promoted for Android
],
defaults=(
# "Since fields with a default value must come after any fields without
@ -38,7 +38,7 @@ _PromotedSuperClass = namedtuple(
False, # can_primary_hero - can be added to a primary hero shelf
False, # immediate_approval - will addon be auto-approved once added
False, # flag_for_human_review - will be add-on be flagged for another review
False, # can_be_compatible_with_fenix
False, # can_be_compatible_with_all_fenix_versions
),
)
@ -69,7 +69,7 @@ RECOMMENDED = PromotedClass(
applications.ANDROID.short: 'recommended-android',
},
can_primary_hero=True,
can_be_compatible_with_fenix=True,
can_be_compatible_with_all_fenix_versions=True,
)
SPONSORED = PromotedClass(
@ -113,7 +113,7 @@ LINE = PromotedClass(
applications.ANDROID.short: 'line',
},
can_primary_hero=True,
can_be_compatible_with_fenix=True,
can_be_compatible_with_all_fenix_versions=True,
)
SPOTLIGHT = PromotedClass(

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

@ -885,10 +885,9 @@ class CompatForm(AMOModelForm):
# On Android, disable Fenix-pre GA version range unless the add-on is
# recommended or line.
if app == amo.ANDROID.id and not (
addon.promoted
and addon.promoted.group.can_be_compatible_with_fenix
and amo.ANDROID in addon.promoted.approved_applications
if (
app == amo.ANDROID.id
and not addon.can_be_compatible_with_all_fenix_versions
):
self.fields[
'min'

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

@ -42,5 +42,8 @@
</div>
</form>
</div>
{% if not addon or not addon.can_be_compatible_with_all_fenix_versions %}
{% include 'devhub/includes/android_compatibility_modal.html' %}
{% endif %}
</div>
{% endblock content %}

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

@ -0,0 +1,10 @@
<div id="modal-confirm-android-compatibility" class="modal">
<form method="POST" action="#">
<h3>{{ _("Firefox Android compatibility") }}</h3>
<p>{% trans %}Did you test your extension to ensure it works as expected on Firefox Android? If not, please see <a target="_blank" rel="noopener noreferrer" href="https://extensionworkshop.com/documentation/develop/developing-extensions-for-firefox-for-android/">Developing extensions for Firefox Android</a> for test guidance before submitting.{% endtrans %}</p>
<div class="modal-actions">
<button type="submit">{{ _("Yes, Ive tested my Firefox Android extension") }}</button>
<a href="#" class="close button delete-button">{{ _("No, I have not tested for Android compatibility") }}</a>
</div>
</form>
</div>

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

@ -32,7 +32,7 @@ from olympia.amo.tests import (
version_factory,
)
from olympia.constants.licenses import LICENSES_BY_BUILTIN
from olympia.constants.promoted import NOTABLE
from olympia.constants.promoted import NOTABLE, RECOMMENDED
from olympia.devhub import views
from olympia.files.tests.test_models import UploadMixin
from olympia.files.utils import parse_addon
@ -858,6 +858,13 @@ class TestAddonSubmitUpload(UploadMixin, TestCase):
)
self.assert3xx(response, expected_location)
def test_android_compatibility_modal(self):
url = reverse('devhub.submit.upload', args=['listed'])
modal_selector = '#modals #modal-confirm-android-compatibility.modal'
response = self.client.get(url)
doc = pq(response.content)
assert doc(modal_selector)
class TestAddonSubmitSource(TestSubmitBase):
def setUp(self):
@ -2508,6 +2515,18 @@ class TestVersionSubmitUploadListed(VersionSubmitUploadMixin, UploadMixin, TestC
'Version 0.0.1 must be greater than the previous approved version 0.0.1.0.'
)
def test_android_compatibility_modal(self):
url = reverse('devhub.submit.version.upload', args=[self.addon.slug, 'listed'])
modal_selector = '#modals #modal-confirm-android-compatibility.modal'
response = self.client.get(url)
doc = pq(response.content)
assert doc(modal_selector)
self.make_addon_promoted(self.addon, RECOMMENDED, approve_version=True)
response = self.client.get(url)
doc = pq(response.content)
assert not doc(modal_selector)
class TestVersionSubmitUploadUnlisted(VersionSubmitUploadMixin, UploadMixin, TestCase):
channel = amo.CHANNEL_UNLISTED

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

@ -37,7 +37,7 @@ class Command(BaseCommand):
application=amo.ANDROID.id, version=amo.MAX_VERSION_FENNEC
)
promoted_groups_ids = [
p.id for p in PROMOTED_GROUPS if p.can_be_compatible_with_fenix
p.id for p in PROMOTED_GROUPS if p.can_be_compatible_with_all_fenix_versions
]
qs = (
# We only care about listed extensions already marked as compatible

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

@ -62,13 +62,10 @@ class Command(BaseCommand):
count = 0
skipped = 0
for addon in addons:
if (
addon.promoted
and addon.promoted.group.can_be_compatible_with_fenix
and amo.ANDROID in addon.promoted.approved_applications
):
if addon.can_be_compatible_with_all_fenix_versions:
log.info(
'Skipping add-on id %d because of its promoted group.', addon.pk
'Skipping add-on id %d because it can be compatible with Fenix.',
addon.pk,
)
skipped += 1
continue

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

@ -1467,11 +1467,7 @@ class ApplicationsVersions(models.Model):
# Recommended/line for Android are allowed to set compatibility in the
# limited range.
if (
addon.promoted
and addon.promoted.group.can_be_compatible_with_fenix
and amo.ANDROID in addon.promoted.approved_applications
):
if addon.can_be_compatible_with_all_fenix_versions:
return False
# Range is expressed as a [closed, open) interval.

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

@ -33,3 +33,7 @@ input.ui-autocomplete-loading,
}
}
}
.modal-actions button {
margin: 5px 0;
}

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

@ -1888,7 +1888,7 @@ h3.author .transfer-ownership {
.contrib-overlay,
.modal-overlay {
background: rgba(0, 0, 0, 0.5);
background: rgba(0, 0, 0, 0.7);
}
.primary.island {

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

@ -1350,4 +1350,34 @@ function initSubmitModals() {
return false; // don't follow the a.href link
});
}
// Warn about Android compatibility (if selected).
if ($('#modal-confirm-android-compatibility').length > 0) {
let confirmedOnce = false;
let $input = $('#id_compatible_apps label.android input[type=checkbox]');
const $modalAndroidConfirm = $(
'#modal-confirm-android-compatibility',
).modal('#id_compatible_apps label.android', {
width: 630,
callback: function shouldShowAndroidModal(options) {
if ($input.prop('disabled')) {
return false;
}
if (confirmedOnce) {
$input.prop('checked', !$input.prop('checked'));
}
return !confirmedOnce;
},
});
$('#modal-confirm-android-compatibility')
.find('form')
.on('submit', function onSubmit(e) {
e.preventDefault();
$input.prop('checked', true);
$modalAndroidConfirm.trigger('close');
confirmedOnce = true;
});
}
}

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

@ -304,10 +304,10 @@ $.fn.modal = function (click_target, o) {
offset = offset || $modal.o.offset;
$modal.detach().appendTo('body');
var toX = ($(window).width() - $modal.outerWidth(false)) / 2,
toY = $(window).scrollTop() + 26; //distance from top of the window
let toX = offset.x || ($(window).width() - $modal.outerWidth(false)) / 2,
toY = offset.y || 160;
$modal.css({
left: toX,
left: toX + 'px',
top: toY + 'px',
right: 'inherit',
bottom: 'inherit',