Skip to content
Snippets Groups Projects
Commit 2a6728ad authored by Konrad Mohrfeldt's avatar Konrad Mohrfeldt :koala:
Browse files

test: implement tests for note REST API endpoint

parent f1d339d8
No related branches found
No related tags found
1 merge request!25Refactor Note REST API endpoint
Pipeline #3103 passed
import datetime
from django.contrib.auth.models import User
from django.utils.text import slugify
from django.utils.timezone import now
from program.models import Note, RRule, Schedule, Show, TimeSlot
class SteeringTestCaseMixin:
base_url = "/api/v1"
def _url(self, *paths, **kwargs):
url = "/".join(str(p) for p in paths) + "/"
return f"{self.base_url}/{url.format(**kwargs)}"
def _get_client(self, user=None):
client = self.client_class()
if user:
client.force_authenticate(user=user)
return client
class UserMixin:
user_admin: User
user_common: User
def setUp(self):
self.user_admin = User.objects.create_superuser(
"admin", "admin@aura.radio", password="admin"
)
self.user_common = User.objects.create_user(
"herbert", "herbert@aura.radio", password="herbert"
)
class ShowMixin:
def _create_show(self, name: str, **kwargs):
kwargs["name"] = name
kwargs.setdefault("slug", slugify(name))
kwargs.setdefault("short_description", f"The {name} show")
owners = kwargs.pop("owners", [])
show = Show.objects.create(**kwargs)
if owners:
show.owners.set(owners)
return show
class ScheduleMixin:
def _get_rrule(self):
rrule = RRule.objects.first()
if rrule is None:
rrule = RRule.objects.create(name="once", freq=0)
return rrule
def _create_schedule(self, show: Show, **kwargs):
_first_date = kwargs.get("first_date", now().date())
kwargs["show"] = show
kwargs.setdefault("first_date", _first_date)
kwargs.setdefault("start_time", "08:00")
kwargs.setdefault("last_date", _first_date + datetime.timedelta(days=365))
kwargs.setdefault("end_time", "09:00")
kwargs.setdefault("rrule", self._get_rrule())
return Schedule.objects.create(**kwargs)
class TimeSlotMixin:
def _create_timeslot(self, schedule: Schedule, **kwargs):
_start = kwargs.get("start", now())
kwargs.setdefault("schedule", schedule)
kwargs.setdefault("show", schedule.show)
kwargs.setdefault("start", _start)
kwargs.setdefault("end", _start + datetime.timedelta(hours=1))
return TimeSlot.objects.create(**kwargs)
class NoteMixin:
def _create_note(self, timeslot: TimeSlot, **kwargs):
note_count = Note.objects.all().count()
_title = kwargs.get("title", f"a random note #{note_count}")
kwargs["timeslot"] = timeslot
kwargs["title"] = _title
kwargs.setdefault("slug", slugify(_title))
return Note.objects.create(**kwargs)
def _create_random_note_content(self, **kwargs):
note_count = Note.objects.all().count()
_title = kwargs.get("title", f"a random note #{note_count}")
kwargs["title"] = _title
kwargs.setdefault("slug", slugify(_title))
kwargs.setdefault("content", "some random content")
kwargs.setdefault("contributors", [])
return kwargs
class ProgramModelMixin(ShowMixin, ScheduleMixin, TimeSlotMixin, NoteMixin):
pass
class BaseMixin(UserMixin, ProgramModelMixin, SteeringTestCaseMixin):
pass
from rest_framework.test import APITransactionTestCase
from program import tests
from program.models import Schedule, Show
class NoteViewTestCase(tests.BaseMixin, APITransactionTestCase):
reset_sequences = True
show_beatbetrieb: Show
schedule_beatbetrieb: Schedule
show_musikrotation: Show
schedule_musikrotation: Schedule
def setUp(self) -> None:
super().setUp()
self.show_beatbetrieb = self._create_show("Beatbetrieb")
self.schedule_beatbetrieb = self._create_schedule(self.show_beatbetrieb)
self.show_musikrotation = self._create_show("Musikrotation", owners=[self.user_common])
self.schedule_musikrotation = self._create_schedule(
self.show_musikrotation, start_time="10:00", end_time="12:00"
)
def test_everyone_can_read_notes(self):
self._create_note(self._create_timeslot(schedule=self.schedule_beatbetrieb))
self._create_note(self._create_timeslot(schedule=self.schedule_musikrotation))
res = self._get_client().get(self._url("notes"))
self.assertEqual(len(res.data), 2)
def test_common_users_can_create_notes_for_owned_shows(self):
ts = self._create_timeslot(schedule=self.schedule_musikrotation)
client = self._get_client(self.user_common)
endpoint = self._url("notes")
res = client.post(
endpoint, self._create_random_note_content(timeslot=ts.id), format="json"
)
self.assertEqual(res.status_code, 201)
def test_common_users_cannot_create_notes_for_foreign_shows(self):
ts = self._create_timeslot(schedule=self.schedule_beatbetrieb)
client = self._get_client(self.user_common)
endpoint = self._url("notes")
res = client.post(
endpoint, self._create_random_note_content(timeslot=ts.id), format="json"
)
self.assertEqual(res.status_code, 404)
def test_common_user_can_update_owned_shows(self):
ts = self._create_timeslot(schedule=self.schedule_musikrotation)
note = self._create_note(ts)
client = self._get_client(self.user_common)
new_note_content = self._create_random_note_content(title="meh")
res = client.put(self._url("notes", note.id), new_note_content, format="json")
self.assertEqual(res.status_code, 200)
def test_common_user_cannot_update_notes_of_foreign_shows(self):
ts = self._create_timeslot(schedule=self.schedule_beatbetrieb)
note = self._create_note(ts)
client = self._get_client(self.user_common)
new_note_content = self._create_random_note_content(title="meh")
res = client.put(self._url("notes", note.id), new_note_content, format="json")
self.assertEqual(res.status_code, 404)
def test_admin_can_create_notes_for_all_timeslots(self):
timeslot = self._create_timeslot(schedule=self.schedule_musikrotation)
client = self._get_client(self.user_admin)
res = client.post(
self._url("notes"),
self._create_random_note_content(timeslot=timeslot.id),
format="json",
)
self.assertEqual(res.status_code, 201)
def test_notes_can_be_created_through_nested_routes(self):
client = self._get_client(self.user_admin)
# /shows/{pk}/notes/
ts1 = self._create_timeslot(schedule=self.schedule_musikrotation)
url = self._url("shows", self.show_musikrotation.id, "notes")
note = self._create_random_note_content(title="meh", timeslot=ts1.id)
res = client.post(url, note, format="json")
self.assertEqual(res.status_code, 201)
# /shows/{pk}/timeslots/{pk}/note/
ts2 = self._create_timeslot(schedule=self.schedule_musikrotation)
url = self._url("shows", self.show_musikrotation, "timeslots", ts2.id, "note")
note = self._create_random_note_content(title="cool")
res = client.post(url, note, format="json")
self.assertEqual(res.status_code, 201)
def test_notes_can_be_filtered_through_nested_routes_and_query_params(self):
client = self._get_client()
ts1 = self._create_timeslot(schedule=self.schedule_musikrotation)
ts2 = self._create_timeslot(schedule=self.schedule_beatbetrieb)
ts3 = self._create_timeslot(schedule=self.schedule_beatbetrieb)
n1 = self._create_note(timeslot=ts1)
n2 = self._create_note(timeslot=ts2)
n3 = self._create_note(timeslot=ts3)
def _get_ids(res):
return set(ts["id"] for ts in res.data)
# /shows/{pk}/notes/
query_res = client.get(self._url("notes") + f"?show={self.show_beatbetrieb.id}")
route_res = client.get(self._url("shows", self.show_beatbetrieb.id, "notes"))
ids = {n2.id, n3.id}
self.assertEqual(_get_ids(query_res), ids)
self.assertEqual(_get_ids(route_res), ids)
query_res = client.get(self._url("notes") + f"?show={self.show_musikrotation.id}")
route_res = client.get(self._url("shows", self.show_musikrotation.id, "notes"))
ids = {n1.id}
self.assertEqual(_get_ids(query_res), ids)
self.assertEqual(_get_ids(route_res), ids)
# /shows/{pk}/timeslots/{pk}/note/
query_res = client.get(self._url("notes") + f"?timeslot={ts2.id}")
route_res = client.get(
self._url("shows", self.show_beatbetrieb.id, "timeslots", ts2.id, "note")
)
ids = {n2.id}
self.assertEqual(_get_ids(query_res), ids)
self.assertEqual(_get_ids(route_res), ids)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment