commenced DRF efforts w. package installation, creation of apps.api, w. UTs & ITs to ensure core efficacy; core.settings & .urls changed to accomodate
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed

This commit is contained in:
Disco DeDisco
2026-02-20 16:37:48 -05:00
parent ed21730a38
commit 9bdc358e59
13 changed files with 149 additions and 0 deletions

View File

@@ -9,6 +9,7 @@ dj-database-url
Django==6.0
django-stubs==5.2.8
django-stubs-ext==5.2.8
djangorestframework
gunicorn==23.0.0
h11==0.16.0
idna==3.11

View File

@@ -3,6 +3,7 @@ Django==6.0
dj-database-url
django-stubs==5.2.8
django-stubs-ext==5.2.8
djangorestframework
gunicorn==23.0.0
lxml==6.0.2
psycopg2-binary

0
src/apps/api/__init__.py Normal file
View File

View File

@@ -0,0 +1,17 @@
from rest_framework import serializers
from apps.dashboard.models import Item, List
class ItemSerializer(serializers.ModelSerializer):
class Meta:
model = Item
fields = ["id", "text"]
class ListSerializer(serializers.ModelSerializer):
name = serializers.ReadOnlyField()
url = serializers.CharField(source="get_absolute_url", read_only=True)
items = ItemSerializer(many=True, read_only=True, source="item_set")
class Meta:
model = List
fields = ["id", "name", "url", "items"]

View File

View File

@@ -0,0 +1,62 @@
from django.test import TestCase
from rest_framework.test import APIClient
from apps.dashboard.models import Item, List
from apps.lyric.models import User
class BaseAPITest(TestCase):
# Helper fns
def setUp(self):
self.client = APIClient()
self.user = User.objects.create_user("test@example.com")
self.client.force_authenticate(user=self.user)
class ListDetailAPITest(BaseAPITest):
def test_returns_list_with_items(self):
list_ = List.objects.create(owner=self.user)
Item.objects.create(text="item 1", list=list_)
Item.objects.create(text="item 2", list=list_)
response = self.client.get(f"/api/lists/{list_.id}/")
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data["id"], list_.id)
self.assertEqual(len(response.data["items"]), 2)
class ListItemsAPITest(BaseAPITest):
def test_can_add_item_to_list(self):
list_ = List.objects.create(owner=self.user)
response = self.client.post(
f"/api/lists/{list_.id}/items/",
{"text": "a new item"},
)
self.assertEqual(response.status_code, 201)
self.assertEqual(Item.objects.count(), 1)
self.assertEqual(Item.objects.first().text, "a new item")
class ListsAPITest(BaseAPITest):
def test_get_returns_only_users_lists(self):
list1 = List.objects.create(owner=self.user)
Item.objects.create(text="item 1", list=list1)
other_user = User.objects.create_user("other@example.com")
List.objects.create(owner=other_user)
response = self.client.get("/api/lists/")
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), 1)
self.assertEqual(response.data[0]["id"], list1.id)
def test_post_creates_list_with_item(self):
response = self.client.post(
"/api/lists/",
{"text": "first item"},
)
self.assertEqual(response.status_code, 201)
self.assertEqual(List.objects.count(), 1)
self.assertEqual(List.objects.first().owner, self.user)
self.assertEqual(Item.objects.first().text, "first item")

View File

View File

@@ -0,0 +1,20 @@
from django.test import SimpleTestCase
from apps.api.serializers import ItemSerializer, ListSerializer
class ItemSerializerTest(SimpleTestCase):
def test_fields(self):
serializer = ItemSerializer()
self.assertEqual(
set(serializer.fields.keys()),
{"id", "text"},
)
class ListSerializerTest(SimpleTestCase):
def test_fields(self):
serializer = ListSerializer()
self.assertEqual(
set(serializer.fields.keys()),
{"id", "name", "url", "items"},
)

11
src/apps/api/urls.py Normal file
View File

@@ -0,0 +1,11 @@
from django.urls import path
from . import views
urlpatterns = [
path('', views.ListsAPI.as_view(), name='api_lists'),
path('<int:list_id>/', views.ListDetailAPI.as_view(), name='api_list_detail'),
path('<int:list_id>/items/', views.ListItemsAPI.as_view(), name='api_list_items'),
]

34
src/apps/api/views.py Normal file
View File

@@ -0,0 +1,34 @@
from django.shortcuts import get_object_or_404
from rest_framework.views import APIView
from rest_framework.response import Response
from apps.dashboard.models import Item, List
from apps.api.serializers import ItemSerializer, ListSerializer
class ListDetailAPI(APIView):
def get(self, request, list_id):
list_ = get_object_or_404(List, id=list_id)
serializer = ListSerializer(list_)
return Response(serializer.data)
class ListItemsAPI(APIView):
def post(self, request, list_id):
list_ = get_object_or_404(List, id=list_id)
serializer = ItemSerializer(data=request.data)
if serializer.is_valid():
serializer.save(list=list_)
return Response(serializer.data, status=201)
return Response(serializer.errors, status=400)
class ListsAPI(APIView):
def get(self, request):
lists = List.objects.filter(owner=request.user)
serializer = ListSerializer(lists, many=True)
return Response(serializer.data)
def post(self, request):
list_ = List.objects.create(owner=request.user)
item = Item.objects.create(text=request.data.get("text", ""), list=list_)
serializer = ListSerializer(list_)
return Response(serializer.data, status=201)

View File

@@ -54,8 +54,10 @@ INSTALLED_APPS = [
# Custom apps
'apps.dashboard',
'apps.lyric',
'apps.api',
'functional_tests',
# Depend apps
'rest_framework',
]
# if 'DJANGO_DEBUG_FALSE' not in os.environ:

View File

@@ -8,6 +8,7 @@ urlpatterns = [
path('', dash_views.home_page, name='home'),
path('apps/dashboard/', include('apps.dashboard.urls')),
path('apps/lyric/', include('apps.lyric.urls')),
path('api/lists/', include('apps.api.urls')),
]
# Please remove the following urlpattern