From abb1dc17fd8a3c0663039ce673d7b06b04c68d78 Mon Sep 17 00:00:00 2001 From: Nick Krichevsky Date: Mon, 10 Jul 2023 19:07:33 -0400 Subject: [PATCH] Add extremely primitve post structure --- printpub/post/__init__.py | 0 printpub/post/apps.py | 6 ++++ printpub/post/migrations/0001_initial.py | 36 ++++++++++++++++++++++ printpub/post/migrations/__init__.py | 0 printpub/post/models/__init__.py | 1 + printpub/post/models/post.py | 9 ++++++ printpub/post/serializers/json/__init__.py | 1 + printpub/post/serializers/json/post.py | 20 ++++++++++++ printpub/post/urls.py | 5 +++ printpub/post/views/__init__.py | 1 + printpub/post/views/post.py | 10 ++++++ printpub/settings.py | 1 + printpub/urls.py | 3 +- tests/post/serializers/post_json_test.py | 28 +++++++++++++++++ tests/post/views/post_test.py | 33 ++++++++++++++++++++ tests/user/views/webfinger_test.py | 4 +-- 16 files changed, 154 insertions(+), 4 deletions(-) create mode 100644 printpub/post/__init__.py create mode 100644 printpub/post/apps.py create mode 100644 printpub/post/migrations/0001_initial.py create mode 100644 printpub/post/migrations/__init__.py create mode 100644 printpub/post/models/__init__.py create mode 100644 printpub/post/models/post.py create mode 100644 printpub/post/serializers/json/__init__.py create mode 100644 printpub/post/serializers/json/post.py create mode 100644 printpub/post/urls.py create mode 100644 printpub/post/views/__init__.py create mode 100644 printpub/post/views/post.py create mode 100644 tests/post/serializers/post_json_test.py create mode 100644 tests/post/views/post_test.py diff --git a/printpub/post/__init__.py b/printpub/post/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/printpub/post/apps.py b/printpub/post/apps.py new file mode 100644 index 0000000..939c84d --- /dev/null +++ b/printpub/post/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class PostConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "printpub.post" diff --git a/printpub/post/migrations/0001_initial.py b/printpub/post/migrations/0001_initial.py new file mode 100644 index 0000000..0b9dc17 --- /dev/null +++ b/printpub/post/migrations/0001_initial.py @@ -0,0 +1,36 @@ +# Generated by Django 4.2.3 on 2023-07-10 19:32 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + ("user", "0004_alter_localuser_poster"), + ] + + operations = [ + migrations.CreateModel( + name="Post", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("content", models.TextField()), + ( + "author", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="user.poster" + ), + ), + ], + ), + ] diff --git a/printpub/post/migrations/__init__.py b/printpub/post/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/printpub/post/models/__init__.py b/printpub/post/models/__init__.py new file mode 100644 index 0000000..8541e8d --- /dev/null +++ b/printpub/post/models/__init__.py @@ -0,0 +1 @@ +from printpub.post.models.post import Post diff --git a/printpub/post/models/post.py b/printpub/post/models/post.py new file mode 100644 index 0000000..d80d9b5 --- /dev/null +++ b/printpub/post/models/post.py @@ -0,0 +1,9 @@ +from django.db import models + +import printpub.user.models + + +class Post(models.Model): + author = models.ForeignKey(printpub.user.models.Poster, on_delete=models.CASCADE) + # TODO: We will want a lot more than text content very quickly... + content = models.TextField() diff --git a/printpub/post/serializers/json/__init__.py b/printpub/post/serializers/json/__init__.py new file mode 100644 index 0000000..06d6b4b --- /dev/null +++ b/printpub/post/serializers/json/__init__.py @@ -0,0 +1 @@ +from printpub.post.serializers.json.post import PostSerializer diff --git a/printpub/post/serializers/json/post.py b/printpub/post/serializers/json/post.py new file mode 100644 index 0000000..cb5dc0a --- /dev/null +++ b/printpub/post/serializers/json/post.py @@ -0,0 +1,20 @@ +import rest_framework.serializers + +import printpub.post.models + + +class _AuthorSerializer(rest_framework.serializers.Serializer): + display_name = rest_framework.serializers.CharField( + source="local_user.display_name", read_only=True + ) + username = rest_framework.serializers.CharField( + source="local_user.username", read_only=True + ) + + +class PostSerializer(rest_framework.serializers.ModelSerializer): + author = _AuthorSerializer() + + class Meta: + model = printpub.post.models.Post + fields = ["content", "author"] diff --git a/printpub/post/urls.py b/printpub/post/urls.py new file mode 100644 index 0000000..98782bc --- /dev/null +++ b/printpub/post/urls.py @@ -0,0 +1,5 @@ +from django.urls import path + +import printpub.post.views.post + +urlpatterns = [path("post/", printpub.post.views.post.PostView.as_view())] diff --git a/printpub/post/views/__init__.py b/printpub/post/views/__init__.py new file mode 100644 index 0000000..5e81437 --- /dev/null +++ b/printpub/post/views/__init__.py @@ -0,0 +1 @@ +from printpub.post.views.post import PostView diff --git a/printpub/post/views/post.py b/printpub/post/views/post.py new file mode 100644 index 0000000..cc656b1 --- /dev/null +++ b/printpub/post/views/post.py @@ -0,0 +1,10 @@ +import rest_framework +import rest_framework.generics + +import printpub.post.models +import printpub.post.serializers.json + + +class PostView(rest_framework.generics.RetrieveAPIView): + queryset = printpub.post.models.Post.objects.all() + serializer_class = printpub.post.serializers.json.PostSerializer diff --git a/printpub/settings.py b/printpub/settings.py index 6b4dff1..aa088a9 100644 --- a/printpub/settings.py +++ b/printpub/settings.py @@ -43,6 +43,7 @@ INSTALLED_APPS = [ "django.contrib.sites", "rest_framework", "printpub.user.apps.UserConfig", + "printpub.post.apps.PostConfig", ] AUTH_USER_MODEL = "user.LocalUser" diff --git a/printpub/urls.py b/printpub/urls.py index a9cff16..5e12a8c 100644 --- a/printpub/urls.py +++ b/printpub/urls.py @@ -17,9 +17,8 @@ Including another URLconf from django.contrib import admin from django.urls import include, path -import printpub.user.urls - urlpatterns = [ path("", include("printpub.user.urls")), + path("", include("printpub.post.urls")), path("admin/", admin.site.urls), ] diff --git a/tests/post/serializers/post_json_test.py b/tests/post/serializers/post_json_test.py new file mode 100644 index 0000000..504a794 --- /dev/null +++ b/tests/post/serializers/post_json_test.py @@ -0,0 +1,28 @@ +import json + +import printpub.post.models +import printpub.post.serializers.json +import printpub.user.models + + +def test_serializes_post(): + poster = printpub.user.models.Poster() + poster.save() + user = printpub.user.models.LocalUser( + username="wint", password="hunter2", display_name="dril", poster=poster + ) + user.save() + post = printpub.post.models.Post( + author=poster, + content='"im not owned! im not owned!!", i continue to insist as i slowly shrink and transform into a corn cob', + ) + + post_serializer = printpub.post.serializers.json.PostSerializer(post) + assert post_serializer.data == { + "content": '"im not owned! im not owned!!", i continue to insist as i slowly shrink and transform into a corn cob', + "author": { + "display_name": "dril", + "username": "wint", + # TODO: work domain into here somehow + }, + } diff --git a/tests/post/views/post_test.py b/tests/post/views/post_test.py new file mode 100644 index 0000000..a710d65 --- /dev/null +++ b/tests/post/views/post_test.py @@ -0,0 +1,33 @@ +import rest_framework + +import printpub.post.models +import printpub.user.models + + +class TestPostGet: + def test_getting_nonexistent_post_returns_404(self): + client = rest_framework.test.APIClient() + res = client.get("/post/1234") + assert res.status_code == 404 + + def test_get_200_with_existing_post(self): + poster = printpub.user.models.Poster() + poster.save() + user = printpub.user.models.LocalUser( + username="wint", password="hunter2", display_name="dril", poster=poster + ) + user.save() + post = printpub.post.models.Post( + author=poster, + content='"im not owned! im not owned!!", i continue to insist as i slowly shrink and transform into a corn cob', + ) + post.save() + + client = rest_framework.test.APIClient() + res = client.get(f"/post/{post.pk}") + assert res.status_code == 200 + # More data is validated by the serializer, this is just a sanity check + assert ( + res.data["content"] + == '"im not owned! im not owned!!", i continue to insist as i slowly shrink and transform into a corn cob' + ) diff --git a/tests/user/views/webfinger_test.py b/tests/user/views/webfinger_test.py index 1f86062..8adceda 100644 --- a/tests/user/views/webfinger_test.py +++ b/tests/user/views/webfinger_test.py @@ -11,12 +11,12 @@ class TestWebfingerGet: def test_request_with_no_resource_gives_400(self): client = rest_framework.test.APIClient() res = client.get("/.well-known/webfinger") - assert res.status_code == 400 # type: ignore + assert res.status_code == 400 def test_request_with_unknown_user_returns_404(self): client = rest_framework.test.APIClient() res = client.get("/.well-known/webfinger?resource=acct:wint@my.website") - assert res.status_code == 404 # type: ignore + assert res.status_code == 404 def test_known_user_returns_serializer_data(self): client = rest_framework.test.APIClient()