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"], str(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") def test_cannot_add_empty_item_to_list(self): list_ = List.objects.create(owner=self.user) response = self.client.post( f"/api/lists/{list_.id}/items/", {"text": ""}, ) self.assertEqual(response.status_code, 400) self.assertEqual(Item.objects.count(), 0) def test_cannot_add_duplicate_item_to_list(self): list_ = List.objects.create(owner=self.user) Item.objects.create(text="list item", list=list_) duplicate_response = self.client.post( f"/api/lists/{list_.id}/items/", {"text": "list item"}, ) self.assertEqual(duplicate_response.status_code, 400) self.assertEqual(Item.objects.count(), 1) 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"], str(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") 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])