Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Multiple Partner Addons #22888

Open
wants to merge 38 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
16d4576
Allow multiple PromotedAddons to a single Addon
chrstinalin Nov 25, 2024
91cc3a5
format
chrstinalin Nov 25, 2024
e8e905c
test changes
chrstinalin Nov 25, 2024
570d40d
no prefetch?
chrstinalin Nov 25, 2024
728795a
refresh from db
chrstinalin Nov 26, 2024
29cb597
multi state
chrstinalin Nov 26, 2024
6eaa568
refresh
chrstinalin Nov 26, 2024
40dd1d5
tests
chrstinalin Nov 26, 2024
0ee69e4
more tests
chrstinalin Nov 26, 2024
6431d51
test
chrstinalin Nov 27, 2024
549fb43
how badly does this break
chrstinalin Nov 28, 2024
dc00e17
prefetch
chrstinalin Nov 28, 2024
b254f27
fakedatetime object
chrstinalin Nov 28, 2024
4cc40f9
lint
chrstinalin Nov 28, 2024
188c101
catch dne
chrstinalin Nov 28, 2024
cf8f017
tests
chrstinalin Nov 28, 2024
9957a1f
more tests
chrstinalin Nov 28, 2024
baf0edd
main tests
chrstinalin Nov 29, 2024
3d22f81
elastic
chrstinalin Nov 29, 2024
7bee3dc
queryparam
chrstinalin Nov 29, 2024
5a4c9af
es
chrstinalin Nov 29, 2024
b4bf689
query count comments
chrstinalin Nov 29, 2024
6603877
refactor promoted_group to promoted_groups
chrstinalin Dec 2, 2024
d49f84e
codestyle
chrstinalin Dec 2, 2024
25396f6
approvals
chrstinalin Dec 3, 2024
9fb4e99
iterate all
chrstinalin Dec 3, 2024
d2ca683
all_apps
chrstinalin Dec 3, 2024
341ecbd
addon model tests
chrstinalin Dec 4, 2024
7d2f9e6
test fix
chrstinalin Dec 4, 2024
5ec5b4b
tests
chrstinalin Dec 4, 2024
8019034
test
chrstinalin Dec 4, 2024
12efa09
docs, conflict
chrstinalin Dec 19, 2024
0d6ad41
lint
chrstinalin Dec 19, 2024
d29a0ce
tests
chrstinalin Dec 19, 2024
3d7b7a7
add shim for api v3/v4
chrstinalin Dec 19, 2024
9c60b7b
whoops
chrstinalin Dec 19, 2024
5034b0f
tests
chrstinalin Dec 19, 2024
cde026a
safer tests
chrstinalin Jan 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/topics/api/addons.rst
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,9 @@ This endpoint allows you to fetch a specific add-on by id, slug or guid.
:>json int position: The position in the list of previews images.
:>json int previews[].thumbnail_size[]: width, height dimensions of of the preview image thumbnail.
:>json string previews[].thumbnail_url: The URL (including a cachebusting query string) to the preview image thumbnail.
:>json object|null promoted: Object holding promotion information about the add-on. Null if the add-on is not currently promoted.
:>json string promoted.category: The name of the :ref:`promoted category <addon-detail-promoted-category>` for the add-on.
:>json array promoted.apps[]: Array of the :ref:`applications <addon-detail-application>` for which the add-on is promoted.
:>json array promoted: Array holding promotion information about the add-on.
:>json string promoted[].category: The name of the :ref:`promoted category <addon-detail-promoted-category>` for the add-on.
:>json array promoted[].apps[]: Array of the :ref:`applications <addon-detail-application>` for which the add-on is promoted.
:>json object ratings: Object holding ratings summary information about the add-on.
:>json int ratings.count: The total number of user ratings for the add-on.
:>json int ratings.text_count: The number of user ratings with review text for the add-on.
Expand Down
9 changes: 4 additions & 5 deletions src/olympia/abuse/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from olympia.amo.templatetags.jinja_helpers import absolutify
from olympia.amo.utils import send_mail
from olympia.bandwagon.models import Collection
from olympia.constants.promoted import HIGH_PROFILE, HIGH_PROFILE_RATING
from olympia.ratings.models import Rating
from olympia.users.models import UserProfile

Expand Down Expand Up @@ -251,7 +252,7 @@ def should_hold_action(self):
or self.target.groups_list # has any permissions
# owns a high profile add-on
or any(
addon.promoted_group(currently_approved=False).high_profile
addon.get(HIGH_PROFILE, currently_approved=False)
for addon in self.target.addons.all()
)
)
Expand Down Expand Up @@ -282,7 +283,7 @@ def should_hold_action(self):
return bool(
self.target.status != amo.STATUS_DISABLED
# is a high profile add-on
and self.target.promoted_group(currently_approved=False).high_profile
and self.target.get(HIGH_PROFILE, currently_approved=False)
)

def process_action(self):
Expand Down Expand Up @@ -393,9 +394,7 @@ def should_hold_action(self):
return bool(
not self.target.deleted
and self.target.reply_to
and self.target.addon.promoted_group(
currently_approved=False
).high_profile_rating
and self.target.addon.get(HIGH_PROFILE_RATING, currently_approved=False)
)

def process_action(self):
Expand Down
8 changes: 5 additions & 3 deletions src/olympia/abuse/cinder.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,9 @@ class CinderUser(CinderEntity):
def __init__(self, user):
self.user = user
self.related_addons = (
self.user.addons.all().only_translations().select_related('promotedaddon')
self.user.addons.all()
.only_translations()
.prefetch_related('promoted_addons')
)

@property
Expand Down Expand Up @@ -332,7 +334,7 @@ def get_attributes(self):
# promoted in any way, but we don't care about the promotion being
# approved for the current version, it would make more queries and it's
# not useful for moderation purposes anyway.
promoted_group = self.addon.promoted_group(currently_approved=False)
group_name = self.addon.group_name(currently_approved=False)
data = {
'id': self.id,
'average_daily_users': self.addon.average_daily_users,
Expand All @@ -342,7 +344,7 @@ def get_attributes(self):
'name': self.get_str(self.addon.name),
'slug': self.addon.slug,
'summary': self.get_str(self.addon.summary),
'promoted': self.get_str(promoted_group.name if promoted_group else ''),
'promoted': self.get_str(group_name),
}
return data

Expand Down
11 changes: 4 additions & 7 deletions src/olympia/abuse/tests/test_cinder.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,10 @@ def test_get_str(self):

class TestCinderAddon(BaseTestCinderCase, TestCase):
CinderClass = CinderAddon
# 2 queries expected:
# 1 queries expected:
# - Authors (can't use the listed_authors transformer, we want non-listed as well,
# and we have custom limits for batch-sending relationships)
# - Promoted add-on
expected_queries_for_report = 2
expected_queries_for_report = 1
expected_queue_suffix = 'listings'

def _create_dummy_target(self, **kwargs):
Expand Down Expand Up @@ -1097,8 +1096,7 @@ class TestCinderAddonHandledByReviewers(TestCinderAddon):
CinderClass = CinderAddonHandledByReviewers
# For rendering the payload to Cinder like CinderAddon:
# - 1 Fetch Addon authors
# - 2 Fetch Promoted Addon
expected_queries_for_report = 2
expected_queries_for_report = 1
expected_queue_suffix = 'addon-infringement'

def test_queue_with_theme(self):
Expand Down Expand Up @@ -1590,8 +1588,7 @@ class TestCinderAddonHandledByLegal(TestCinderAddon):
CinderClass = CinderAddonHandledByLegal
# For rendering the payload to Cinder like CinderAddon:
# - 1 Fetch Addon authors
# - 2 Fetch Promoted Addon
expected_queries_for_report = 2
expected_queries_for_report = 1
expected_queue_suffix = None

def test_queue(self):
Expand Down
6 changes: 4 additions & 2 deletions src/olympia/activity/tests/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def test_list(self):
self.grant_permission(user, '*:*')
self.client.force_login(user)

with self.assertNumQueries(11):
with self.assertNumQueries(12):
# - 2 savepoints/release
# - 2 user and groups
# - 1 count for pagination
Expand All @@ -40,6 +40,7 @@ def test_list(self):
# - 1 all versions from activities
# - 1 all translations from those versions
# - 1 all add-ons from activities
# - 1 add-ons' promoted addon
# - 1 all translations for those add-ons
response = self.client.get(self.list_url)
assert response.status_code == 200
Expand All @@ -65,7 +66,7 @@ def test_search_for_single_ip(self):
with core.override_remote_addr('127.0.0.1'):
extra_user = user_factory() # Extra user that shouldn't match
ActivityLog.objects.create(amo.LOG.LOG_IN, user=extra_user)
with self.assertNumQueries(11):
with self.assertNumQueries(12):
# - 2 savepoints/release
# - 2 user and groups
# - 1 count for pagination
Expand All @@ -74,6 +75,7 @@ def test_search_for_single_ip(self):
# - 1 all versions from activities
# - 1 all translations from those versions
# - 1 all add-ons from activities
# - 1 add-ons' promoted addon
# - 1 all translations for those add-ons
response = self.client.get(self.list_url, {'q': '127.0.0.2'}, follow=True)
assert response.status_code == 200
Expand Down
9 changes: 6 additions & 3 deletions src/olympia/activity/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,10 +328,11 @@ def test_arguments_old_reviews_app_to_ratings(self):
assert activity.arguments == [addon, rating]
activity.save()

with self.assertNumQueries(5):
with self.assertNumQueries(6):
# - 1 for all activities
# - 1 for all users
# - 1 for all addons
# - 1 for addons' promoted addon
# - 1 for all add-on translations
# - 1 for all ratings
activity = ActivityLog.objects.latest('pk')
Expand All @@ -342,10 +343,11 @@ def test_arguments_old_reviews_app_to_ratings(self):
addon2 = addon_factory(slug='foo')
user2 = user_factory()
rating2 = Rating.objects.create(addon=addon2, user=user2, rating=2)
with self.assertNumQueries(5):
with self.assertNumQueries(6):
# - 1 for all activities
# - 1 for all users
# - 1 for all addons
# - 1 for addons' promoted addon
# - 1 for all add-on translations
# - 1 for all ratings
activities = ActivityLog.objects.for_addons([addon, addon2]).order_by('pk')
Expand Down Expand Up @@ -387,10 +389,11 @@ def test_to_string_num_queries_model_depending_on_addon(self):
addon2.current_version,
user=user_factory(),
)
with self.assertNumQueries(6):
with self.assertNumQueries(7):
# - 1 for all activities
# - 1 for all users
# - 1 for all addons
# - 1 for addons' promoted addon
# - 1 for all add-on translations
# - 1 for all versions
# - 1 for all versions translations
Expand Down
3 changes: 2 additions & 1 deletion src/olympia/activity/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,10 +302,11 @@ def test_queries(self):
'fiiiine', amo.LOG.REVIEWER_REPLY_VERSION, self.days_ago(0)
)
self._login_developer()
with self.assertNumQueries(16):
with self.assertNumQueries(18):
# - 2 savepoints because of tests
# - 2 user and groups
# - 2 addon and its translations
# - 2 addons' promoted addons
# - 1 addon author lookup (permission check)
# - 1 version (no transforms at all)
# - 1 count of activity logs
Expand Down
12 changes: 5 additions & 7 deletions src/olympia/addons/indexers.py
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ def get_mapping(cls):
'promoted': {
'type': 'object',
'properties': {
'group_id': {'type': 'byte'},
'group_ids': {'type': 'byte'},
'approved_for_apps': {'type': 'byte'},
},
},
Expand Down Expand Up @@ -662,8 +662,8 @@ def extract_document(cls, obj):
data['has_eula'] = bool(obj.eula)
data['has_privacy_policy'] = bool(obj.privacy_policy)

data['is_recommended'] = bool(
obj.promoted and obj.promoted.group == RECOMMENDED
data['is_recommended'] = any(
RECOMMENDED.id == promoted.group_id for promoted in obj.promoted
)

data['previews'] = [
Expand All @@ -678,11 +678,9 @@ def extract_document(cls, obj):

data['promoted'] = (
{
'group_id': obj.promoted.group_id,
'group_ids': obj.group_ids,
# store the app approvals because .approved_applications needs it.
'approved_for_apps': [
app.id for app in obj.promoted.approved_applications
],
'approved_for_apps': [app.id for app in obj.approved_applications],
}
if obj.promoted
else None
Expand Down
Loading
Loading