Move organization info into game heading for Kick campaigns on dashboard
All checks were successful
Deploy to Server / deploy (push) Successful in 29s
All checks were successful
Deploy to Server / deploy (push) Successful in 29s
This commit is contained in:
parent
64a622b6fa
commit
decc8ae5ab
3 changed files with 107 additions and 15 deletions
|
|
@ -1,3 +1,5 @@
|
||||||
|
from datetime import UTC
|
||||||
|
from datetime import datetime as dt
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from django.test import RequestFactory
|
from django.test import RequestFactory
|
||||||
|
|
@ -6,6 +8,9 @@ from django.test.utils import override_settings
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
from core.views import _build_base_url
|
from core.views import _build_base_url
|
||||||
|
from kick.models import KickCategory
|
||||||
|
from kick.models import KickDropCampaign
|
||||||
|
from kick.models import KickOrganization
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from django.test.client import _MonkeyPatchedWSGIResponse
|
from django.test.client import _MonkeyPatchedWSGIResponse
|
||||||
|
|
@ -43,3 +48,76 @@ class TestSitemapViews(TestCase):
|
||||||
)
|
)
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert "<urlset" in response.content.decode()
|
assert "<urlset" in response.content.decode()
|
||||||
|
|
||||||
|
|
||||||
|
class TestCoreDashboardKickSection(TestCase):
|
||||||
|
"""Tests for the Kick campaigns section within the core dashboard."""
|
||||||
|
|
||||||
|
def _make_org(self, kick_id: str, name: str) -> KickOrganization:
|
||||||
|
return KickOrganization.objects.create(kick_id=kick_id, name=name)
|
||||||
|
|
||||||
|
def _make_category(self, kick_id: int, name: str) -> KickCategory:
|
||||||
|
return KickCategory.objects.create(
|
||||||
|
kick_id=kick_id,
|
||||||
|
name=name,
|
||||||
|
slug=name.lower().replace(" ", "-"),
|
||||||
|
)
|
||||||
|
|
||||||
|
def _make_campaign(
|
||||||
|
self,
|
||||||
|
kick_id: str,
|
||||||
|
name: str,
|
||||||
|
category: KickCategory | None,
|
||||||
|
organization: KickOrganization,
|
||||||
|
) -> KickDropCampaign:
|
||||||
|
return KickDropCampaign.objects.create(
|
||||||
|
kick_id=kick_id,
|
||||||
|
name=name,
|
||||||
|
status="active",
|
||||||
|
starts_at=dt(2020, 1, 1, tzinfo=UTC),
|
||||||
|
ends_at=dt(2099, 12, 31, tzinfo=UTC),
|
||||||
|
organization=organization,
|
||||||
|
category=category,
|
||||||
|
rule_id=1,
|
||||||
|
rule_name="Watch to redeem",
|
||||||
|
is_fully_imported=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_shows_organization_under_game_heading(self) -> None:
|
||||||
|
"""Organization name should appear under the game heading, not per-campaign."""
|
||||||
|
org: KickOrganization = self._make_org("org-test-1", "Test Studio")
|
||||||
|
cat: KickCategory = self._make_category(999, "Test Game")
|
||||||
|
self._make_campaign("camp-test-1", "Test Campaign", cat, org)
|
||||||
|
|
||||||
|
response: _MonkeyPatchedWSGIResponse = self.client.get(
|
||||||
|
reverse("core:dashboard"),
|
||||||
|
)
|
||||||
|
content: str = response.content.decode()
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
# Organization should be near the game heading
|
||||||
|
assert "Test Studio" in content
|
||||||
|
# Game name should appear
|
||||||
|
assert "Test Game" in content
|
||||||
|
|
||||||
|
def test_unknown_category_shows_org_link_in_heading(self) -> None:
|
||||||
|
"""Campaigns without a category should show org name as the heading."""
|
||||||
|
org: KickOrganization = self._make_org("org-uncat-1", "Uncategorized Org")
|
||||||
|
campaign: KickDropCampaign = self._make_campaign(
|
||||||
|
"camp-uncat-1",
|
||||||
|
"No Category Campaign",
|
||||||
|
None,
|
||||||
|
org,
|
||||||
|
)
|
||||||
|
|
||||||
|
response: _MonkeyPatchedWSGIResponse = self.client.get(
|
||||||
|
reverse("core:dashboard"),
|
||||||
|
)
|
||||||
|
content: str = response.content.decode()
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert campaign.name in content
|
||||||
|
# Org name should appear as a link to the org detail page
|
||||||
|
org_url: str = reverse("kick:organization_detail", args=[org.kick_id])
|
||||||
|
assert org_url in content
|
||||||
|
assert "Unknown Category" not in content
|
||||||
|
|
|
||||||
|
|
@ -1062,8 +1062,14 @@ def dashboard(request: HttpRequest) -> HttpResponse:
|
||||||
"image": game_image,
|
"image": game_image,
|
||||||
"kick_id": game_kick_id,
|
"kick_id": game_kick_id,
|
||||||
"campaigns": [],
|
"campaigns": [],
|
||||||
|
"organizations": [],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if campaign.organization:
|
||||||
|
org = campaign.organization
|
||||||
|
if org not in kick_campaigns_by_game[game_key]["organizations"]:
|
||||||
|
kick_campaigns_by_game[game_key]["organizations"].append(org)
|
||||||
|
|
||||||
kick_campaigns_by_game[game_key]["campaigns"].append({
|
kick_campaigns_by_game[game_key]["campaigns"].append({
|
||||||
"campaign": campaign,
|
"campaign": campaign,
|
||||||
"channels": list(campaign.channels.all()),
|
"channels": list(campaign.channels.all()),
|
||||||
|
|
|
||||||
|
|
@ -203,6 +203,15 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</a>
|
</a>
|
||||||
</h3>
|
</h3>
|
||||||
|
{% if campaign.ends_at %}
|
||||||
|
<p style="margin: 0.25rem 0;">
|
||||||
|
<strong>Ends:</strong>
|
||||||
|
<time datetime="{{ campaign.ends_at|date:'c' }}"
|
||||||
|
title="{{ campaign.ends_at|date:'DATETIME_FORMAT' }}">
|
||||||
|
{{ campaign.ends_at|date:"M d, Y H:i" }}
|
||||||
|
</time>
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
{% if campaign.game %}
|
{% if campaign.game %}
|
||||||
<p style="margin: 0.25rem 0;">
|
<p style="margin: 0.25rem 0;">
|
||||||
<strong>Game:</strong>
|
<strong>Game:</strong>
|
||||||
|
|
@ -213,15 +222,6 @@
|
||||||
<strong>Type:</strong> Site-wide reward campaign
|
<strong>Type:</strong> Site-wide reward campaign
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if campaign.ends_at %}
|
|
||||||
<p style="margin: 0.25rem 0;">
|
|
||||||
<strong>Ends:</strong>
|
|
||||||
<time datetime="{{ campaign.ends_at|date:'c' }}"
|
|
||||||
title="{{ campaign.ends_at|date:'DATETIME_FORMAT' }}">
|
|
||||||
{{ campaign.ends_at|date:"M d, Y H:i" }}
|
|
||||||
</time>
|
|
||||||
</p>
|
|
||||||
{% endif %}
|
|
||||||
{% if campaign.summary %}
|
{% if campaign.summary %}
|
||||||
<p>{{ campaign.summary }}</p>
|
<p>{{ campaign.summary }}</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
@ -254,10 +254,24 @@
|
||||||
<h3 style="margin: 0 0 0.5rem 0;">
|
<h3 style="margin: 0 0 0.5rem 0;">
|
||||||
{% if game_data.kick_id %}
|
{% if game_data.kick_id %}
|
||||||
<a href="{% url 'kick:game_detail' game_data.kick_id %}">{{ game_data.name }}</a>
|
<a href="{% url 'kick:game_detail' game_data.kick_id %}">{{ game_data.name }}</a>
|
||||||
|
{% elif game_data.organizations %}
|
||||||
|
{% for org in game_data.organizations %}
|
||||||
|
<a href="{% url 'kick:organization_detail' org.kick_id %}">{{ org.name }}</a>
|
||||||
|
{% if not forloop.last %}, {% endif %}
|
||||||
|
{% endfor %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ game_data.name }}
|
{{ game_data.name }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</h3>
|
</h3>
|
||||||
|
{% if game_data.kick_id and game_data.organizations %}
|
||||||
|
<div style="font-size: 0.9rem; color: #666;">
|
||||||
|
Organization:
|
||||||
|
{% for org in game_data.organizations %}
|
||||||
|
<a href="{% url 'kick:organization_detail' org.kick_id %}">{{ org.name }}</a>
|
||||||
|
{% if not forloop.last %}, {% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
</header>
|
</header>
|
||||||
<div style="display: flex; gap: 1rem;">
|
<div style="display: flex; gap: 1rem;">
|
||||||
<div style="flex-shrink: 0;">
|
<div style="flex-shrink: 0;">
|
||||||
|
|
@ -315,12 +329,6 @@
|
||||||
text-align: left">
|
text-align: left">
|
||||||
Started {{ campaign_data.campaign.starts_at|timesince }} ago
|
Started {{ campaign_data.campaign.starts_at|timesince }} ago
|
||||||
</time>
|
</time>
|
||||||
{% if campaign_data.campaign.organization %}
|
|
||||||
<p style="margin: 0.25rem 0; font-size: 0.9rem; text-align: left;">
|
|
||||||
<strong>Organization:</strong>
|
|
||||||
<a href="{% url 'kick:organization_detail' campaign_data.campaign.organization.kick_id %}">{{ campaign_data.campaign.organization.name }}</a>
|
|
||||||
</p>
|
|
||||||
{% endif %}
|
|
||||||
<div style="margin-top: 0.5rem; font-size: 0.8rem;">
|
<div style="margin-top: 0.5rem; font-size: 0.8rem;">
|
||||||
<strong>Channels:</strong>
|
<strong>Channels:</strong>
|
||||||
<ul style="margin: 0.25rem 0 0 0;
|
<ul style="margin: 0.25rem 0 0 0;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue