From 143e81fc41e57f003235e1528162e8efde69d37f Mon Sep 17 00:00:00 2001 From: Disco DeDisco Date: Sun, 1 Mar 2026 21:44:30 -0500 Subject: [PATCH] updated new username feature to api app; restructured api urlpatterns for more sustainable pahts --- src/apps/api/serializers.py | 7 +++++ src/apps/api/tests/integrated/test_views.py | 34 ++++++++++++++++++++- src/apps/api/urls.py | 7 +++-- src/apps/api/views.py | 13 +++++++- src/core/urls.py | 4 ++- 5 files changed, 59 insertions(+), 6 deletions(-) diff --git a/src/apps/api/serializers.py b/src/apps/api/serializers.py index 640a41f..023fbb8 100644 --- a/src/apps/api/serializers.py +++ b/src/apps/api/serializers.py @@ -1,5 +1,7 @@ from rest_framework import serializers + from apps.dashboard.models import Item, List +from apps.lyric.models import User class ItemSerializer(serializers.ModelSerializer): @@ -15,3 +17,8 @@ class ListSerializer(serializers.ModelSerializer): class Meta: model = List fields = ["id", "name", "url", "items"] + +class UserSerializer(serializers.ModelSerializer): + class Meta: + model = User + fields = ["id", "username"] diff --git a/src/apps/api/tests/integrated/test_views.py b/src/apps/api/tests/integrated/test_views.py index 3dd5be7..9a6d2e6 100644 --- a/src/apps/api/tests/integrated/test_views.py +++ b/src/apps/api/tests/integrated/test_views.py @@ -59,4 +59,36 @@ class ListsAPITest(BaseAPITest): 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") \ No newline at end of file + self.assertEqual(Item.objects.first().text, "first item") + +class UserSearchAPITest(BaseAPITest): + def test_returns_users_matching_username(self): + disco = User.objects.create_user("disco@example.com") + disco.username = "discoman" + disco.searchable = True + disco.save() + + response = self.client.get("/api/users/?q=disc") + + self.assertEqual(response.status_code, 200) + self.assertEqual(len(response.data), 1) + self.assertEqual(response.data[0]["username"], "discoman") + + def test_non_searchable_users_are_excluded(self): + alice = User.objects.create_user("alice@example.com") + alice.username = "princessAli" + alice.save() # searchable defaults to False + + response = self.client.get("/api/users/?q=prin") + + self.assertEqual(response.data, []) + + def test_response_does_not_include_email(self): + alice = User.objects.create_user("alice@example.com") + alice.username = "princessAli" + alice.searchable = True + alice.save() + + response = self.client.get("/api/users/?q=prin") + + self.assertNotIn("email", response.data[0]) diff --git a/src/apps/api/urls.py b/src/apps/api/urls.py index 08e6d5f..1e94041 100644 --- a/src/apps/api/urls.py +++ b/src/apps/api/urls.py @@ -4,8 +4,9 @@ from . import views urlpatterns = [ - path('', views.ListsAPI.as_view(), name='api_lists'), - path('/', views.ListDetailAPI.as_view(), name='api_list_detail'), - path('/items/', views.ListItemsAPI.as_view(), name='api_list_items'), + path('lists/', views.ListsAPI.as_view(), name='api_lists'), + path('lists//', views.ListDetailAPI.as_view(), name='api_list_detail'), + path('lists//items/', views.ListItemsAPI.as_view(), name='api_list_items'), + path('users/', views.UserSearchAPI.as_view(), name='api_users'), ] diff --git a/src/apps/api/views.py b/src/apps/api/views.py index eb083ff..ee0defa 100644 --- a/src/apps/api/views.py +++ b/src/apps/api/views.py @@ -2,8 +2,9 @@ from django.shortcuts import get_object_or_404 from rest_framework.views import APIView from rest_framework.response import Response +from apps.api.serializers import ItemSerializer, ListSerializer, UserSerializer from apps.dashboard.models import Item, List -from apps.api.serializers import ItemSerializer, ListSerializer +from apps.lyric.models import User class ListDetailAPI(APIView): @@ -32,3 +33,13 @@ class ListsAPI(APIView): item = Item.objects.create(text=request.data.get("text", ""), list=list_) serializer = ListSerializer(list_) return Response(serializer.data, status=201) + +class UserSearchAPI(APIView): + def get(self, request): + q = request.query_params.get("q", "") + users = User.objects.filter( + username__icontains=q, + searchable=True, + ) + serializer = UserSerializer(users, many=True) + return Response(serializer.data) diff --git a/src/core/urls.py b/src/core/urls.py index a2f2ebd..2442a55 100644 --- a/src/core/urls.py +++ b/src/core/urls.py @@ -1,14 +1,16 @@ from django.contrib import admin from django.http import HttpResponse from django.urls import include, path + from apps.dashboard import views as dash_views + urlpatterns = [ path('admin/', admin.site.urls), path('', dash_views.home_page, name='home'), + path('api/', include('apps.api.urls')), path('dashboard/', include('apps.dashboard.urls')), path('lyric/', include('apps.lyric.urls')), - path('api/lists/', include('apps.api.urls')), ] # Please remove the following urlpattern