diff --git a/requirements.txt b/requirements.txt
index 44816cb..cf50894 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,3 +1,3 @@
-e git+https://github.com/OpenDataServices/flatten-tool.git@v0.5.0#egg=flattentool
--e git+https://github.com/OpenDataServices/lib-cove.git@e1a6132fecdc2000ed03d82da9c2cc4dae3bd442#egg=libcove
+-e git+https://github.com/OpenDataServices/lib-cove.git@fe0ec370280e2986e6d47dff458a08313acceaef#egg=libcove
-e .
diff --git a/requirements_dev.txt b/requirements_dev.txt
index 827c65e..213e078 100644
--- a/requirements_dev.txt
+++ b/requirements_dev.txt
@@ -1,5 +1,5 @@
-e git+https://github.com/OpenDataServices/flatten-tool.git@v0.5.0#egg=flattentool
--e git+https://github.com/OpenDataServices/lib-cove.git@e1a6132fecdc2000ed03d82da9c2cc4dae3bd442#egg=libcove
+-e git+https://github.com/OpenDataServices/lib-cove.git@fe0ec370280e2986e6d47dff458a08313acceaef#egg=libcove
-e .
pytest
flake8
diff --git a/tests/test_api.py b/tests/test_api.py
index 1da6aaa..6c33b9a 100644
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -4,6 +4,42 @@
from libcovebods.api import bods_json_output
+BADFILE_RESULTS = [
+ ({'message': "'entityType' is missing but required. Check that the field is included and correctly spelled.", 'message_safe': 'entityType
is missing but required. Check that the field is included and correctly spelled.', 'message_type': 'required', 'path_no_number': ''}, [{'path': '21'}]), # noqa
+ ({'message': "'exact' should be a number. Check that the value is not null, and doesn’t contain any characters other than 0-9 and dot ('.'). Number values should not be in quotes. ", 'message_safe': 'exact
should be a number. Check that the value is not null, and doesn’t contain any characters other than 0-9 and dot (.
). Number values should not be in quotes. ', 'message_type': 'number', 'path_no_number': 'interests/share/exact'}, [{'path': '16/interests/0/share/exact', 'value': 'not a number'}]), # noqa
+ ({'message': "'exclusiveMinimum' should be a JSON boolean, 'true' or 'false'.", 'message_safe': 'exclusiveMinimum
should be a JSON boolean, true
or false
.', 'message_type': 'boolean', 'path_no_number': 'interests/share/exclusiveMinimum'}, [{'path': '19/interests/0/share/exclusiveMinimum', 'value': 'not a bool'}]), # noqa
+ ({'message': "'interestedParty' is missing but required. Check that the field is included and correctly spelled.", 'message_safe': 'interestedParty
is missing but required. Check that the field is included and correctly spelled.', 'message_type': 'required', 'path_no_number': ''}, [{'path': '16'}, {'path': '17'}, {'path': '18'}, {'path': '19'}, {'path': '20'}]), # noqa
+ ({'message': "'interests' should be a JSON array. Check that value(s) appear within square brackets, [...]", 'message_safe': 'interests
should be a JSON array. Check that value(s) appear within square brackets, [...]', 'message_type': 'array', 'path_no_number': 'interests'}, [{'path': '17/interests'}]), # noqa
+ ({'message': "'interests/0' should be a JSON object", 'message_safe': 'interests/0
should be a JSON object', 'message_type': 'object', 'path_no_number': 'interests'}, [{'path': '18/interests/0', 'value': 'not an object'}]), # noqa
+ ({'message': "'missingPersonType' is a dependency of 'missingPersonReason'", 'message_safe': ''missingPersonType' is a dependency of 'missingPersonReason'', 'message_type': 'dependencies', 'path_no_number': ''}, [{'path': '14'}]), # noqa
+ ({'message': "'motivation' contains an unrecognised value. Check the related codelist for allowed code values.", 'message_safe': 'motivation
contains an unrecognised value. Check the related codelist for allowed code values.', 'message_type': 'enum', 'path_no_number': 'annotations/motivation'}, [{'path': '20/annotations/0/motivation', 'value': 'not on open list'}]), # noqa
+ ({'message': "'not a date' does not match '^([\\\\+-]?\\\\d{4}(?!\\\\d{2}\\x08))((-?)((0[1-9]|1[0-2])(\\\\3([12]\\\\d|0[1-9]|3[01]))?|W([0-4]\\\\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\\\\d|[12]\\\\d{2}|3([0-5]\\\\d|6[1-6])))([T\\\\s]((([01]\\\\d|2[0-3])((:?)[0-5]\\\\d)?|24\\\\:?00)([\\\\.,]\\\\d+(?!:))?)?(\\\\17[0-5]\\\\d([\\\\.,]\\\\d+)?)?([zZ]|([\\\\+-])([01]\\\\d|2[0-3]):?([0-5]\\\\d)?)?)?)?$'", 'message_safe': 'birthDate
does not match the regex ^([\\+-]?\\d{4}(?!\\d{2}\x08))((-?)((0[1-9]|1[0-2])(\\3([12]\\d|0[1-9]|3[01]))?|W([0-4]\\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\\d|[12]\\d{2}|3([0-5]\\d|6[1-6])))([T\\s]((([01]\\d|2[0-3])((:?)[0-5]\\d)?|24\\:?00)([\\.,]\\d+(?!:))?)?(\\17[0-5]\\d([\\.,]\\d+)?)?([zZ]|([\\+-])([01]\\d|2[0-3]):?([0-5]\\d)?)?)?)?$
', 'message_type': 'pattern', 'path_no_number': 'birthDate'}, [{'path': '12/birthDate', 'value': 'not a date'}]), # noqa
+ ({'message': "'personType' contains an unrecognised value. Check the related codelist for allowed code values.", 'message_safe': 'personType
contains an unrecognised value. Check the related codelist for allowed code values.', 'message_type': 'enum', 'path_no_number': 'personType'}, [{'path': '11/personType', 'value': 'bad person type'}]), # noqa
+ ({'message': "'replacesStatements' should be a JSON array. Check that value(s) appear within square brackets, [...]", 'message_safe': 'replacesStatements
should be a JSON array. Check that value(s) appear within square brackets, [...]', 'message_type': 'array', 'path_no_number': 'replacesStatements'}, [{'path': '9/replacesStatements', 'value': 'not an array'}]), # noqa
+ ({'message': "'statementID' is missing but required. Check that the field is included and correctly spelled.", 'message_safe': 'statementID
is missing but required. Check that the field is included and correctly spelled.', 'message_type': 'required', 'path_no_number': ''}, [{'path': '2'}, {'path': '7'}, {'path': '8'}, {'path': '9'}, {'path': '10'}]), # noqa
+ ({'message': "'statementID' should be a string. Check that the value is not null, and has quotes at the start and end. Escape any quotes in the value with '\\'", 'message_safe': 'statementID
should be a string. Check that the value is not null, and has quotes at the start and end. Escape any quotes in the value with \\
', 'message_type': 'string', 'path_no_number': 'statementID'}, [{'path': '4/statementID', 'value': 100}]), # noqa
+ ({'message': "'statementType' contains an unrecognised value. Check the related codelist for allowed code values.", 'message_safe': 'statementType
contains an unrecognised value. Check the related codelist for allowed code values.', 'message_type': 'enum', 'path_no_number': 'statementType'}, [{'path': '1/statementType', 'value': 'bad statement type'}, {'path': '3/statementType'}]), # noqa
+ ({'message': "'statementType' is missing but required. Check that the field is included and correctly spelled.", 'message_safe': 'statementType
is missing but required. Check that the field is included and correctly spelled.', 'message_type': 'required', 'path_no_number': ''}, [{'path': '0'}]), # noqa
+ ({'message': "'subject' is missing but required. Check that the field is included and correctly spelled.", 'message_safe': 'subject
is missing but required. Check that the field is included and correctly spelled.', 'message_type': 'required', 'path_no_number': ''}, [{'path': '16'}, {'path': '17'}, {'path': '18'}, {'path': '19'}, {'path': '20'}]), # noqa
+ ({'message': "'too long long long long long long long long long long long long long long long long' is too long", 'message_safe': 'replacesStatements/0
is too long. It should not exceed 64 characters.', 'message_type': 'maxLength', 'path_no_number': 'replacesStatements'}, [{'path': '8/replacesStatements/0', 'value': 'too long long long long long long long long long long long long long long long long'}]), # noqa
+ ({'message': "'tooshort' is too short", 'message_safe': 'replacesStatements/0
is too short. It should be at least 32 characters.', 'message_type': 'minLength', 'path_no_number': 'replacesStatements'}, [{'path': '7/replacesStatements/0', 'value': 'tooshort'}]), # noqa
+ ({'message': "'tooshort' is too short", 'message_safe': 'statementID
is too short. It should be at least 32 characters.', 'message_type': 'minLength', 'path_no_number': 'statementID'}, [{'path': '5/statementID', 'value': 'tooshort'}]), # noqa
+ ({'message': '-1 is less than the minimum of 0', 'message_safe': 'minimum
is too small. The minimum allowed value is 0.', 'message_type': 'minimum', 'path_no_number': 'interests/share/minimum'}, [{'path': '16/interests/0/share/minimum', 'value': -1}]), # noqa
+ ({'message': '101 is greater than the maximum of 100', 'message_safe': 'maximum
is too large. The maximum allowed value is 100.', 'message_type': 'maximum', 'path_no_number': 'interests/share/maximum'}, [{'path': '16/interests/0/share/maximum', 'value': 101}]), # noqa
+ ({'message': 'Date is not in the correct format. The correct format is YYYY-MM-DD.', 'message_safe': 'Date is not in the correct format. The correct format is YYYY-MM-DD.', 'message_type': 'date', 'path_no_number': 'statementDate'}, [{'path': '10/statementDate', 'value': 'not a date'}]), # noqa
+ ({'message': 'Date is not in the correct format. The correct format is YYYY-MM-DDThh:mm:ssZ.', 'message_safe': 'Date is not in the correct format. The correct format is YYYY-MM-DDT00:00:00Z.', 'message_type': 'date-time', 'path_no_number': 'source/retrievedAt'}, [{'path': '13/source/retrievedAt', 'value': 'not a date-time'}]), # noqa
+ ({'message': 'Invalid uri found', 'message_safe': 'Invalid uri found', 'message_type': 'uri', 'path_no_number': 'uri'}, [{'path': '21/uri', 'value': 'not a uri'}]), # noqa
+ ({'message': "{'motivation': 'not on open list'} is not valid under any of the given schemas", 'message_safe': '{'motivation': 'not on open list'} is not valid under any of the given schemas', 'message_type': 'anyOf', 'path_no_number': 'annotations'}, [{'path': '20/annotations/0'}]), # noqa
+ ({'message': '{} is not valid under any of the given schemas', 'message_safe': '{} is not valid under any of the given schemas', 'message_type': 'anyOf', 'path_no_number': 'identifiers'}, [{'path': '15/identifiers/0'}]), # noqa
+]
+
+
+def unpack_validation_error(validation_error_result):
+ validation_error, data = validation_error_result
+ validation_error_data = json.loads(validation_error)
+ return validation_error_data, data
+
+
def test_basic_1():
cove_temp_folder = tempfile.mkdtemp(prefix='lib-cove-bods-tests-', dir=tempfile.gettempdir())
@@ -153,11 +189,6 @@ def test_basic_statement_id_and_type_errors():
assert results['statistics']['count_ownership_or_control_statement_interested_party_with_person'] == 1
assert results['statistics']['count_ownership_or_control_statement_interested_party_with_entity'] == 0
- def unpack_validation_error(validation_error_result):
- validation_error, data = validation_error_result
- validation_error_data = json.loads(validation_error)
- return validation_error_data, data
-
validation_error_data, data = unpack_validation_error(results['validation_errors'][0])
assert "'shortID' is too short" in validation_error_data['message']
assert data[0]['path'] == '1/statementID'
@@ -168,12 +199,12 @@ def unpack_validation_error(validation_error_result):
assert data[0]['path'] == '0'
assert data[1]['path'] == '2'
- validation_error_data, data = unpack_validation_error(results['validation_errors'][2])
+ validation_error_data, data = unpack_validation_error(results['validation_errors'][3])
assert "'statementType' is missing but required" in validation_error_data['message']
assert data[0]['path'] == '3'
- validation_error_data, data = unpack_validation_error(results['validation_errors'][3])
- assert "Invalid code found in 'statementType'" in validation_error_data['message']
+ validation_error_data, data = unpack_validation_error(results['validation_errors'][2])
+ assert "'statementType' contains an unrecognised value. Check the related codelist for allowed code values." in validation_error_data['message'] # noqa
assert data[0]['path'] == '4/statementType'
assert data[0]['value'] == 'test'
@@ -374,3 +405,28 @@ def test_basic_bad_identifier_scheme():
assert results['additional_checks'][0]['type'] == 'entity_identifier_scheme_not_known'
assert results['additional_checks'][0]['scheme'] == 'GB-COH-THIS-SCHEME-IS-NOT-REAL-I-JUST-MADE-IT-UP-MWAHAHAHAHA'
assert results['additional_checks'][0]['entity_statement'] == '1dc0e987-5c57-4a1c-b3ad-61353b66a9b7'
+
+
+def test_badfile_all_validation_errors():
+
+ cove_temp_folder = tempfile.mkdtemp(prefix='lib-cove-bods-tests-', dir=tempfile.gettempdir())
+ json_filename = os.path.join(os.path.dirname(
+ os.path.realpath(__file__)), 'fixtures', 'api', 'badfile_all_validation_errors.json'
+ )
+
+ results = bods_json_output(cove_temp_folder, json_filename)
+
+ assert results['validation_errors_count'] == 39
+ assert results['additional_fields_count'] == 1
+ assert results['additional_checks_count'] == 9
+ assert results['file_type'] == 'json'
+
+ for (i, (expected_error, expected_values)) in enumerate(BADFILE_RESULTS):
+ error, values = unpack_validation_error(results['validation_errors'][i])
+ assert error['message'] == expected_error['message']
+ assert error['message_safe'] == expected_error['message_safe']
+ assert error['message_type'] == expected_error['message_type']
+ assert error['path_no_number'] == expected_error['path_no_number']
+
+ for j, value in enumerate(expected_values):
+ assert value['path'] == expected_values[j]['path']