from django.test import TestCase from rest_framework.test import APIClient from apps.dashboard.models import Item, Note 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 NoteDetailAPITest(BaseAPITest): def test_returns_note_with_items(self): note = Note.objects.create(owner=self.user) Item.objects.create(text="item 1", note=note) Item.objects.create(text="item 2", note=note) response = self.client.get(f"/api/notes/{note.id}/") self.assertEqual(response.status_code, 200) self.assertEqual(response.data["id"], str(note.id)) self.assertEqual(len(response.data["items"]), 2) class NoteItemsAPITest(BaseAPITest): def test_can_add_item_to_note(self): note = Note.objects.create(owner=self.user) response = self.client.post( f"/api/notes/{note.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_note(self): note = Note.objects.create(owner=self.user) response = self.client.post( f"/api/notes/{note.id}/items/", {"text": ""}, ) self.assertEqual(response.status_code, 400) self.assertEqual(Item.objects.count(), 0) def test_cannot_add_duplicate_item_to_note(self): note = Note.objects.create(owner=self.user) Item.objects.create(text="note item", note=note) duplicate_response = self.client.post( f"/api/notes/{note.id}/items/", {"text": "note item"}, ) self.assertEqual(duplicate_response.status_code, 400) self.assertEqual(Item.objects.count(), 1) class NotesAPITest(BaseAPITest): def test_get_returns_only_users_notes(self): note1 = Note.objects.create(owner=self.user) Item.objects.create(text="item 1", note=note1) other_user = User.objects.create_user("other@example.com") Note.objects.create(owner=other_user) response = self.client.get("/api/notes/") self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 1) self.assertEqual(response.data[0]["id"], str(note1.id)) def test_post_creates_note_with_item(self): response = self.client.post( "/api/notes/", {"text": "first item"}, ) self.assertEqual(response.status_code, 201) self.assertEqual(Note.objects.count(), 1) self.assertEqual(Note.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])