diff --git a/src/cpr_data_access/models/search.py b/src/cpr_data_access/models/search.py index b0002caa..1d764683 100644 --- a/src/cpr_data_access/models/search.py +++ b/src/cpr_data_access/models/search.py @@ -1,4 +1,5 @@ from datetime import datetime +import re from typing import List, Mapping, Optional, Sequence, Union from pydantic import BaseModel, field_validator @@ -19,6 +20,9 @@ "source": "family_source", } +_ID_ELEMENT = r"[a-zA-Z0-9]+([-_]?[a-zA-Z0-9]+)*" +ID_PATTERN = re.compile(rf"{_ID_ELEMENT}\.{_ID_ELEMENT}\.{_ID_ELEMENT}\.{_ID_ELEMENT}") + class SearchParameters(BaseModel): """Parameters for a search request""" @@ -58,9 +62,9 @@ def ids_must_fit_pattern(cls, ids): CCLW.family.10014.0 """ if ids: - for i in ids: - if len(i.split(".")) != 4: - raise QueryError(f"id does not seem valid: {i}") + for _id in ids: + if not re.fullmatch(ID_PATTERN, _id): + raise QueryError(f"id seems invalid: {_id}") return ids @field_validator("year_range") diff --git a/tests/test_search_requests.py b/tests/test_search_requests.py index 85b49daf..5f3aa20b 100644 --- a/tests/test_search_requests.py +++ b/tests/test_search_requests.py @@ -59,13 +59,25 @@ def test_whether_valid_family_ids_are_accepted(): assert isinstance(params, SearchParameters) -def test_whether_an_invalid_family_id_raises_a_queryerror(): +@pytest.mark.parametrize( + "bad_id", + [ + "invalid_fam_id", + "Not.Quite.It", + "CCLW.family.i00000003.!!!!!!", + "UNFCCC.family.i00000003", + "UNFCCC.family.i00000003.n000.11", + ], +) +def test_whether_an_invalid_family_id_raises_a_queryerror(bad_id): with pytest.raises(QueryError) as excinfo: SearchParameters( query_string="test", - family_ids=("CCLW.family.i00000003.n0000", "invalid_fam_id"), + family_ids=("CCLW.family.i00000003.n0000", bad_id), ) - assert "id does not seem valid: invalid_fam_id" in str(excinfo.value) + assert f"id seems invalid: {bad_id}" in str( + excinfo.value + ), f"expected failure on {bad_id}" def test_whether_valid_document_ids_are_accepted(): @@ -76,13 +88,24 @@ def test_whether_valid_document_ids_are_accepted(): assert isinstance(params, SearchParameters) -def test_whether_an_invalid_document_id_raises_a_queryerror(): +@pytest.mark.parametrize( + "bad_id", + [ + "invalid_fam_id", + "Not.Quite.It", + "CCLW.doc.i00000003.!!!!!!", + "UNFCCC.doc.i00000003", + ], +) +def test_whether_an_invalid_document_id_raises_a_queryerror(bad_id): with pytest.raises(QueryError) as excinfo: SearchParameters( query_string="test", - document_ids=("invalid_doc_id", "CCLW.document.i00000004.n0000"), + document_ids=(bad_id, "CCLW.document.i00000004.n0000"), ) - assert "id does not seem valid: invalid_doc_id" in str(excinfo.value) + assert f"id seems invalid: {bad_id}" in str( + excinfo.value + ), f"expected failure on {bad_id}" @pytest.mark.parametrize("field", ["date", "name"])