2026-02-20 16:37:48 -05:00
|
|
|
from django.test import TestCase
|
|
|
|
|
from rest_framework.test import APIClient
|
|
|
|
|
|
2026-03-11 13:59:43 -04:00
|
|
|
from apps.dashboard.models import Item, Note
|
2026-02-20 16:37:48 -05:00
|
|
|
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)
|
|
|
|
|
|
2026-03-11 13:59:43 -04:00
|
|
|
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)
|
2026-02-20 16:37:48 -05:00
|
|
|
|
2026-03-11 13:59:43 -04:00
|
|
|
response = self.client.get(f"/api/notes/{note.id}/")
|
2026-02-20 16:37:48 -05:00
|
|
|
|
|
|
|
|
self.assertEqual(response.status_code, 200)
|
2026-03-11 13:59:43 -04:00
|
|
|
self.assertEqual(response.data["id"], str(note.id))
|
2026-02-20 16:37:48 -05:00
|
|
|
self.assertEqual(len(response.data["items"]), 2)
|
|
|
|
|
|
2026-03-11 13:59:43 -04:00
|
|
|
class NoteItemsAPITest(BaseAPITest):
|
|
|
|
|
def test_can_add_item_to_note(self):
|
|
|
|
|
note = Note.objects.create(owner=self.user)
|
2026-02-20 16:37:48 -05:00
|
|
|
|
|
|
|
|
response = self.client.post(
|
2026-03-11 13:59:43 -04:00
|
|
|
f"/api/notes/{note.id}/items/",
|
2026-02-20 16:37:48 -05:00
|
|
|
{"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")
|
|
|
|
|
|
2026-03-11 13:59:43 -04:00
|
|
|
def test_cannot_add_empty_item_to_note(self):
|
|
|
|
|
note = Note.objects.create(owner=self.user)
|
2026-03-04 13:40:19 -05:00
|
|
|
|
|
|
|
|
response = self.client.post(
|
2026-03-11 13:59:43 -04:00
|
|
|
f"/api/notes/{note.id}/items/",
|
2026-03-04 13:40:19 -05:00
|
|
|
{"text": ""},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
self.assertEqual(response.status_code, 400)
|
|
|
|
|
self.assertEqual(Item.objects.count(), 0)
|
|
|
|
|
|
2026-03-11 13:59:43 -04:00
|
|
|
def test_cannot_add_duplicate_item_to_note(self):
|
|
|
|
|
note = Note.objects.create(owner=self.user)
|
|
|
|
|
Item.objects.create(text="note item", note=note)
|
2026-03-04 13:40:19 -05:00
|
|
|
duplicate_response = self.client.post(
|
2026-03-11 13:59:43 -04:00
|
|
|
f"/api/notes/{note.id}/items/",
|
|
|
|
|
{"text": "note item"},
|
2026-03-04 13:40:19 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
self.assertEqual(duplicate_response.status_code, 400)
|
|
|
|
|
self.assertEqual(Item.objects.count(), 1)
|
|
|
|
|
|
2026-03-11 13:59:43 -04:00
|
|
|
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)
|
2026-02-20 16:37:48 -05:00
|
|
|
other_user = User.objects.create_user("other@example.com")
|
2026-03-11 13:59:43 -04:00
|
|
|
Note.objects.create(owner=other_user)
|
2026-02-20 16:37:48 -05:00
|
|
|
|
2026-03-11 13:59:43 -04:00
|
|
|
response = self.client.get("/api/notes/")
|
2026-02-20 16:37:48 -05:00
|
|
|
|
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
|
self.assertEqual(len(response.data), 1)
|
2026-03-11 13:59:43 -04:00
|
|
|
self.assertEqual(response.data[0]["id"], str(note1.id))
|
2026-02-20 16:37:48 -05:00
|
|
|
|
2026-03-11 13:59:43 -04:00
|
|
|
def test_post_creates_note_with_item(self):
|
2026-02-20 16:37:48 -05:00
|
|
|
response = self.client.post(
|
2026-03-11 13:59:43 -04:00
|
|
|
"/api/notes/",
|
2026-02-20 16:37:48 -05:00
|
|
|
{"text": "first item"},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
self.assertEqual(response.status_code, 201)
|
2026-03-11 13:59:43 -04:00
|
|
|
self.assertEqual(Note.objects.count(), 1)
|
|
|
|
|
self.assertEqual(Note.objects.first().owner, self.user)
|
2026-03-01 21:44:30 -05:00
|
|
|
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])
|