Skip to content

Commit

Permalink
Add DynamicHTML options and endpoints for Cyberstorm
Browse files Browse the repository at this point in the history
  • Loading branch information
Oksamies committed May 23, 2024
1 parent 4c9d27c commit 3066f62
Show file tree
Hide file tree
Showing 6 changed files with 211 additions and 0 deletions.
129 changes: 129 additions & 0 deletions django/thunderstore/api/cyberstorm/tests/test_dynamic_html.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import pytest
from rest_framework.test import APIClient

from thunderstore.frontend.models import DynamicHTML, DynamicPlacement


@pytest.mark.django_db
def test_get_dynamic_html__returns_not_found__when_no_active(
api_client: APIClient,
) -> None:
DynamicHTML.objects.create(
name="dynamic_placement_1",
placement=DynamicPlacement.cyberstorm_header,
content="<title>DYNAMIC HTML TITLE</title>",
ordering=0,
is_active=False,
)
DynamicHTML.objects.create(
name="dynamic_placement_2",
placement=DynamicPlacement.cyberstorm_header,
content='<script>console.log("DYNAMIC HTML SCRIPT")</script>',
ordering=1,
is_active=False,
)

response = api_client.get(
f"/api/cyberstorm/dynamichtml/{DynamicPlacement.cyberstorm_header}/",
)
actual = response.json()

assert actual["detail"] == "Not found."


@pytest.mark.django_db
def test_get_dynamic_html__returns_not_found__when_bad_placement_arg(
api_client: APIClient,
) -> None:
DynamicHTML.objects.create(
name="dynamic_placement_1",
placement=DynamicPlacement.cyberstorm_header,
content="<title>DYNAMIC HTML TITLE</title>",
ordering=0,
)

response = api_client.get(
f"/api/cyberstorm/dynamichtml/{DynamicPlacement.cyberstorm_header + 'bad'}/",
)
actual = response.json()

assert actual["detail"] == "Not found."


@pytest.mark.django_db
def test_get_dynamic_html__returns_not_found__when_placement_arg_doesnt_start_with_cyberstorm(
api_client: APIClient,
) -> None:
DynamicHTML.objects.create(
name="dynamic_placement_1",
placement=DynamicPlacement.cyberstorm_header,
content="<title>DYNAMIC HTML TITLE</title>",
ordering=0,
)

response = api_client.get(
f"/api/cyberstorm/dynamichtml/{DynamicPlacement.cyberstorm_header[len('cyberstorm_'):]}/",
)
actual = response.json()

assert actual["detail"] == "Not found."


@pytest.mark.django_db
def test_get_dynamic_html__returns_correct_object__when_multiple(
api_client: APIClient,
) -> None:
DynamicHTML.objects.create(
name="dynamic_placement_1",
placement=DynamicPlacement.cyberstorm_header,
content="<title>DYNAMIC HTML TITLE</title>",
ordering=0,
is_active=False,
)
DynamicHTML.objects.create(
name="dynamic_placement_2",
placement=DynamicPlacement.cyberstorm_header,
content='<script>console.log("DYNAMIC HTML SCRIPT")</script>',
ordering=1,
)

response = api_client.get(
f"/api/cyberstorm/dynamichtml/{DynamicPlacement.cyberstorm_header}/",
)
actual = response.json()

assert (
actual["dynamic_htmls"][0]
== "\\u003Cscript\\u003Econsole.log(\\u0022DYNAMIC HTML SCRIPT\\u0022)\\u003C/script\\u003E"
)


@pytest.mark.django_db
def test_get_dynamic_html__returns_multiple(api_client: APIClient) -> None:
DynamicHTML.objects.create(
name="dynamic_placement_1",
placement=DynamicPlacement.cyberstorm_header,
content="<title>DYNAMIC HTML TITLE</title>",
ordering=1,
is_active=False,
)
DynamicHTML.objects.create(
name="dynamic_placement_2",
placement=DynamicPlacement.cyberstorm_header,
content='<script>console.log("DYNAMIC HTML SCRIPT")</script>',
ordering=0,
)

response = api_client.get(
f"/api/cyberstorm/dynamichtml/{DynamicPlacement.cyberstorm_header}/",
)
actual = response.json()

assert (
actual["dynamic_htmls"][0]
== "\\u003Cscript\\u003Econsole.log(\\u0022DYNAMIC HTML SCRIPT\\u0022)\\u003C/script\\u003E"
)
assert (
actual["dynamic_htmls"][1]
== "\\u003Ctitle\\u003EDYNAMIC HTML TITLE\\u003C/title\\u003E"
)
2 changes: 2 additions & 0 deletions django/thunderstore/api/cyberstorm/views/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from .community import CommunityAPIView
from .community_filters import CommunityFiltersAPIView
from .community_list import CommunityListAPIView
from .dynamic_html import DynamicHTMLAPIView
from .markdown import PackageVersionChangelogAPIView, PackageVersionReadmeAPIView
from .package_listing import PackageListingAPIView
from .package_listing_list import (
Expand Down Expand Up @@ -31,4 +32,5 @@
"TeamMemberAddAPIView",
"TeamMemberListAPIView",
"TeamServiceAccountListAPIView",
"DynamicHTMLAPIView",
]
32 changes: 32 additions & 0 deletions django/thunderstore/api/cyberstorm/views/dynamic_html.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from django.http import Http404
from django.utils.html import escapejs
from rest_framework import serializers
from rest_framework.generics import RetrieveAPIView

from thunderstore.api.utils import CyberstormAutoSchemaMixin
from thunderstore.frontend.models import DynamicHTML, DynamicPlacement


class CyberstormDynamicHTMLResponseSerializer(serializers.Serializer):
dynamic_htmls = serializers.ListField(child=serializers.CharField())


class DynamicHTMLAPIView(CyberstormAutoSchemaMixin, RetrieveAPIView):
"""
Return Cyberstorm dynamic html placement contents as prerendered HTML.
"""

serializer_class = CyberstormDynamicHTMLResponseSerializer

def get_object(self):
if (
self.kwargs["placement"].startswith("cyberstorm_")
and self.kwargs["placement"] in DynamicPlacement.options()
):
dynamic_htmls = DynamicHTML.objects.filter(
placement=self.kwargs["placement"],
is_active=True,
).order_by("ordering")

return {"dynamic_htmls": [escapejs(dh.content) for dh in dynamic_htmls]}
raise Http404
6 changes: 6 additions & 0 deletions django/thunderstore/api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
CommunityAPIView,
CommunityFiltersAPIView,
CommunityListAPIView,
DynamicHTMLAPIView,
PackageListingAPIView,
PackageListingByCommunityListAPIView,
PackageListingByDependencyListAPIView,
Expand All @@ -18,6 +19,11 @@
)

cyberstorm_urls = [
path(
"dynamichtml/<str:placement>/",
DynamicHTMLAPIView.as_view(),
name="cyberstorm.dynamichtml",
),
path(
"community/",
CommunityListAPIView.as_view(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Generated by Django 3.1.7 on 2024-05-23 17:11

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("frontend", "0012_add_footer_links"),
]

operations = [
migrations.AlterField(
model_name="dynamichtml",
name="placement",
field=models.CharField(
choices=[
("ads_txt", "ads_txt"),
("robots_txt", "robots_txt"),
("html_head", "html_head"),
("html_body_beginning", "html_body_beginning"),
("content_beginning", "content_beginning"),
("footer_top", "footer_top"),
("footer_bottom", "footer_bottom"),
("content_end", "content_end"),
("package_page_actions", "package_page_actions"),
("main_content_left", "main_content_left"),
("main_content_right", "main_content_right"),
("cyberstorm_header", "cyberstorm_header"),
("cyberstorm_body_beginning", "cyberstorm_body_beginning"),
("cyberstorm_content_left", "cyberstorm_content_left"),
("cyberstorm_content_right", "cyberstorm_content_right"),
],
db_index=True,
max_length=256,
),
),
]
4 changes: 4 additions & 0 deletions django/thunderstore/frontend/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ class DynamicPlacement(ChoiceEnum):
package_page_actions = "package_page_actions"
main_content_left = "main_content_left"
main_content_right = "main_content_right"
cyberstorm_header = "cyberstorm_header"
cyberstorm_body_beginning = "cyberstorm_body_beginning"
cyberstorm_content_left = "cyberstorm_content_left"
cyberstorm_content_right = "cyberstorm_content_right"


class DynamicHTML(models.Model):
Expand Down

0 comments on commit 3066f62

Please sign in to comment.