59 lines
2.4 KiB
Python
59 lines
2.4 KiB
Python
from tests.support import ApiTestCase
|
|
|
|
|
|
class SearchTests(ApiTestCase):
|
|
def setUp(self):
|
|
super().setUp()
|
|
self.register()
|
|
self.scifi = self.genre_id("Science Fiction")
|
|
self.fantasy = self.genre_id("Fantasy")
|
|
self.create_book(title="Dune", author="Frank Herbert", genre_id=self.scifi)
|
|
self.create_book(
|
|
title="The Hobbit", author="J.R.R. Tolkien", genre_id=self.fantasy
|
|
)
|
|
self.create_book(title="100% Pure", author="Jane_Doe", genre_id=self.fantasy)
|
|
self.create_book(title="1000 Pages", author="Back\\slash", genre_id=self.scifi)
|
|
|
|
def titles(self, query: str) -> list[str]:
|
|
response = self.call("GET", f"/api/books?{query}")
|
|
self.assertEqual(response.status_code, 200, response.get_json())
|
|
return sorted(b["title"] for b in response.get_json())
|
|
|
|
def test_matches_title_or_author_case_insensitively(self):
|
|
self.assertEqual(self.titles("q=dUnE"), ["Dune"])
|
|
self.assertEqual(self.titles("q=tolkien"), ["The Hobbit"])
|
|
|
|
def test_wildcards_match_literally(self):
|
|
self.assertEqual(self.titles("q=100%25"), ["100% Pure"]) # %25 is "%"
|
|
self.assertEqual(self.titles("q=e_D"), ["100% Pure"]) # literal "_" in Jane_Doe
|
|
self.assertEqual(
|
|
self.titles("q=k_s"), []
|
|
) # unescaped "_" would match "Back\\slash"
|
|
self.assertEqual(self.titles("q=k%5Cs"), ["1000 Pages"]) # %5C is "\"
|
|
|
|
def test_genre_filter_and_combination(self):
|
|
self.assertEqual(
|
|
self.titles(f"genre_id={self.fantasy}"), ["100% Pure", "The Hobbit"]
|
|
)
|
|
self.assertEqual(self.titles(f"q=100&genre_id={self.scifi}"), ["1000 Pages"])
|
|
|
|
def test_blank_query_returns_everything(self):
|
|
self.assertEqual(len(self.titles("q=%20%20")), 4)
|
|
|
|
def test_invalid_parameters(self):
|
|
for query, field in (
|
|
("genre_id=abc", "genre_id"),
|
|
("genre_id=99999", "genre_id"),
|
|
("q=a%00b", "q"),
|
|
):
|
|
with self.subTest(query=query):
|
|
response = self.call("GET", f"/api/books?{query}")
|
|
self.assertEqual(response.status_code, 400)
|
|
self.assertEqual(response.get_json()["field"], field)
|
|
|
|
def test_search_never_returns_other_users_books(self):
|
|
bob = self.other_user("bob")
|
|
self.assertEqual(
|
|
self.call("GET", "/api/books?q=dune", client=bob).get_json(), []
|
|
)
|