From fc12b1319bb6e259c683033d63d9edab6cdc20a9 Mon Sep 17 00:00:00 2001 From: Danil Zagoskin Date: Mon, 1 Sep 2025 13:02:19 +0300 Subject: [PATCH] fix format validation of array items --- src/openapi_schema.erl | 2 ++ test/openapi_schema_SUITE.erl | 18 ++++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/openapi_schema.erl b/src/openapi_schema.erl index 24ba28a..e923d91 100644 --- a/src/openapi_schema.erl +++ b/src/openapi_schema.erl @@ -88,6 +88,8 @@ prepare_type(#{oneOf := Types} = Type0) -> Type0#{oneOf := [prepare_type(T) || T <- Types]}; prepare_type(#{type := <<"object">>, properties := Props} = Type0) -> Type0#{properties => maps:map(fun(_, T) -> prepare_type(T) end, Props)}; +prepare_type(#{type := <<"array">>, items := Items} = Type0) -> + Type0#{items => prepare_type(Items)}; prepare_type(#{} = Type0) -> % Convert format name to atom. This matches validators syntax Type1 = case Type0 of diff --git a/test/openapi_schema_SUITE.erl b/test/openapi_schema_SUITE.erl index 4584f07..c3d642c 100644 --- a/test/openapi_schema_SUITE.erl +++ b/test/openapi_schema_SUITE.erl @@ -49,6 +49,8 @@ init_per_suite(Config) -> openapi_handler:load_schema(SchemaPath, test_openapi), BigOpenapiPath = code:lib_dir(openapi_handler) ++ "/test/redocly-big-openapi.json", openapi_handler:load_schema(BigOpenapiPath, big_openapi), + ExamplePath = code:lib_dir(openapi_handler) ++ "/test/example-openapi.json", + openapi_handler:load_schema(ExamplePath, example_openapi), Config. end_per_suite(Config) -> @@ -302,10 +304,18 @@ external_validators(_) -> {error, Err2} = openapi_schema:process(<<" ab cd">>, #{schema => Schema, validators => Validators}), #{error := wrong_format, format := no_space, detail := leading_space} = Err2, - % format validators work with loaded schema - % big_openapi.digest is a composition of allOf and object, so it needs schema to be properly prepared - #{password := <<"ab_cd">>} = openapi_schema:process( - #{username => <<"Joe">>, password => <<"ab cd">>}, #{name => big_openapi, type => digest, validators => #{password => fun no_space_validator/1}}), + % format validators work with loaded schema (to ensure openapi_schema:prepare_type works well) + % as simple value + <<"ab_cd">> = openapi_schema:process(<<"ab cd">>, #{name => example_openapi, type => external_validators_simple, validators => Validators}), + {error, _} = openapi_schema:process(<<" cd">>, #{name => example_openapi, type => external_validators_simple, validators => Validators}), + % as array item (nested) + [[<<"ab_cd">>]] = openapi_schema:process([[<<"ab cd">>]], #{name => example_openapi, type => external_validators_array, validators => Validators}), + {error, _} = openapi_schema:process([[<<" cd">>]], #{name => example_openapi, type => external_validators_array, validators => Validators}), + % as object key (nested) + #{in_object := #{prop1 := <<"ab_cd">>}} = + openapi_schema:process(#{in_object => #{prop1 => <<"ab cd">>}}, #{name => example_openapi, type => external_validators_object, validators => Validators}), + {error, _} = + openapi_schema:process(#{in_object => #{prop1 => <<" cd">>}}, #{name => example_openapi, type => external_validators_object, validators => Validators}), % format validator and pattern work simultaneously Schema2 = #{type => <<"string">>, format => no_space, pattern => <<"^[a-z]+$">>},