Skip to content

Commit 365233e

Browse files
authored
Sponsorship placement tweaks (#1914)
* add an anchor link for each sponsor on the sponsorship page * add options to alter link/description of sponsor logo placements * implement overrides for sponsor url/description in placements per configuration * fix tests
1 parent 1064bf1 commit 365233e

File tree

7 files changed

+112
-5
lines changed

7 files changed

+112
-5
lines changed

sponsors/api.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
from django.utils.text import slugify
2+
from django.urls import reverse
3+
14
from rest_framework import permissions
25
from rest_framework import serializers
36
from rest_framework.authentication import TokenAuthentication
@@ -56,6 +59,10 @@ def get(self, request, *args, **kwargs):
5659
placement = base_data.copy()
5760
placement["publisher"] = logo.publisher
5861
placement["flight"] = logo.logo_place
62+
if logo.describe_as_sponsor:
63+
placement["description"] = f"{sponsor.name} is a {sponsorship.level_name} sponsor of the Python Software Foundation."
64+
if logo.link_to_sponsors_page:
65+
placement["sponsor_url"] = request.build_absolute_uri(reverse('psf-sponsors') + f"#{slugify(sponsor.name)}")
5966
placements.append(placement)
6067

6168
serializer = LogoPlacementSerializer(placements, many=True)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Generated by Django 2.2.24 on 2021-11-11 15:26
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('sponsors', '0059_auto_20211029_1503'),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name='logoplacement',
15+
name='describe_as_sponsor',
16+
field=models.BooleanField(default=False),
17+
),
18+
migrations.AddField(
19+
model_name='logoplacement',
20+
name='link_to_sponsors_page',
21+
field=models.BooleanField(default=False),
22+
),
23+
migrations.AddField(
24+
model_name='logoplacementconfiguration',
25+
name='describe_as_sponsor',
26+
field=models.BooleanField(default=False),
27+
),
28+
migrations.AddField(
29+
model_name='logoplacementconfiguration',
30+
name='link_to_sponsors_page',
31+
field=models.BooleanField(default=False),
32+
),
33+
]
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Generated by Django 2.2.24 on 2021-11-11 15:29
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('sponsors', '0060_auto_20211111_1526'),
10+
]
11+
12+
operations = [
13+
migrations.AlterField(
14+
model_name='logoplacement',
15+
name='describe_as_sponsor',
16+
field=models.BooleanField(default=False, help_text='Override description with "SPONSOR_NAME is a SPONSOR_LEVEL sponsor of the Python Software Foundation".'),
17+
),
18+
migrations.AlterField(
19+
model_name='logoplacement',
20+
name='link_to_sponsors_page',
21+
field=models.BooleanField(default=False, help_text='Override URL in placement to the PSF Sponsors Page, rather than the sponsor landing page url.'),
22+
),
23+
migrations.AlterField(
24+
model_name='logoplacementconfiguration',
25+
name='describe_as_sponsor',
26+
field=models.BooleanField(default=False, help_text='Override description with "SPONSOR_NAME is a SPONSOR_LEVEL sponsor of the Python Software Foundation".'),
27+
),
28+
migrations.AlterField(
29+
model_name='logoplacementconfiguration',
30+
name='link_to_sponsors_page',
31+
field=models.BooleanField(default=False, help_text='Override URL in placement to the PSF Sponsors Page, rather than the sponsor landing page url.'),
32+
),
33+
]

sponsors/models/benefits.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ class BaseLogoPlacement(models.Model):
2525
verbose_name="Logo Placement",
2626
help_text="Where the logo should be placed?"
2727
)
28+
link_to_sponsors_page = models.BooleanField(
29+
default=False,
30+
help_text="Override URL in placement to the PSF Sponsors Page, rather than the sponsor landing page url.",
31+
)
32+
describe_as_sponsor = models.BooleanField(
33+
default=False,
34+
help_text='Override description with "SPONSOR_NAME is a SPONSOR_LEVEL sponsor of the Python Software Foundation".',
35+
)
2836

2937
class Meta:
3038
abstract = True

sponsors/tests/baker_recipes.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,9 @@
4949
publisher=PublisherChoices.FOUNDATION.value,
5050
logo_place=LogoPlacementChoices.SPONSORS_PAGE.value,
5151
)
52+
53+
logo_at_pypi_feature = Recipe(
54+
LogoPlacement,
55+
publisher=PublisherChoices.PYPI.value,
56+
logo_place=LogoPlacementChoices.SIDEBAR.value,
57+
)

sponsors/tests/test_api.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
from django.contrib.auth.models import Permission
22
from django.urls import reverse_lazy
3+
from django.utils.text import slugify
34
from model_bakery import baker
45
from rest_framework.authtoken.models import Token
56
from rest_framework.test import APITestCase
67

78
from sponsors.models import Sponsor
8-
from sponsors.models.enums import LogoPlacementChoices
9+
from sponsors.models.enums import LogoPlacementChoices, PublisherChoices
910

1011

1112
class LogoPlacementeAPIListTests(APITestCase):
@@ -17,7 +18,7 @@ def setUp(self):
1718
self.permission = Permission.objects.get(name='Can access sponsor placement API')
1819
self.user.user_permissions.add(self.permission)
1920
self.authorization = f'Token {token.key}'
20-
self.sponsors = baker.make(Sponsor, _create_files=True, _quantity=2)
21+
self.sponsors = baker.make(Sponsor, _create_files=True, _quantity=3)
2122

2223
def tearDown(self):
2324
for sponsor in Sponsor.objects.all():
@@ -27,20 +28,39 @@ def tearDown(self):
2728
sponsor.print_logo.delete()
2829

2930
def test_list_logo_placement_as_expected(self):
30-
sp1, sp2 = baker.make_recipe("sponsors.tests.finalized_sponsorship", sponsor=iter(self.sponsors), _quantity=2)
31+
sp1, sp2, sp3 = baker.make_recipe("sponsors.tests.finalized_sponsorship", sponsor=iter(self.sponsors), _quantity=3)
3132
baker.make_recipe("sponsors.tests.logo_at_download_feature", sponsor_benefit__sponsorship=sp1)
3233
baker.make_recipe("sponsors.tests.logo_at_sponsors_feature", sponsor_benefit__sponsorship=sp1)
3334
baker.make_recipe("sponsors.tests.logo_at_sponsors_feature", sponsor_benefit__sponsorship=sp2)
35+
baker.make_recipe("sponsors.tests.logo_at_pypi_feature", sponsor_benefit__sponsorship=sp3, link_to_sponsors_page=True, describe_as_sponsor=True)
3436

3537
response = self.client.get(self.url, HTTP_AUTHORIZATION=self.authorization)
3638
data = response.json()
3739

3840
self.assertEqual(200, response.status_code)
39-
self.assertEqual(3, len(data))
41+
self.assertEqual(4, len(data))
4042
self.assertEqual(2, len([p for p in data if p["flight"] == LogoPlacementChoices.SPONSORS_PAGE.value]))
4143
self.assertEqual(1, len([p for p in data if p["flight"] == LogoPlacementChoices.DOWNLOAD_PAGE.value]))
44+
self.assertEqual(1, len([p for p in data if p["flight"] == LogoPlacementChoices.SIDEBAR.value]))
4245
self.assertEqual(2, len([p for p in data if p["sponsor"] == self.sponsors[0].name]))
4346
self.assertEqual(1, len([p for p in data if p["sponsor"] == self.sponsors[1].name]))
47+
self.assertEqual(1, len([p for p in data if p["sponsor"] == self.sponsors[2].name]))
48+
self.assertEqual(
49+
None,
50+
[p for p in data if p["publisher"] == PublisherChoices.FOUNDATION.value][0]['sponsor_url']
51+
)
52+
self.assertEqual(
53+
f"http://testserver/psf/sponsors/#{slugify(sp3.sponsor.name)}",
54+
[p for p in data if p["publisher"] == PublisherChoices.PYPI.value][0]['sponsor_url']
55+
)
56+
self.assertCountEqual(
57+
[sp1.sponsor.description, sp1.sponsor.description, sp2.sponsor.description],
58+
[p['description'] for p in data if p["publisher"] == PublisherChoices.FOUNDATION.value]
59+
)
60+
self.assertEqual(
61+
[f"{sp3.sponsor.name} is a {sp3.level_name} sponsor of the Python Software Foundation."],
62+
[p['description'] for p in data if p["publisher"] == PublisherChoices.PYPI.value]
63+
)
4464

4565
def test_invalid_token(self):
4666
Token.objects.all().delete()

templates/sponsors/partials/sponsors-list.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ <h1 style="font-size: {% if forloop.first %}350%{% else %}300%{% endif %}">{{ pa
2121

2222
<div style="display: grid; grid-gap: 2em; grid-template-columns: repeat(auto-fit, minmax({{ dimension }}px, 0fr)); grid-template-rows: repeat(1, minmax({{ dimension }}px, 0fr)); align-items: center; justify-content: center;">
2323
{% for sponsorship in placement_info.sponsorships %}
24-
<div>
24+
<div id={{ sponsorship.sponsor.name|slugify }}>
2525
<a href="{{ sponsorship.sponsor.landing_page_url }}">
2626
{% thumbnail sponsorship.sponsor.web_logo thumbnail_res format="PNG" quality=100 as im %}
2727
<img src="{{ im.url }}" alt="{{ sponsorship.sponsor.name }} logo" style="max-height:{{ im.height }}px;max-width:{{ im.width }}px;height:auto;width:auto;">

0 commit comments

Comments
 (0)