Skip to content

Commit 926122e

Browse files
committed
reservable rooms API
1 parent 588b4f1 commit 926122e

6 files changed

Lines changed: 141 additions & 1 deletion

File tree

reservation/api.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from ninja import Query
2+
from ninja_extra import ControllerBase, api_controller, paginate, route
3+
from ninja_extra.pagination import PageNumberPaginationExtra
4+
from ninja_extra.schemas import PaginatedResponseSchema
5+
6+
from core.auth.api_permissions import HasPerm
7+
from reservation.models import ReservationSlot, Room
8+
from reservation.schemas import (
9+
RoomFilterSchema,
10+
RoomSchema,
11+
SlotFilterSchema,
12+
SlotSchema,
13+
)
14+
15+
16+
@api_controller("/reservation/room")
17+
class ReservableRoomController(ControllerBase):
18+
@route.get(
19+
"",
20+
response=list[RoomSchema],
21+
permissions=[HasPerm("reservation.viem_room")],
22+
url_name="fetch_reservable_rooms",
23+
)
24+
def fetch_rooms(self, filters: Query[RoomFilterSchema]):
25+
return filters.filter(Room.objects.select_related("club"))
26+
27+
28+
@api_controller("/reservation/slot")
29+
class ReservationSlotController(ControllerBase):
30+
@route.get(
31+
"",
32+
response=PaginatedResponseSchema[SlotSchema],
33+
permissions=[HasPerm("reservation.view_reservationslot")],
34+
)
35+
@paginate(PageNumberPaginationExtra)
36+
def fetch_slots(self, filters: Query[SlotFilterSchema]):
37+
return filters.filter(ReservationSlot.objects.select_related("author"))

reservation/schemas.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from datetime import datetime
2+
3+
from ninja import FilterSchema, ModelSchema
4+
from pydantic import Field
5+
6+
from club.schemas import ClubSchema
7+
from core.schemas import SimpleUserSchema
8+
from reservation.models import ReservationSlot, Room
9+
10+
11+
class RoomFilterSchema(FilterSchema):
12+
club: set[int] | None = Field(None, q="club_id__in")
13+
14+
15+
class RoomSchema(ModelSchema):
16+
class Meta:
17+
model = Room
18+
fields = ["id", "name", "description", "address"]
19+
20+
club: ClubSchema
21+
22+
23+
class SlotFilterSchema(FilterSchema):
24+
after: datetime = Field(default=None, q="end_at__gt")
25+
before: datetime = Field(default=None, q="start_at__lt")
26+
room: set[int] | None = None
27+
club: set[int] | None = None
28+
29+
30+
class SlotSchema(ModelSchema):
31+
class Meta:
32+
model = ReservationSlot
33+
fields = ["id", "room", "nb_people", "comment"]
34+
35+
start: datetime = Field(alias="start_at")
36+
end: datetime = Field(alias="end_at")
37+
author: SimpleUserSchema

reservation/tests.py

Lines changed: 0 additions & 1 deletion
This file was deleted.

reservation/tests/__init__.py

Whitespace-only changes.

reservation/tests/test_room_api.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import pytest
2+
from model_bakery import baker
3+
from ninja_extra.testing import TestClient
4+
from pytest_django.asserts import assertNumQueries
5+
6+
from reservation.api import ReservableRoomController
7+
from reservation.models import Room
8+
9+
10+
@pytest.mark.django_db
11+
class TestFetchRoom:
12+
def test_fetch_simple(self):
13+
rooms = baker.make(Room, _quantity=3, _bulk_create=True)
14+
response = TestClient(ReservableRoomController).get("")
15+
assert response.json() == [
16+
{
17+
"id": room.id,
18+
"name": room.name,
19+
"description": room.description,
20+
"address": room.address,
21+
"club": {"id": room.club.id, "name": room.club.name},
22+
}
23+
for room in rooms
24+
]
25+
26+
def test_nb_queries(self):
27+
with assertNumQueries(1):
28+
TestClient(ReservableRoomController).get("")

reservation/tests/test_slot_api.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import pytest
2+
from model_bakery import baker
3+
from ninja_extra.testing import TestClient
4+
from pytest_django.asserts import assertNumQueries
5+
6+
from reservation.api import ReservableRoomController, ReservationSlotController
7+
from reservation.models import ReservationSlot
8+
9+
10+
@pytest.mark.django_db
11+
class TestFetchRoom:
12+
def test_fetch_simple(self):
13+
slots = baker.make(ReservationSlot, _quantity=5, _bulk_create=True)
14+
response = TestClient(ReservationSlotController).get("")
15+
assert response.json() == [
16+
{
17+
"id": slot.id,
18+
"room": slot.room_id,
19+
"comment": slot.comment,
20+
"nb_people": slot.nb_people,
21+
"start": slot.start_at.isoformat(timespec="milliseconds").replace(
22+
"+00:00", "Z"
23+
),
24+
"end": slot.end_at.isoformat(timespec="milliseconds").replace(
25+
"+00:00", "Z"
26+
),
27+
"author": {
28+
"id": slot.author.id,
29+
"first_name": slot.author.first_name,
30+
"last_name": slot.author.last_name,
31+
"nick_name": slot.author.nick_name,
32+
},
33+
}
34+
for slot in slots
35+
]
36+
37+
def test_nb_queries(self):
38+
with assertNumQueries(1):
39+
TestClient(ReservableRoomController).get("")

0 commit comments

Comments
 (0)