Make invalid search input explicit in UI and API
This commit is contained in:
@ -196,3 +196,28 @@ def test_api_combined_filters_respect_same_player_season_context(client):
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert response.json()["count"] == 0
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_players_api_returns_400_for_invalid_numeric_filter(client):
|
||||
response = client.get(reverse("api:players"), data={"points_per_game_min": "abc"})
|
||||
assert response.status_code == 400
|
||||
payload = response.json()
|
||||
assert payload["detail"] == "Invalid search parameters."
|
||||
assert "points_per_game_min" in payload["errors"]
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_players_api_returns_400_for_invalid_choice_filter(client):
|
||||
response = client.get(reverse("api:players"), data={"sort": "not-a-sort"})
|
||||
assert response.status_code == 400
|
||||
payload = response.json()
|
||||
assert "sort" in payload["errors"]
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_players_api_returns_400_for_invalid_range_combination(client):
|
||||
response = client.get(reverse("api:players"), data={"age_min": 30, "age_max": 20})
|
||||
assert response.status_code == 400
|
||||
payload = response.json()
|
||||
assert "age_max" in payload["errors"]
|
||||
|
||||
@ -135,3 +135,61 @@ def test_player_detail_page_loads(client):
|
||||
body = response.content.decode()
|
||||
assert "Paul Martin" in body
|
||||
assert "P. Martin" in body
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_player_search_invalid_numeric_filter_shows_errors_and_no_broad_fallback(client):
|
||||
nationality = Nationality.objects.create(name="Belgium", iso2_code="BE", iso3_code="BEL")
|
||||
position = Position.objects.create(code="PG", name="Point Guard")
|
||||
role = Role.objects.create(code="playmaker", name="Playmaker")
|
||||
Player.objects.create(
|
||||
first_name="Any",
|
||||
last_name="Player",
|
||||
full_name="Any Player",
|
||||
birth_date=date(2000, 1, 1),
|
||||
nationality=nationality,
|
||||
nominal_position=position,
|
||||
inferred_role=role,
|
||||
)
|
||||
|
||||
response = client.get(reverse("players:index"), data={"points_per_game_min": "abc", "q": "Any"})
|
||||
|
||||
assert response.status_code == 200
|
||||
assert list(response.context["players"]) == []
|
||||
assert response.context["search_has_errors"] is True
|
||||
assert "points per game min" in response.content.decode().lower()
|
||||
assert response.context["search_form"]["q"].value() == "Any"
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_player_search_invalid_choice_filter_shows_errors(client):
|
||||
response = client.get(reverse("players:index"), data={"sort": "bad-sort"})
|
||||
assert response.status_code == 200
|
||||
assert list(response.context["players"]) == []
|
||||
assert response.context["search_has_errors"] is True
|
||||
assert "select a valid choice" in response.content.decode().lower()
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_player_search_invalid_range_combination_shows_errors(client):
|
||||
response = client.get(reverse("players:index"), data={"age_min": 30, "age_max": 20})
|
||||
assert response.status_code == 200
|
||||
assert list(response.context["players"]) == []
|
||||
assert response.context["search_has_errors"] is True
|
||||
body = response.content.decode().lower()
|
||||
assert "age max" in body
|
||||
assert "must be >=" in body or "must be >=" in body
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_player_search_htmx_invalid_filters_return_validation_feedback(client):
|
||||
response = client.get(
|
||||
reverse("players:index"),
|
||||
HTTP_HX_REQUEST="true",
|
||||
data={"points_per_game_min": "abc"},
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
body = response.content.decode().lower()
|
||||
assert "search filters are invalid" in body
|
||||
assert "points per game min" in body
|
||||
|
||||
Reference in New Issue
Block a user