Skip to content

Commit

Permalink
Command to remove firefox and android addons (#265)
Browse files Browse the repository at this point in the history
* Refactor the left-over 'delete_addons_not_compatible_with_firefoxes' command to remove addons compatible with Firefox and Android.

* Include firefox in the appsupport set.

* Refactor and simplify "TestDeleteAddonsNotCompatibleWithFirefoxes" to "TestDeleteAddonsNotCompatibleWithThunderbird"
  • Loading branch information
MelissaAutumn authored May 23, 2024
1 parent c8e9457 commit 414d9fe
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 65 deletions.
16 changes: 7 additions & 9 deletions src/olympia/addons/management/commands/process_addons.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from olympia.addons.models import Addon
from olympia.addons.tasks import (
add_dynamic_theme_tag, add_firefox57_tag, bump_appver_for_legacy_addons,
delete_addon_not_compatible_with_firefoxes,
delete_addon_not_compatible_with_thunderbird,
delete_obsolete_applicationsversions,
find_inconsistencies_between_es_and_db,
migrate_legacy_dictionaries_to_webextension,
Expand Down Expand Up @@ -66,14 +66,6 @@
~Q(type=amo.ADDON_PERSONA)
]
},
# Run this once we've disallowed new submissions not targeting Firefox and
# addons.thunderbird.net is live.
'delete_addons_not_compatible_with_firefoxes': {
'method': delete_addon_not_compatible_with_firefoxes,
'qs': [Q(status=amo.STATUS_PUBLIC),
~Q(appsupport__app__in=(amo.THUNDERBIRD.id, amo.SEAMONKEY.id))],
'post': delete_obsolete_applicationsversions,
},
'add_dynamic_theme_tag_for_theme_api': {
'method': add_dynamic_theme_tag,
'qs': [
Expand All @@ -98,6 +90,12 @@
_current_version__files__is_webextension=True),
],
},
'delete_addons_not_compatible_with_thunderbird': {
'method': delete_addon_not_compatible_with_thunderbird,
'qs': [Q(status=amo.STATUS_PUBLIC),
~Q(appsupport__app__in=(amo.THUNDERBIRD.id, amo.SEAMONKEY.id))],
'post': delete_obsolete_applicationsversions,
},
}


Expand Down
13 changes: 7 additions & 6 deletions src/olympia/addons/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -664,28 +664,29 @@ def migrate_lwts_to_static_themes(ids, **kw):

@task
@use_primary_db
def delete_addon_not_compatible_with_firefoxes(ids, **kw):
def delete_addon_not_compatible_with_thunderbird(ids, **kw):
"""
Delete the specified add-ons.
Used by process_addons --task=delete_addons_not_compatible_with_firefoxes
Used by process_addons --task=delete_addons_not_compatible_with_thunderbird
"""
log.info(
'Deleting addons not compatible with firefoxes %d-%d [%d].',
'Deleting addons not compatible with thunderbird %d-%d [%d].',
ids[0], ids[-1], len(ids))
qs = Addon.objects.filter(id__in=ids)
for addon in qs:
with transaction.atomic():
# Remove addon appsupport versions for android and firefox
addon.appsupport_set.filter(
app__in=(amo.FIREFOX.id, amo.ANDROID.id)).delete()
app__in=(amo.ANDROID.id, amo.FIREFOX.id)).delete()
addon.delete()


@task
@use_primary_db
def delete_obsolete_applicationsversions(**kw):
"""Delete ApplicationsVersions objects not relevant for Firefoxes."""
"""Delete ApplicationsVersions objects not relevant for Thunderbird/Seamonkey."""
qs = ApplicationsVersions.objects.exclude(
application__in=(amo.FIREFOX.id, amo.ANDROID.id))
application__in=(amo.THUNDERBIRD.id, amo.SEAMONKEY.id))
for av in qs.iterator():
av.delete()

Expand Down
105 changes: 55 additions & 50 deletions src/olympia/addons/tests/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -524,10 +524,10 @@ def test_correctly_ignored_because_strict_compatibility_is_enabled(self):
assert apv.max != self.firefox_56_star


class TestDeleteAddonsNotCompatibleWithFirefoxes(TestCase):
class TestDeleteAddonsNotCompatibleWithThunderbird(TestCase):
def make_the_call(self):
call_command('process_addons',
task='delete_addons_not_compatible_with_firefoxes')
task='delete_addons_not_compatible_with_thunderbird')

@pytest.mark.xfail(reason="Test and the associated command are Firefox specific.")
def test_basic(self):
Expand All @@ -539,42 +539,42 @@ def test_basic(self):
application=amo.SEAMONKEY.id, version='2.49.3')
av_seamonkey_max, _ = AppVersion.objects.get_or_create(
application=amo.SEAMONKEY.id, version='2.49.*')
# Those add-ons should not be deleted, because they are compatible with
# at least Firefox or Firefox for Android.
addon_factory() # A pure Firefox add-on
addon_factory(version_kw={'application': amo.ANDROID.id})
addon_with_both_firefoxes = addon_factory()
ApplicationsVersions.objects.get_or_create(
application=amo.ANDROID.id,
version=addon_with_both_firefoxes.current_version,
min=av_min, max=av_max)
addon_with_thunderbird_and_android = addon_factory(
version_kw={'application': amo.THUNDERBIRD.id})
ApplicationsVersions.objects.get_or_create(
application=amo.ANDROID.id,
version=addon_with_thunderbird_and_android.current_version,
min=av_min, max=av_max)
addon_with_firefox_and_seamonkey = addon_factory(
version_kw={'application': amo.FIREFOX.id})
ApplicationsVersions.objects.get_or_create(
application=amo.SEAMONKEY.id,
version=addon_with_firefox_and_seamonkey.current_version,
min=av_seamonkey_min, max=av_seamonkey_max)
addon_factory(
status=amo.STATUS_NULL, # Non-public, will cause it to be ignored.
version_kw={'application': amo.THUNDERBIRD.id})
av_tb_min, _ = AppVersion.objects.get_or_create(
application=amo.THUNDERBIRD.id, version='115.1')
av_tb_max, _ = AppVersion.objects.get_or_create(
application=amo.THUNDERBIRD.id, version='115.*')

def create_addon(version, alt_version = None, min = None, max = None):
addon = addon_factory(version_kw={'application': version})
# Create a new version, if alt_version is provided it's essentially a release for that platform
if alt_version:
ApplicationsVersions.objects.get_or_create(
application=alt_version,
version=addon.current_version,
min=min, max=max)
return addon

# These addons should stay
good_addons = [
# Thunderbird
create_addon(amo.THUNDERBIRD.id),
# Seamonkey
create_addon(amo.SEAMONKEY.id),
# Thunderbird and Seamonkey
create_addon(amo.THUNDERBIRD.id, amo.SEAMONKEY.id, av_seamonkey_min, av_seamonkey_max),
# Firefox and Thunderbird
create_addon(amo.FIREFOX.id, amo.THUNDERBIRD.id, av_tb_min, av_tb_max)
]

# Those add-ons should be deleted as they are only compatible with
# Thunderbird or Seamonkey, or both.
addon = addon_factory(version_kw={'application': amo.THUNDERBIRD.id})
addon2 = addon_factory(version_kw={'application': amo.SEAMONKEY.id,
'min_app_version': '2.49.3',
'max_app_version': '2.49.*'})
addon3 = addon_factory(version_kw={'application': amo.THUNDERBIRD.id})
ApplicationsVersions.objects.get_or_create(
application=amo.SEAMONKEY.id,
version=addon3.current_version,
min=av_seamonkey_min, max=av_seamonkey_max)
# These addons should go
bad_addons = [
# Firefox
create_addon(amo.FIREFOX.id),
# Android
create_addon(amo.ANDROID.id),
# Firefox and Android
create_addon(amo.FIREFOX.id, amo.ANDROID.id, min=av_min, max=av_max)
]

# We've manually changed the ApplicationVersions, so let's run
# update_appsupport() on all public add-ons. In the real world that is
Expand All @@ -583,33 +583,38 @@ def test_basic(self):
# somehow fell through the cracks once a day.
update_appsupport(Addon.objects.public().values_list('pk', flat=True))

assert Addon.objects.count() == 9
assert Addon.objects.count() == 7

with count_subtask_calls(
pa.delete_addon_not_compatible_with_firefoxes) as calls:
pa.delete_addon_not_compatible_with_thunderbird) as calls:
self.make_the_call()

bad_addons_pk = map(lambda a: a.pk, bad_addons)

assert len(calls) == 1
assert calls[0]['kwargs']['args'] == [[addon.pk, addon2.pk, addon3.pk]]
assert not Addon.objects.filter(pk=addon.pk).exists()
assert not Addon.objects.filter(pk=addon2.pk).exists()
assert not Addon.objects.filter(pk=addon3.pk).exists()
assert calls[0]['kwargs']['args'] == [bad_addons_pk]

for addon in good_addons:
assert Addon.objects.filter(pk=addon.pk).exists()

for addon in bad_addons:
assert not Addon.objects.filter(pk=addon.pk).exists()

assert Addon.objects.count() == 6
assert Addon.objects.count() == 4

# Make sure ApplicationsVersions targeting Thunderbird or Seamonkey are
# Make sure ApplicationsVersions targeting Android or Firefox are
# gone.
assert not ApplicationsVersions.objects.filter(
application=amo.SEAMONKEY.id).exists()
application=amo.ANDROID.id).exists()
assert not ApplicationsVersions.objects.filter(
application=amo.THUNDERBIRD.id).exists()
application=amo.FIREFOX.id).exists()

# Make sure AppSupport targeting Thunderbird or Seamonkey are gone for
# Make sure AppSupport targeting Android or Firefox are gone for
# add-ons we touched.
assert not AppSupport.objects.filter(
addon__in=(addon, addon2, addon3), app=amo.SEAMONKEY.id).exists()
addon__in=bad_addons, app=amo.FIREFOX.id).exists()
assert not AppSupport.objects.filter(
addon__in=(addon, addon2, addon3), app=amo.THUNDERBIRD.id).exists()
addon__in=bad_addons, app=amo.ANDROID.id).exists()


class TestMigrateLegacyDictionariesToWebextension(TestCase):
Expand Down

0 comments on commit 414d9fe

Please sign in to comment.