Add tests for search page
This commit is contained in:
parent
edbedcd0fa
commit
6403aca2a2
3 changed files with 142 additions and 5 deletions
8
website/search/factories.py
Normal file
8
website/search/factories.py
Normal file
|
@ -0,0 +1,8 @@
|
|||
from website.common.factories import BaseContentFactory
|
||||
|
||||
from .models import SearchPage
|
||||
|
||||
|
||||
class SearchPageFactory(BaseContentFactory):
|
||||
class Meta:
|
||||
model = SearchPage
|
|
@ -1,7 +1,7 @@
|
|||
from django.core.paginator import EmptyPage, Paginator
|
||||
from django.http.request import HttpRequest
|
||||
from django.http.response import HttpResponse, HttpResponseBadRequest
|
||||
from django.shortcuts import render
|
||||
from django.http.response import Http404, HttpResponse, HttpResponseBadRequest
|
||||
from django.template.response import TemplateResponse
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.utils.functional import cached_property
|
||||
from django.views.decorators.http import require_GET
|
||||
|
@ -46,7 +46,7 @@ class SearchPage(RoutablePageMixin, BaseContentPage):
|
|||
serializer = SearchParamsSerializer(data=request.GET)
|
||||
|
||||
if not serializer.is_valid():
|
||||
return render(
|
||||
return TemplateResponse(
|
||||
request,
|
||||
"search/enter-search-term.html",
|
||||
{"MIN_SEARCH_LENGTH": MIN_SEARCH_LENGTH},
|
||||
|
@ -82,8 +82,8 @@ class SearchPage(RoutablePageMixin, BaseContentPage):
|
|||
)
|
||||
|
||||
except EmptyPage:
|
||||
results = []
|
||||
raise Http404
|
||||
|
||||
context["results"] = results
|
||||
|
||||
return render(request, "search/search_results.html", context)
|
||||
return TemplateResponse(request, "search/search_results.html", context)
|
||||
|
|
129
website/search/tests.py
Normal file
129
website/search/tests.py
Normal file
|
@ -0,0 +1,129 @@
|
|||
from bs4 import BeautifulSoup
|
||||
from django.test import TestCase
|
||||
|
||||
from website.common.factories import ContentPageFactory
|
||||
from website.home.models import HomePage
|
||||
|
||||
from .factories import SearchPageFactory
|
||||
from .models import SearchPage
|
||||
|
||||
|
||||
class SearchPageTestCase(TestCase):
|
||||
@classmethod
|
||||
def setUpTestData(cls) -> None:
|
||||
cls.home_page = HomePage.objects.get()
|
||||
cls.page = SearchPageFactory(parent=cls.home_page)
|
||||
|
||||
def test_accessible(self) -> None:
|
||||
response = self.client.get(self.page.url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.context["search_url"], "results/")
|
||||
self.assertEqual(response.context["MIN_SEARCH_LENGTH"], 3)
|
||||
|
||||
def test_initial_query(self) -> None:
|
||||
response = self.client.get(self.page.url, {"q": "post 1"})
|
||||
self.assertEqual(response.context["search_query"], "post 1")
|
||||
self.assertTemplateNotUsed(response, "search/enter-search-term.html")
|
||||
|
||||
search_input = BeautifulSoup(response.content, "lxml").find("input")
|
||||
self.assertEqual(search_input.attrs["value"], "post 1")
|
||||
|
||||
def test_search_input(self) -> None:
|
||||
response = self.client.get(self.page.url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
soup = BeautifulSoup(response.content, "lxml")
|
||||
search_input = soup.find("input")
|
||||
|
||||
self.assertEqual(search_input.attrs["name"], "q")
|
||||
self.assertEqual(search_input.attrs["hx-get"], "results/")
|
||||
self.assertEqual(search_input.attrs["value"], "")
|
||||
|
||||
self.assertEqual(len(soup.select(search_input.attrs["hx-target"])), 1)
|
||||
self.assertEqual(len(soup.select(search_input.attrs["hx-indicator"])), 1)
|
||||
|
||||
|
||||
class SearchPageResultsTestCase(TestCase):
|
||||
@classmethod
|
||||
def setUpTestData(cls) -> None:
|
||||
cls.home_page = HomePage.objects.get()
|
||||
cls.page = SearchPageFactory(parent=cls.home_page)
|
||||
|
||||
for i in range(SearchPage.PAGE_SIZE + 1):
|
||||
ContentPageFactory(parent=cls.home_page, title=f"Post {i}")
|
||||
|
||||
cls.url = cls.page.url + cls.page.reverse_subpage("results")
|
||||
|
||||
def test_returns_results(self) -> None:
|
||||
with self.assertNumQueries(11):
|
||||
response = self.client.get(self.url, {"q": "post"}, HTTP_HX_REQUEST="true")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
self.assertEqual(len(response.context["results"]), SearchPage.PAGE_SIZE)
|
||||
self.assertEqual(response.context["paginator"].count, SearchPage.PAGE_SIZE + 1)
|
||||
self.assertEqual(response.context["search_query"], "post")
|
||||
self.assertEqual(response.context["page_num"], 1)
|
||||
|
||||
def test_page_trigger(self) -> None:
|
||||
response = self.client.get(self.url, {"q": "post"}, HTTP_HX_REQUEST="true")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
trigger = BeautifulSoup(response.content, "lxml").find(
|
||||
"span", attrs={"hx-trigger": "revealed"}
|
||||
)
|
||||
self.assertEqual(trigger.attrs["hx-swap"], "outerHTML")
|
||||
self.assertEqual(trigger.attrs["hx-get"], "results/?q=post&page=2")
|
||||
|
||||
def test_pagination(self) -> None:
|
||||
response = self.client.get(
|
||||
self.url, {"q": "post", "page": 2}, HTTP_HX_REQUEST="true"
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
self.assertEqual(response.context["page_num"], 2)
|
||||
self.assertEqual(len(response.context["results"]), 1)
|
||||
|
||||
self.assertIsNone(
|
||||
BeautifulSoup(response.content, "lxml").find(
|
||||
"span", attrs={"hx-trigger": "revealed"}
|
||||
)
|
||||
)
|
||||
|
||||
def test_too_high_page(self) -> None:
|
||||
with self.assertNumQueries(46):
|
||||
response = self.client.get(
|
||||
self.url, {"q": "post", "page": 3}, HTTP_HX_REQUEST="true"
|
||||
)
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_returns_result(self) -> None:
|
||||
response = self.client.get(self.url, {"q": "post 1"}, HTTP_HX_REQUEST="true")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
self.assertEqual(len(response.context["results"]), 1)
|
||||
self.assertEqual(list(response.context["results"])[0].title, "Post 1")
|
||||
|
||||
def test_no_results(self) -> None:
|
||||
response = self.client.get(self.url, {"q": "nothing"}, HTTP_HX_REQUEST="true")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
self.assertEqual(len(response.context["results"]), 0)
|
||||
self.assertContains(response, "No results found")
|
||||
|
||||
def test_no_query(self) -> None:
|
||||
with self.assertNumQueries(7):
|
||||
response = self.client.get(self.url, HTTP_HX_REQUEST="true")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
self.assertTemplateUsed(response, "search/enter-search-term.html")
|
||||
|
||||
def test_empty_query(self) -> None:
|
||||
with self.assertNumQueries(7):
|
||||
response = self.client.get(self.url, {"q": ""}, HTTP_HX_REQUEST="true")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
self.assertTemplateUsed(response, "search/enter-search-term.html")
|
||||
|
||||
def test_not_htmx(self) -> None:
|
||||
with self.assertNumQueries(7):
|
||||
response = self.client.get(self.url)
|
||||
self.assertEqual(response.status_code, 400)
|
Loading…
Reference in a new issue