Make invalid search input explicit in UI and API

This commit is contained in:
Alfredo Di Stasio
2026-03-10 15:53:55 +01:00
parent 92c804a474
commit 2586f15ae8
6 changed files with 150 additions and 17 deletions

View File

@ -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"]

View File

@ -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