def check(schema, required_fields, data, errors): api_errors = get_validation_errors(schema_name, data, enforce_required=False, required_fields=required_fields) assert api_errors == errors
def test_brief_response_essential_requirements(): for schema_name in ("brief-responses-digital-outcomes-and-specialists-digital-specialists", "brief-responses-digital-outcomes-and-specialists-2-digital-specialists"): assert get_validation_errors( schema_name, { "availability": "valid start date", "dayRate": "100", "essentialRequirementsMet": True, "essentialRequirements": [ {"evidence": "valid evidence"}, {"evidence": "word " * 100}, {"evidence": "some more valid evidence"}, {} ], "niceToHaveRequirements": [ {"yesNo": False} ], "respondToEmailAddress": "*****@*****.**" } ) == { 'essentialRequirements': [ { 'error': 'under_100_words', 'field': u'evidence', 'index': 1 }, { 'error': 'answer_required', 'field': u'evidence', 'index': 3 }, ] }
def test_too_many_list_items_causes_validation_error(): data = load_example_listing("G7-SCS") data.update({'serviceBenefits': [ '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11' ]}) errs = get_validation_errors("services-g-cloud-7-scs", data) assert "max_items_limit" in errs['serviceBenefits']
def test_additional_properties_has_validation_error(): data = load_example_listing("G7-SCS") data = drop_api_exported_fields_so_that_api_import_will_validate(data) data.update({'newKey': 1}) errs = get_validation_errors("services-g-cloud-7-scs", data) assert "Additional properties are not allowed ('newKey' was unexpected)" \ in "{}".format(errs['_form'])
def test_enforce_required_false_allows_missing_fields(): data = load_example_listing("G7-SCS") data = drop_api_exported_fields_so_that_api_import_will_validate(data) data.pop("serviceSummary", None) data.pop("serviceDefinitionDocumentURL", None) errs = get_validation_errors("services-g-cloud-7-scs", data, enforce_required=False) assert not errs
def test_required_fields_param_requires_specified_fields(): data = load_example_listing("G7-SCS") data.pop("serviceSummary", None) data.pop("serviceDefinitionDocumentURL", None) errs = get_validation_errors("services-g-cloud-7-scs", data, enforce_required=False, required_fields=['serviceSummary']) assert "answer_required" in errs['serviceSummary']
def test_g9_followup_questions(schema_name, required_fields, input_data, expected_errors): assert get_validation_errors( schema_name, input_data, enforce_required=False, required_fields=required_fields, ) == expected_errors
def test_max_price_larger_than_min_price(): cases = ['132.20', ''] for price_max in cases: data = load_example_listing("G7-SCS") data.update({"priceMax": price_max}) errs = get_validation_errors("services-g-cloud-7-scs", data) assert_not_in('priceMax', errs)
def test_dos4_dependent_questions(required_fields, input_data, expected_errors): # specifically dos4 services because they have "dependencies" assert get_validation_errors( "services-digital-outcomes-and-specialists-4-digital-specialists", input_data, enforce_required=False, required_fields=required_fields, ) == expected_errors
def test_assurance_only_causes_validation_error(): data = load_example_listing("G6-PaaS") data.update({ 'serviceAvailabilityPercentage': { "assurance": "Service provider assertion" } }) errs = get_validation_errors("services-g-cloud-7-paas", data) assert "answer_required" in errs['serviceAvailabilityPercentage']
def test_min_price_larger_than_max_price_causes_validation_error(): cases = ['32.20', '9.00'] for price_max in cases: data = load_example_listing("G7-SCS") data.update({"priceMax": price_max}) errs = get_validation_errors("services-g-cloud-7-scs", data) assert_in('max_less_than_min', errs['priceMax'])
def test_non_number_value_causes_validation_error(): data = load_example_listing("G6-PaaS") data.update({ 'serviceAvailabilityPercentage': { "value": "a99.9", "assurance": "Service provider assertion" } }) errs = get_validation_errors("services-g-cloud-7-paas", data) assert "not_a_number" in errs['serviceAvailabilityPercentage']
def test_error_messages(self, schema_name): self.data["niceToHaveRequirements"] = [ {}, { "yesNo": True, "evidence": "valid evidence" }, { "yesNo": True, "evidence": "word " * 100 }, { "yesNo": True }, { "yesNo": False }, { "yesNo": False, "evidence": "shouldnt be here" }, ] assert get_validation_errors( schema_name, self.data )["niceToHaveRequirements"] == [ { 'error': 'answer_required', 'field': 'yesNo', 'index': 0 }, { 'error': 'under_100_words', 'field': 'evidence', 'index': 2 }, { 'error': 'answer_required', 'field': 'evidence', 'index': 3 }, { 'error': ( # python 3.6+ guarantees consistent dict ordering "{'yesNo': False, 'evidence': 'shouldnt be here'} is not valid under any of the given schemas" ), 'index': 5, }, ]
def test_dict_bool_mix(self, schema_name): self.data["niceToHaveRequirements"] = [ { "yesNo": False, "evidence": "shouldnt be here" }, True, { 'yesNo': False }, { "yesNo": False, "evidence": "shouldnt be here" }, ] assert get_validation_errors( schema_name, self.data )["niceToHaveRequirements"] == "True is not of type 'object'"
def test_brief_response_essential_requirements(schema_name): assert get_validation_errors( schema_name, { "availability": "valid start date", "dayRate": "100", "essentialRequirementsMet": True, "essentialRequirements": [ { "evidence": "valid evidence" }, { "evidence": "word " * 100 }, { "evidence": "some more valid evidence" }, {}, ], "niceToHaveRequirements": [ { "yesNo": False }, ], "respondToEmailAddress": "*****@*****.**", }, ) == { 'essentialRequirements': [ { 'error': 'under_100_words', 'field': 'evidence', 'index': 1, }, { 'error': 'answer_required', 'field': 'evidence', 'index': 3, }, ], }
def test_g7_missing_required_field_has_validation_error(): data = load_example_listing("G7-SCS") data.pop("serviceSummary", None) errs = get_validation_errors("services-g-cloud-7-scs", data) assert "answer_required" in errs['serviceSummary']
def test_pure_booleans(self, schema_name): self.data["niceToHaveRequirements"] = [True, True, True] assert get_validation_errors( schema_name, self.data )["niceToHaveRequirements"] == "True is not of type 'object'"
def test_supplier_fails_with_bad_companies_house_number(): data = load_example_listing("supplier_creation") data["companiesHouseNumber"] = "short" errs = get_validation_errors("new-supplier", data) assert len(errs) is 1
def test_string_too_long_causes_validation_error(): data = load_example_listing("G7-SCS") data.update({'serviceName': "a" * 101}) errs = get_validation_errors("services-g-cloud-7-scs", data) assert "under_character_limit" in errs['serviceName']
def test_too_many_words_causes_validation_error(): data = load_example_listing("G7-SCS") data.update({'serviceBenefits': ['more than ten words 5 6 7 8 9 10 11']}) errs = get_validation_errors("services-g-cloud-7-scs", data) assert 'under_word_limit' in errs['serviceBenefits']
def test_invalid_url_field_has_validation_error(): data = load_example_listing("G7-SCS") data.update({'serviceDefinitionDocumentURL': 'not_a_url'}) errs = get_validation_errors("services-g-cloud-7-scs", data) assert errs['serviceDefinitionDocumentURL'] == 'invalid_format'
def test_invalid_enum_values_has_validation_error(): data = load_example_listing("G7-SCS") data.update({'minimumContractPeriod': 'Fortnight'}) errs = get_validation_errors("services-g-cloud-7-scs", data) assert "'Fortnight' is not one of" in errs['minimumContractPeriod']
def test_new_supplier_fails_with_bad_duns(duns): data = load_example_listing("new-supplier") data["dunsNumber"] = duns errs = get_validation_errors("new-supplier", data) assert len(errs) == 1
def check_min_price_valid(field, case): data[field] = case errs = get_validation_errors("services-g-cloud-7-scs", data) assert "not_money_format" not in errs.get(field, "")
def test_brief_response_nice_to_have_requirements(): for schema_name in ( "brief-responses-digital-outcomes-and-specialists-digital-specialists", "brief-responses-digital-outcomes-and-specialists-2-digital-specialists" ): data = { "availability": "valid start date", "dayRate": "100", "essentialRequirementsMet": True, "essentialRequirements": [ { "evidence": "valid evidence" }, ], "respondToEmailAddress": "*****@*****.**" } # Nice-to-have requirements are optional. assert not get_validation_errors(schema_name, data) data["niceToHaveRequirements"] = [{}, { "yesNo": True, "evidence": "valid evidence" }, { "yesNo": True, "evidence": "word " * 100 }, { "yesNo": True }, { "yesNo": False }, { "yesNo": False, "evidence": "shouldnt be here" }] error_messages = get_validation_errors(schema_name, data)["niceToHaveRequirements"] assert error_messages[:3] == [{ 'error': 'answer_required', 'field': u'yesNo', 'index': 0 }, { 'error': 'under_100_words', 'field': u'evidence', 'index': 2 }, { 'error': 'answer_required', 'field': u'evidence', 'index': 3 }] assert error_messages[3]["index"] == 5 # Python 3 dictionary ordering is unpredicatable so we have to cover both possible orders as it is converted to # a string assert error_messages[3]["error"] in [ "{'yesNo': False, 'evidence': 'shouldnt be here'} is not valid under any of the given schemas", "{'evidence': 'shouldnt be here', 'yesNo': False} is not valid under any of the given schemas" ] assert len(error_messages) == 4 # Purely boolean nice to have requirements data["niceToHaveRequirements"] = [True, True, True] error_messages = get_validation_errors(schema_name, data)["niceToHaveRequirements"] assert "True is not of type" in error_messages assert "object" in error_messages # Mix of dict and boolean nice to have requirements data["niceToHaveRequirements"] = [{ "yesNo": False, "evidence": "shouldnt be here" }, True, { 'yesNo': False }, { "yesNo": False, "evidence": "shouldnt be here" }] error_messages = get_validation_errors(schema_name, data)["niceToHaveRequirements"] assert "True is not of type" in error_messages assert "object" in error_messages
def test_valid_g7_service_has_no_validation_errors(): data = load_example_listing("G7-SCS") data = drop_api_exported_fields_so_that_api_import_will_validate(data) errs = get_validation_errors("services-g-cloud-7-scs", data) assert not errs
def test_supplier_validates_with_no_companies_house_number(): data = load_example_listing("supplier_creation") data.pop("companiesHouseNumber", None) errs = get_validation_errors("new-supplier", data) assert len(errs) is 0
def test_nice_to_have_optional(self, schema_name): assert not get_validation_errors(schema_name, self.data)
def test_api_type_is_optional(): data = load_example_listing("G6-PaaS") del data["apiType"] errs = get_validation_errors("services-g-cloud-7-paas", data) assert not errs.get('apiType', None)
def test_supplier_validates(): data = load_example_listing("supplier_creation") errs = get_validation_errors("new-supplier", data) assert len(errs) is 0