Modify terminology

This commit is contained in:
Joakim Hellsén 2026-03-16 23:41:19 +01:00
commit 1f5e931af6
Signed by: Joakim Hellsén
SSH key fingerprint: SHA256:/9h/CsExpFp+PRhsfA0xznFx2CGfTT5R/kpuFfUgEQk
3 changed files with 73 additions and 33 deletions

View file

@ -1,6 +1,6 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block title %} {% block title %}
YouTube channels with rewards {{ page_title }}
{% endblock title %} {% endblock title %}
{% block content %} {% block content %}
<main> <main>
@ -14,17 +14,17 @@
<thead> <thead>
<tr> <tr>
<th>Channel</th> <th>Channel</th>
<th>Partner</th> <th>Organization</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for group in partner_groups %} {% for group in organization_groups %}
{% for item in group.channels %} {% for item in group.channels %}
<tr> <tr>
<td> <td>
<a href="{{ item.url }}" rel="noopener" target="_blank">{{ item.channel }}</a> <a href="{{ item.url }}" rel="noopener" target="_blank">{{ item.channel }}</a>
</td> </td>
<td>{{ group.partner }}</td> <td>{{ group.organization }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
{% endfor %} {% endfor %}

View file

@ -10,13 +10,44 @@ if TYPE_CHECKING:
class YouTubeIndexViewTest(TestCase): class YouTubeIndexViewTest(TestCase):
"""Tests for the YouTube drops channels index page.""" """Tests for the YouTube drops channels index page."""
def test_index_includes_page_specific_seo_metadata(self) -> None:
"""The YouTube page should render dedicated title and description metadata."""
response: _MonkeyPatchedWSGIResponse = self.client.get(reverse("youtube:index"))
content: str = response.content.decode()
assert response.context is not None
assert response.context["page_title"] == "YouTube channels with rewards"
assert (
response.context["page_description"]
== "Browse YouTube channels listed as reward-enabled, including Call of Duty, Blizzard, "
"Fortnite, Riot Games, and more."
)
assert (
'<meta property="og:title" content="YouTube channels with rewards" />'
in content
)
assert (
'<meta property="og:description"\n'
' content="Browse YouTube channels listed as reward-enabled, including Call of Duty, '
'Blizzard, Fortnite, Riot Games, and more." />'
) in content
assert (
'<meta name="twitter:title" content="YouTube channels with rewards" />'
in content
)
assert (
'<meta name="description"\n'
' content="Browse YouTube channels listed as reward-enabled, including Call of Duty, '
'Blizzard, Fortnite, Riot Games, and more." />'
) in content
def test_index_returns_200(self) -> None: def test_index_returns_200(self) -> None:
"""The YouTube index page should return HTTP 200.""" """The YouTube index page should return HTTP 200."""
response: _MonkeyPatchedWSGIResponse = self.client.get(reverse("youtube:index")) response: _MonkeyPatchedWSGIResponse = self.client.get(reverse("youtube:index"))
assert response.status_code == 200 assert response.status_code == 200
def test_index_displays_known_channels(self) -> None: def test_index_displays_known_channels(self) -> None:
"""The page should include key known channels from the partner list.""" """The page should include key known channels from the organization list."""
response: _MonkeyPatchedWSGIResponse = self.client.get(reverse("youtube:index")) response: _MonkeyPatchedWSGIResponse = self.client.get(reverse("youtube:index"))
content: str = response.content.decode() content: str = response.content.decode()
@ -28,8 +59,8 @@ class YouTubeIndexViewTest(TestCase):
assert "Riot Games" in content assert "Riot Games" in content
assert "Ubisoft" in content assert "Ubisoft" in content
def test_index_includes_partner_urls(self) -> None: def test_index_includes_organization_urls(self) -> None:
"""The page should render partner channel links from the source list.""" """The page should render organization channel links from the source list."""
response: _MonkeyPatchedWSGIResponse = self.client.get(reverse("youtube:index")) response: _MonkeyPatchedWSGIResponse = self.client.get(reverse("youtube:index"))
content: str = response.content.decode() content: str = response.content.decode()
@ -37,8 +68,8 @@ class YouTubeIndexViewTest(TestCase):
assert "https://www.youtube.com/user/epicfortnite" in content assert "https://www.youtube.com/user/epicfortnite" in content
assert "https://www.youtube.com/lolesports" in content assert "https://www.youtube.com/lolesports" in content
def test_index_groups_partners_alphabetically(self) -> None: def test_index_groups_organizations_alphabetically(self) -> None:
"""Partner sections should render grouped and in alphabetical order.""" """Organization sections should render grouped and in alphabetical order."""
response: _MonkeyPatchedWSGIResponse = self.client.get(reverse("youtube:index")) response: _MonkeyPatchedWSGIResponse = self.client.get(reverse("youtube:index"))
content: str = response.content.decode() content: str = response.content.decode()

View file

@ -8,90 +8,94 @@ if TYPE_CHECKING:
from django.http import HttpResponse from django.http import HttpResponse
PAGE_TITLE = "YouTube channels with rewards"
PAGE_DESCRIPTION = "Browse YouTube channels listed as reward-enabled, including Call of Duty, Blizzard, Fortnite, Riot Games, and more."
def index(request: HttpRequest) -> HttpResponse: def index(request: HttpRequest) -> HttpResponse:
"""Render a minimal list of YouTube channels with known drops-enabled partners. """Render a minimal list of YouTube channels with known drops-enabled organizations.
Returns: Returns:
HttpResponse: Rendered index page for YouTube drops channels. HttpResponse: Rendered index page for YouTube drops channels.
""" """
channels: list[dict[str, str]] = [ channels: list[dict[str, str]] = [
{ {
"partner": "Activision (Call of Duty)", "organization": "Activision (Call of Duty)",
"channel": "Call of Duty", "channel": "Call of Duty",
"url": "https://www.youtube.com/channel/UCbLIqv9Puhyp9_ZjVtfOy7w", "url": "https://www.youtube.com/channel/UCbLIqv9Puhyp9_ZjVtfOy7w",
}, },
{ {
"partner": "Battle.net / Blizzard", "organization": "Battle.net / Blizzard",
"channel": "PlayOverwatch", "channel": "PlayOverwatch",
"url": "https://www.youtube.com/c/playoverwatch/featured", "url": "https://www.youtube.com/c/playoverwatch/featured",
}, },
{ {
"partner": "Battle.net / Blizzard", "organization": "Battle.net / Blizzard",
"channel": "Hearthstone", "channel": "Hearthstone",
"url": "https://www.youtube.com/c/Hearthstone/featured", "url": "https://www.youtube.com/c/Hearthstone/featured",
}, },
{ {
"partner": "Electronic Arts", "organization": "Electronic Arts",
"channel": "FIFA", "channel": "FIFA",
"url": "https://www.youtube.com/channel/UCFA6YGp5lvgayO20lk7_Ung", "url": "https://www.youtube.com/channel/UCFA6YGp5lvgayO20lk7_Ung",
}, },
{ {
"partner": "Electronic Arts", "organization": "Electronic Arts",
"channel": "EA Madden NFL", "channel": "EA Madden NFL",
"url": "https://www.youtube.com/@EAMaddenNFL", "url": "https://www.youtube.com/@EAMaddenNFL",
}, },
{ {
"partner": "Epic Games", "organization": "Epic Games",
"channel": "Fortnite", "channel": "Fortnite",
"url": "https://www.youtube.com/user/epicfortnite", "url": "https://www.youtube.com/user/epicfortnite",
}, },
{ {
"partner": "Garena", "organization": "Garena",
"channel": "Free Fire", "channel": "Free Fire",
"url": "https://www.youtube.com/channel/UC_vVy4OI86F0amXqFN_zTMg", "url": "https://www.youtube.com/channel/UC_vVy4OI86F0amXqFN_zTMg",
}, },
{ {
"partner": "Krafton (PUBG)", "organization": "Krafton (PUBG)",
"channel": "PUBG: BATTLEGROUNDS", "channel": "PUBG: BATTLEGROUNDS",
"url": "https://www.youtube.com/channel/UCTDO0RgowRyaAEUrPnBAg4g", "url": "https://www.youtube.com/channel/UCTDO0RgowRyaAEUrPnBAg4g",
}, },
{ {
"partner": "MLBB", "organization": "MLBB",
"channel": "Mobile Legends: Bang Bang", "channel": "Mobile Legends: Bang Bang",
"url": "https://www.youtube.com/channel/UCqmld-BIYME2i_ooRTo1EOg", "url": "https://www.youtube.com/channel/UCqmld-BIYME2i_ooRTo1EOg",
}, },
{ {
"partner": "NBA", "organization": "NBA",
"channel": "NBA", "channel": "NBA",
"url": "https://www.youtube.com/user/NBA", "url": "https://www.youtube.com/user/NBA",
}, },
{ {
"partner": "NFL", "organization": "NFL",
"channel": "NFL", "channel": "NFL",
"url": "https://www.youtube.com/@NFL", "url": "https://www.youtube.com/@NFL",
}, },
{ {
"partner": "PUBG Mobile", "organization": "PUBG Mobile",
"channel": "PUBG MOBILE", "channel": "PUBG MOBILE",
"url": "https://www.youtube.com/channel/UCTDO0RgowRyaAEUrPnBAg4g", "url": "https://www.youtube.com/channel/UCTDO0RgowRyaAEUrPnBAg4g",
}, },
{ {
"partner": "Riot Games", "organization": "Riot Games",
"channel": "Riot Games", "channel": "Riot Games",
"url": "https://www.youtube.com/user/RiotGamesInc", "url": "https://www.youtube.com/user/RiotGamesInc",
}, },
{ {
"partner": "Riot Games", "organization": "Riot Games",
"channel": "LoL Esports", "channel": "LoL Esports",
"url": "https://www.youtube.com/lolesports", "url": "https://www.youtube.com/lolesports",
}, },
{ {
"partner": "Supercell", "organization": "Supercell",
"channel": "Clash Royale", "channel": "Clash Royale",
"url": "https://www.youtube.com/channel/UC_F8DoJf9MZogEOU51TpTbQ", "url": "https://www.youtube.com/channel/UC_F8DoJf9MZogEOU51TpTbQ",
}, },
{ {
"partner": "Ubisoft", "organization": "Ubisoft",
"channel": "Ubisoft", "channel": "Ubisoft",
"url": "https://www.youtube.com/user/ubisoft", "url": "https://www.youtube.com/user/ubisoft",
}, },
@ -99,17 +103,22 @@ def index(request: HttpRequest) -> HttpResponse:
grouped_channels: dict[str, list[dict[str, str]]] = defaultdict(list) grouped_channels: dict[str, list[dict[str, str]]] = defaultdict(list)
for channel in channels: for channel in channels:
grouped_channels[channel["partner"]].append(channel) grouped_channels[channel["organization"]].append(channel)
partner_groups: list[dict[str, str | list[dict[str, str]]]] = [] organization_groups: list[dict[str, str | list[dict[str, str]]]] = []
for partner in sorted(grouped_channels.keys(), key=str.lower): for organization in sorted(grouped_channels.keys(), key=str.lower):
sorted_items: list[dict[str, str]] = sorted( sorted_items: list[dict[str, str]] = sorted(
grouped_channels[partner], grouped_channels[organization],
key=lambda item: item["channel"].lower(), key=lambda item: item["channel"].lower(),
) )
partner_groups.append({"partner": partner, "channels": sorted_items}) organization_groups.append({
"organization": organization,
"channels": sorted_items,
})
context: dict[str, list[dict[str, str | list[dict[str, str]]]]] = { context: dict[str, str | list[dict[str, str | list[dict[str, str]]]]] = {
"partner_groups": partner_groups, "page_title": PAGE_TITLE,
"page_description": PAGE_DESCRIPTION,
"organization_groups": organization_groups,
} }
return render(request=request, template_name="youtube/index.html", context=context) return render(request=request, template_name="youtube/index.html", context=context)