diff --git a/CHANGELOG.md b/CHANGELOG.md index e0d45a1..b2c25d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - End point county/code/{code}. - End point county/gridref/{gridref}. - id_difficulty to /verify response. -- result to /verify response. This contains a string of ['pass'|'warn'|'fail']. +- result to /verify and /validate response. This contains a string of + ['pass'|'warn'|'fail']. ### Changed - /validate and /verify to raise errors on taxon name/tvk of ''. @@ -28,7 +29,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Removed - id_difficulty from /validate response. -- ok from /verify response +- ok from /verify and /validate response ## [1.0.0] diff --git a/app/validate/validate_models.py b/app/validate/validate_models.py index 9ea5584..270835e 100644 --- a/app/validate/validate_models.py +++ b/app/validate/validate_models.py @@ -15,5 +15,5 @@ class Validate(BaseModel): class Validated(Validate): preferred_tvk: Optional[str] = None - ok: bool = True + result: str = 'pass' messages: Optional[List[str]] = [] diff --git a/app/validate/validate_routes.py b/app/validate/validate_routes.py index 245b696..0c5339a 100644 --- a/app/validate/validate_routes.py +++ b/app/validate/validate_routes.py @@ -46,71 +46,73 @@ async def validate( results = [] for record in records: # Our response begins with the input data. - result = Validated(**record.model_dump()) + validated = Validated(**record.model_dump()) # As we are validating, try to return as many errors as we can find # to save human time. try: # 1. Confirm TVK/name is valid. if not record.tvk and not record.name: - result.ok = False - result.messages.append("TVK or name required.") + validated.result = 'fail' + validated.messages.append("TVK or name required.") else: if record.tvk: # Use TVK if provided as not ambiguous. taxon = cache.get_taxon_by_tvk(db, env, record.tvk) if not record.name: - result.name = taxon.name + validated.name = taxon.name elif record.name != taxon.name: - result.ok = False - result.messages.append( + validated.result = 'fail' + validated.messages.append( f"Name does not match TVK. Expected {taxon.name}.") else: # Otherwise use name. taxon = cache.get_taxon_by_name(db, env, record.name) - result.tvk = taxon.tvk + validated.tvk = taxon.tvk - result.preferred_tvk = taxon.preferred_tvk + validated.preferred_tvk = taxon.preferred_tvk except Exception as e: - result.ok = False - result.messages.append(str(e)) + validated.result = 'fail' + validated.messages.append(str(e)) try: # 2. Confirm date is valid. vague_date = VagueDate(record.date) # Return date in preferred format. - result.date = str(vague_date) + validated.date = str(vague_date) except Exception as e: - result.ok = False - result.messages.append(str(e)) + validated.result = 'fail' + validated.messages.append(str(e)) try: # 3. Confirm sref is valid. sref = SrefFactory(record.sref) - # Include gridref in result. - result.sref.gridref = sref.gridref + # Include gridref in validated. + validated.sref.gridref = sref.gridref # 4a. Either check vice county... if record.vc is not None: code = VcChecker.prepare_code(record.vc) # Return code if name was supplied. - result.vc = code + validated.vc = code gridref = VcChecker.prepare_sref(sref.gridref) VcChecker.check(gridref, code) # 4b. Or assign vice county. else: gridref = VcChecker.prepare_sref(sref.gridref) - result.vc = VcChecker.get_code_from_sref(gridref) + validated.vc = VcChecker.get_code_from_sref(gridref) except NoVcException as e: - # Failure to assign is not an error. - result.vc = '0' - result.messages.append(str(e)) + # Failure to assign is a warning but must not override a fail. + validated.vc = None + if validated.result == 'pass': + validated.result = 'warn' + validated.messages.append(str(e)) except Exception as e: - result.ok = False - result.messages.append(str(e)) + validated.result = 'fail' + validated.messages.append(str(e)) - results.append(result) + results.append(validated) return results diff --git a/test/validate/test_validate.py b/test/validate/test_validate.py index 7e7d26c..4c0cfd8 100644 --- a/test/validate/test_validate.py +++ b/test/validate/test_validate.py @@ -59,7 +59,7 @@ def test_syntactically_valid_record(self, client: TestClient, mocker): ) assert response.status_code == 200 validated = response.json()[0] - assert not validated['ok'] + assert validated['result'] == 'fail' assert validated['messages'][0] == "TVK or name required." assert validated['messages'][1] == "Unrecognised date format." assert validated['messages'][2] == "Invalid spatial reference. A gridref must be provided." @@ -89,7 +89,7 @@ def test_valid_record_accepted_tvk(self, client: TestClient, mocker): assert validated['date'] == "03/04/2024" assert validated['sref']['gridref'] == "TL123456" assert validated['preferred_tvk'] == "NBNSYS0000008319" - assert validated['ok'] + assert validated['result'] == 'pass' assert len(validated['messages']) == 0 def test_valid_record_common_tvk(self, client: TestClient, mocker): @@ -117,7 +117,7 @@ def test_valid_record_common_tvk(self, client: TestClient, mocker): assert validated['date'] == "03/04/2024" assert validated['sref']['gridref'] == "TL123456" assert validated['preferred_tvk'] == "NBNSYS0000008319" - assert validated['ok'] + assert validated['result'] == 'pass' assert len(validated['messages']) == 0 def test_valid_record_accepted_name(self, client: TestClient, mocker): @@ -144,7 +144,7 @@ def test_valid_record_accepted_name(self, client: TestClient, mocker): assert validated['date'] == "03/04/2024" assert validated['sref']['gridref'] == "TL123456" assert validated['preferred_tvk'] == "NBNSYS0000008319" - assert validated['ok'] + assert validated['result'] == 'pass' assert len(validated['messages']) == 0 def test_valid_record_common_name(self, client: TestClient, mocker): @@ -171,7 +171,7 @@ def test_valid_record_common_name(self, client: TestClient, mocker): assert validated['date'] == "03/04/2024" assert validated['sref']['gridref'] == "TL123456" assert validated['preferred_tvk'] == "NBNSYS0000008319" - assert validated['ok'] + assert validated['result'] == 'pass' assert len(validated['messages']) == 0 def test_invalid_vc(self, client: TestClient, mocker): @@ -200,7 +200,8 @@ def test_invalid_vc(self, client: TestClient, mocker): assert validated['date'] == "03/04/2024" assert validated['sref']['gridref'] == "TL123456" assert validated['vc'] == "1" - assert not validated['ok'] + assert validated['result'] == 'fail' + assert len(validated['messages']) == 1 assert validated['messages'][0] == "Sref not in vice county." def test_valid_vc(self, client: TestClient, mocker): @@ -229,7 +230,7 @@ def test_valid_vc(self, client: TestClient, mocker): assert validated['date'] == "03/04/2024" assert validated['sref']['gridref'] == "TL123456" assert validated['vc'] == "30" - assert validated['ok'] + assert validated['result'] == 'pass' assert len(validated['messages']) == 0 def test_vc_assignment(self, client: TestClient, mocker): @@ -257,7 +258,7 @@ def test_vc_assignment(self, client: TestClient, mocker): assert validated['date'] == "03/04/2024" assert validated['sref']['gridref'] == "TL123456" assert validated['vc'] == "30" - assert validated['ok'] + assert validated['result'] == 'pass' assert len(validated['messages']) == 0 def test_vc_no_assignment(self, client: TestClient, mocker): @@ -284,7 +285,7 @@ def test_vc_no_assignment(self, client: TestClient, mocker): assert validated['name'] == "Adalia bipunctata" assert validated['date'] == "03/04/2024" assert validated['sref']['gridref'] == "TM999999" - assert validated['vc'] == '0' - assert validated['ok'] + assert 'vc' not in validated + assert validated['result'] == 'warn' assert len(validated['messages']) == 1 assert validated['messages'][0] == "No vice county found for gridref."