diff --git a/.gitignore b/.gitignore index 9a54ec5a8..f2a3b94bd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,6 @@ -*/__pycache__/** +# Python +__pycache__/ +*.py[cod] + +# IDE .idea/ diff --git a/pms/forms.py b/pms/forms.py index f1bc68d08..b99cdbb8c 100644 --- a/pms/forms.py +++ b/pms/forms.py @@ -20,6 +20,16 @@ class Meta: } +class RoomFilterForm(forms.Form): + name = forms.CharField( + required=False, + label="Nombre", + widget=forms.TextInput( + attrs={"placeholder": "Nombre de la habitación"} + ), + ) + + class CustomerForm(ModelForm): class Meta: model = Customer diff --git a/pms/templates/rooms.html b/pms/templates/rooms.html index c30929f1f..bd6d0cea2 100644 --- a/pms/templates/rooms.html +++ b/pms/templates/rooms.html @@ -2,6 +2,17 @@ {% block content %}
No se encontraron habitaciones.
{% endfor %} {% endblock content%} diff --git a/pms/tests.py b/pms/tests.py index 7ce503c2d..9b486c5e4 100644 --- a/pms/tests.py +++ b/pms/tests.py @@ -1,3 +1,75 @@ -from django.test import TestCase +from django.test import TestCase, override_settings +from django.urls import reverse -# Create your tests here. +from .models import Room + +@override_settings(STATICFILES_STORAGE="django.contrib.staticfiles.storage.StaticFilesStorage") +class RoomsViewFilterTests(TestCase): + """ + Tests for the room list filter functionality. + + Static files storage is overridden per-class to avoid requiring + collectstatic before running tests. A project-wide test settings + file would be the cleaner long-term solution. + """ + + @classmethod + def setUpTestData(cls): + cls.rooms_url = reverse("rooms") + + cls.matching_room_one = Room.objects.create(name="Room 1.1") + cls.matching_room_two = Room.objects.create(name="Room 1.2") + cls.non_matching_room = Room.objects.create(name="Room 2.1") + + def test_rooms_page_renders_filter_form(self): + response = self.client.get(self.rooms_url) + + self.assertEqual(response.status_code, 200) + self.assertContains(response, 'method="get"', html=False) + self.assertContains(response, 'name="name"', html=False) + + def test_rooms_page_without_name_filter_returns_all_rooms(self): + response = self.client.get(self.rooms_url) + + self.assertEqual(response.status_code, 200) + self.assertContains(response, self.matching_room_one.name) + self.assertContains(response, self.matching_room_two.name) + self.assertContains(response, self.non_matching_room.name) + + def test_rooms_page_filters_rooms_by_partial_name(self): + response = self.client.get(self.rooms_url, {"name": "Room 1"}) + + self.assertEqual(response.status_code, 200) + self.assertContains(response, self.matching_room_one.name) + self.assertContains(response, self.matching_room_two.name) + self.assertNotContains(response, self.non_matching_room.name) + + def test_rooms_page_filters_rooms_case_insensitively(self): + response = self.client.get(self.rooms_url, {"name": "room 1"}) + + self.assertEqual(response.status_code, 200) + self.assertContains(response, self.matching_room_one.name) + self.assertContains(response, self.matching_room_two.name) + self.assertNotContains(response, self.non_matching_room.name) + + def test_rooms_page_with_non_matching_name_returns_no_rooms(self): + response = self.client.get(self.rooms_url, {"name": "Suite"}) + + self.assertEqual(response.status_code, 200) + self.assertNotContains(response, self.matching_room_one.name) + self.assertNotContains(response, self.matching_room_two.name) + self.assertNotContains(response, self.non_matching_room.name) + + def test_rooms_page_ignores_whitespace_only_name_filter(self): + response = self.client.get(self.rooms_url, {"name": " "}) + + self.assertEqual(response.status_code, 200) + self.assertContains(response, self.matching_room_one.name) + self.assertContains(response, self.matching_room_two.name) + self.assertContains(response, self.non_matching_room.name) + + def test_rooms_page_preserves_name_filter_in_form(self): + response = self.client.get(self.rooms_url, {"name": "Room 1"}) + + self.assertEqual(response.status_code, 200) + self.assertEqual(response.context["form"]["name"].value(), "Room 1") diff --git a/pms/views.py b/pms/views.py index f38563933..dd1344ab0 100644 --- a/pms/views.py +++ b/pms/views.py @@ -238,9 +238,18 @@ def get(self, request, pk): class RoomsView(View): def get(self, request): - # renders a list of rooms - rooms = Room.objects.all().values("name", "room_type__name", "id") + form = RoomFilterForm(request.GET or None) + rooms_qs = Room.objects.all().order_by("name", "id") + + if form.is_valid(): + name = (form.cleaned_data.get("name") or "").strip() + if name: + rooms_qs = rooms_qs.filter(name__icontains=name) + + rooms = rooms_qs.values("name", "room_type__name", "id") + context = { - 'rooms': rooms + "rooms": rooms, + "form": form, } return render(request, "rooms.html", context)