|
|
@@ -46,37 +46,78 @@ t_simple_binary(_config) ->
|
|
|
t_object(_config) ->
|
|
|
Path = "/object",
|
|
|
Object =
|
|
|
- #{<<"content">> => #{<<"application/json">> =>
|
|
|
- #{<<"schema">> => #{required => [<<"timeout">>, <<"per_page">>],
|
|
|
- <<"properties">> => [
|
|
|
- {<<"per_page">>, #{description => <<"good per page desc">>,
|
|
|
- maximum => 100, minimum => 1, type => integer}},
|
|
|
- {<<"timeout">>, #{default => 5, <<"oneOf">> =>
|
|
|
- [#{example => <<"1h">>, type => string}, #{enum => [infinity], type => string}]}},
|
|
|
- {<<"inner_ref">>, #{<<"$ref">> =>
|
|
|
- <<"#/components/schemas/emqx_swagger_response_SUITE.good_ref">>}}],
|
|
|
- <<"type">> => object}}}},
|
|
|
+ #{
|
|
|
+ <<"content">> => #{
|
|
|
+ <<"application/json">> =>
|
|
|
+ #{
|
|
|
+ <<"schema">> => #{
|
|
|
+ required => [<<"timeout">>, <<"per_page">>],
|
|
|
+ <<"properties">> => [
|
|
|
+ {<<"per_page">>, #{
|
|
|
+ description => <<"good per page desc">>,
|
|
|
+ maximum => 100,
|
|
|
+ minimum => 1,
|
|
|
+ type => integer
|
|
|
+ }},
|
|
|
+ {<<"timeout">>, #{
|
|
|
+ default => 5,
|
|
|
+ <<"oneOf">> =>
|
|
|
+ [
|
|
|
+ #{example => <<"1h">>, type => string},
|
|
|
+ #{enum => [infinity], type => string}
|
|
|
+ ]
|
|
|
+ }},
|
|
|
+ {<<"inner_ref">>, #{
|
|
|
+ <<"$ref">> =>
|
|
|
+ <<"#/components/schemas/emqx_swagger_response_SUITE.good_ref">>
|
|
|
+ }}
|
|
|
+ ],
|
|
|
+ <<"type">> => object
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
ExpectRefs = [{?MODULE, good_ref}],
|
|
|
validate(Path, Object, ExpectRefs),
|
|
|
ok.
|
|
|
|
|
|
t_error(_Config) ->
|
|
|
Path = "/error",
|
|
|
- Error400 = #{<<"content">> =>
|
|
|
- #{<<"application/json">> => #{<<"schema">> => #{<<"type">> => object,
|
|
|
- <<"properties">> =>
|
|
|
- [
|
|
|
- {<<"code">>, #{enum => ['Bad1', 'Bad2'], type => string}},
|
|
|
- {<<"message">>, #{description => <<"Bad request desc">>, type => string}}]
|
|
|
- }}}},
|
|
|
- Error404 = #{<<"content">> =>
|
|
|
- #{<<"application/json">> => #{<<"schema">> => #{<<"type">> => object,
|
|
|
- <<"properties">> =>
|
|
|
- [
|
|
|
- {<<"code">>, #{enum => ['Not-Found'], type => string}},
|
|
|
- {<<"message">>, #{
|
|
|
- description => <<"Error code to troubleshoot problems.">>, type => string}}]
|
|
|
- }}}},
|
|
|
+ Error400 = #{
|
|
|
+ <<"content">> =>
|
|
|
+ #{
|
|
|
+ <<"application/json">> => #{
|
|
|
+ <<"schema">> => #{
|
|
|
+ <<"type">> => object,
|
|
|
+ <<"properties">> =>
|
|
|
+ [
|
|
|
+ {<<"code">>, #{enum => ['Bad1', 'Bad2'], type => string}},
|
|
|
+ {<<"message">>, #{
|
|
|
+ description => <<"Bad request desc">>, type => string
|
|
|
+ }}
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ Error404 = #{
|
|
|
+ <<"content">> =>
|
|
|
+ #{
|
|
|
+ <<"application/json">> => #{
|
|
|
+ <<"schema">> => #{
|
|
|
+ <<"type">> => object,
|
|
|
+ <<"properties">> =>
|
|
|
+ [
|
|
|
+ {<<"code">>, #{enum => ['Not-Found'], type => string}},
|
|
|
+ {<<"message">>, #{
|
|
|
+ description => <<"Error code to troubleshoot problems.">>,
|
|
|
+ type => string
|
|
|
+ }}
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
{OperationId, Spec, Refs} = emqx_dashboard_swagger:parse_spec_ref(?MODULE, Path, #{}),
|
|
|
?assertEqual(test, OperationId),
|
|
|
Response = maps:get(responses, maps:get(get, Spec)),
|
|
|
@@ -89,121 +130,243 @@ t_error(_Config) ->
|
|
|
t_nest_object(_Config) ->
|
|
|
Path = "/nest/object",
|
|
|
Object =
|
|
|
- #{<<"content">> => #{<<"application/json">> => #{<<"schema">> =>
|
|
|
- #{required => [<<"timeout">>], <<"type">> => object, <<"properties">> => [
|
|
|
- {<<"per_page">>, #{description => <<"good per page desc">>,
|
|
|
- maximum => 100, minimum => 1, type => integer}},
|
|
|
- {<<"timeout">>, #{default => 5, <<"oneOf">> =>
|
|
|
- [#{example => <<"1h">>, type => string}, #{enum => [infinity], type => string}]}},
|
|
|
- {<<"nest_object">>, #{<<"type">> => object, <<"properties">> => [
|
|
|
- {<<"good_nest_1">>, #{type => integer}},
|
|
|
- {<<"good_nest_2">>, #{<<"$ref">> =>
|
|
|
- <<"#/components/schemas/emqx_swagger_response_SUITE.good_ref">>}
|
|
|
- }]}},
|
|
|
- {<<"inner_ref">>, #{<<"$ref">> =>
|
|
|
- <<"#/components/schemas/emqx_swagger_response_SUITE.good_ref">>}}]
|
|
|
- }}}},
|
|
|
+ #{
|
|
|
+ <<"content">> => #{
|
|
|
+ <<"application/json">> => #{
|
|
|
+ <<"schema">> =>
|
|
|
+ #{
|
|
|
+ required => [<<"timeout">>],
|
|
|
+ <<"type">> => object,
|
|
|
+ <<"properties">> => [
|
|
|
+ {<<"per_page">>, #{
|
|
|
+ description => <<"good per page desc">>,
|
|
|
+ maximum => 100,
|
|
|
+ minimum => 1,
|
|
|
+ type => integer
|
|
|
+ }},
|
|
|
+ {<<"timeout">>, #{
|
|
|
+ default => 5,
|
|
|
+ <<"oneOf">> =>
|
|
|
+ [
|
|
|
+ #{example => <<"1h">>, type => string},
|
|
|
+ #{enum => [infinity], type => string}
|
|
|
+ ]
|
|
|
+ }},
|
|
|
+ {<<"nest_object">>, #{
|
|
|
+ <<"type">> => object,
|
|
|
+ <<"properties">> => [
|
|
|
+ {<<"good_nest_1">>, #{type => integer}},
|
|
|
+ {<<"good_nest_2">>, #{
|
|
|
+ <<"$ref">> =>
|
|
|
+ <<"#/components/schemas/emqx_swagger_response_SUITE.good_ref">>
|
|
|
+ }}
|
|
|
+ ]
|
|
|
+ }},
|
|
|
+ {<<"inner_ref">>, #{
|
|
|
+ <<"$ref">> =>
|
|
|
+ <<"#/components/schemas/emqx_swagger_response_SUITE.good_ref">>
|
|
|
+ }}
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
ExpectRefs = [{?MODULE, good_ref}],
|
|
|
validate(Path, Object, ExpectRefs),
|
|
|
ok.
|
|
|
|
|
|
t_empty(_Config) ->
|
|
|
- ?assertThrow({error,
|
|
|
- #{msg := <<"Object only supports not empty proplists">>,
|
|
|
- args := [], module := ?MODULE}}, validate("/empty", error, [])),
|
|
|
+ ?assertThrow(
|
|
|
+ {error, #{
|
|
|
+ msg := <<"Object only supports not empty proplists">>,
|
|
|
+ args := [],
|
|
|
+ module := ?MODULE
|
|
|
+ }},
|
|
|
+ validate("/empty", error, [])
|
|
|
+ ),
|
|
|
ok.
|
|
|
|
|
|
t_raw_local_ref(_Config) ->
|
|
|
Path = "/raw/ref/local",
|
|
|
- Object = #{<<"content">> => #{<<"application/json">> => #{<<"schema">> => #{
|
|
|
- <<"$ref">> => <<"#/components/schemas/emqx_swagger_response_SUITE.good_ref">>}}}},
|
|
|
+ Object = #{
|
|
|
+ <<"content">> => #{
|
|
|
+ <<"application/json">> => #{
|
|
|
+ <<"schema">> => #{
|
|
|
+ <<"$ref">> => <<"#/components/schemas/emqx_swagger_response_SUITE.good_ref">>
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
ExpectRefs = [{?MODULE, good_ref}],
|
|
|
validate(Path, Object, ExpectRefs),
|
|
|
ok.
|
|
|
|
|
|
t_raw_remote_ref(_Config) ->
|
|
|
Path = "/raw/ref/remote",
|
|
|
- Object = #{<<"content">> =>
|
|
|
- #{<<"application/json">> => #{<<"schema">> => #{
|
|
|
- <<"$ref">> => <<"#/components/schemas/emqx_swagger_remote_schema.ref1">>}}}},
|
|
|
+ Object = #{
|
|
|
+ <<"content">> =>
|
|
|
+ #{
|
|
|
+ <<"application/json">> => #{
|
|
|
+ <<"schema">> => #{
|
|
|
+ <<"$ref">> => <<"#/components/schemas/emqx_swagger_remote_schema.ref1">>
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
ExpectRefs = [{emqx_swagger_remote_schema, "ref1"}],
|
|
|
validate(Path, Object, ExpectRefs),
|
|
|
ok.
|
|
|
|
|
|
t_local_ref(_Config) ->
|
|
|
Path = "/ref/local",
|
|
|
- Object = #{<<"content">> => #{<<"application/json">> => #{<<"schema">> => #{
|
|
|
- <<"$ref">> => <<"#/components/schemas/emqx_swagger_response_SUITE.good_ref">>}}}},
|
|
|
+ Object = #{
|
|
|
+ <<"content">> => #{
|
|
|
+ <<"application/json">> => #{
|
|
|
+ <<"schema">> => #{
|
|
|
+ <<"$ref">> => <<"#/components/schemas/emqx_swagger_response_SUITE.good_ref">>
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
ExpectRefs = [{?MODULE, good_ref}],
|
|
|
validate(Path, Object, ExpectRefs),
|
|
|
ok.
|
|
|
|
|
|
t_remote_ref(_Config) ->
|
|
|
Path = "/ref/remote",
|
|
|
- Object = #{<<"content">> =>
|
|
|
- #{<<"application/json">> => #{<<"schema">> => #{
|
|
|
- <<"$ref">> => <<"#/components/schemas/emqx_swagger_remote_schema.ref1">>}}}},
|
|
|
+ Object = #{
|
|
|
+ <<"content">> =>
|
|
|
+ #{
|
|
|
+ <<"application/json">> => #{
|
|
|
+ <<"schema">> => #{
|
|
|
+ <<"$ref">> => <<"#/components/schemas/emqx_swagger_remote_schema.ref1">>
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
ExpectRefs = [{emqx_swagger_remote_schema, "ref1"}],
|
|
|
validate(Path, Object, ExpectRefs),
|
|
|
ok.
|
|
|
|
|
|
t_bad_ref(_Config) ->
|
|
|
Path = "/ref/bad",
|
|
|
- Object = #{<<"content">> => #{<<"application/json">> => #{<<"schema">> =>
|
|
|
- #{<<"$ref">> => <<"#/components/schemas/emqx_swagger_response_SUITE.bad_ref">>}}}},
|
|
|
+ Object = #{
|
|
|
+ <<"content">> => #{
|
|
|
+ <<"application/json">> => #{
|
|
|
+ <<"schema">> =>
|
|
|
+ #{<<"$ref">> => <<"#/components/schemas/emqx_swagger_response_SUITE.bad_ref">>}
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
ExpectRefs = [{?MODULE, bad_ref}],
|
|
|
- ?assertThrow({error, #{module := ?MODULE,
|
|
|
- msg := <<"Object only supports not empty proplists">>}},
|
|
|
- validate(Path, Object, ExpectRefs)),
|
|
|
+ ?assertThrow(
|
|
|
+ {error, #{
|
|
|
+ module := ?MODULE,
|
|
|
+ msg := <<"Object only supports not empty proplists">>
|
|
|
+ }},
|
|
|
+ validate(Path, Object, ExpectRefs)
|
|
|
+ ),
|
|
|
ok.
|
|
|
|
|
|
t_none_ref(_Config) ->
|
|
|
Path = "/ref/none",
|
|
|
- ?assertThrow({error, #{mfa := {?MODULE, schema, ["/ref/none"]},
|
|
|
- reason := function_clause}}, validate(Path, #{}, [])),
|
|
|
+ ?assertThrow(
|
|
|
+ {error, #{
|
|
|
+ mfa := {?MODULE, schema, ["/ref/none"]},
|
|
|
+ reason := function_clause
|
|
|
+ }},
|
|
|
+ validate(Path, #{}, [])
|
|
|
+ ),
|
|
|
ok.
|
|
|
|
|
|
t_nest_ref(_Config) ->
|
|
|
Path = "/ref/nest/ref",
|
|
|
- Object = #{<<"content">> => #{<<"application/json">> => #{<<"schema">> => #{
|
|
|
- <<"$ref">> => <<"#/components/schemas/emqx_swagger_response_SUITE.nest_ref">>}}}},
|
|
|
+ Object = #{
|
|
|
+ <<"content">> => #{
|
|
|
+ <<"application/json">> => #{
|
|
|
+ <<"schema">> => #{
|
|
|
+ <<"$ref">> => <<"#/components/schemas/emqx_swagger_response_SUITE.nest_ref">>
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
ExpectRefs = [{?MODULE, nest_ref}],
|
|
|
validate(Path, Object, ExpectRefs),
|
|
|
ok.
|
|
|
|
|
|
t_sub_fields(_Config) ->
|
|
|
Path = "/fields/sub",
|
|
|
- Object = #{<<"content">> => #{<<"application/json">> => #{<<"schema">> => #{
|
|
|
- <<"$ref">> => <<"#/components/schemas/emqx_swagger_response_SUITE.sub_fields">>}}}},
|
|
|
+ Object = #{
|
|
|
+ <<"content">> => #{
|
|
|
+ <<"application/json">> => #{
|
|
|
+ <<"schema">> => #{
|
|
|
+ <<"$ref">> => <<"#/components/schemas/emqx_swagger_response_SUITE.sub_fields">>
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
ExpectRefs = [{?MODULE, sub_fields}],
|
|
|
validate(Path, Object, ExpectRefs),
|
|
|
ok.
|
|
|
|
|
|
t_complicated_type(_Config) ->
|
|
|
Path = "/ref/complicated_type",
|
|
|
- Object = #{<<"content">> => #{<<"application/json">> =>
|
|
|
- #{<<"schema">> => #{<<"properties">> =>
|
|
|
- [
|
|
|
- {<<"no_neg_integer">>, #{minimum => 0, type => integer}},
|
|
|
- {<<"url">>, #{example => <<"http://127.0.0.1">>, type => string}},
|
|
|
- {<<"server">>, #{example => <<"127.0.0.1:80">>, type => string}},
|
|
|
- {<<"connect_timeout">>, #{example => infinity, <<"oneOf">> => [
|
|
|
- #{example => infinity, type => string},
|
|
|
- #{type => integer}]}},
|
|
|
- {<<"pool_type">>, #{enum => [random, hash], type => string}},
|
|
|
- {<<"timeout">>, #{example => infinity,
|
|
|
- <<"oneOf">> => [#{example => infinity, type => string}, #{type => integer}]}},
|
|
|
- {<<"bytesize">>, #{example => <<"32MB">>, type => string}},
|
|
|
- {<<"wordsize">>, #{example => <<"1024KB">>, type => string}},
|
|
|
- {<<"maps">>, #{example => #{}, type => object}},
|
|
|
- {<<"comma_separated_list">>, #{example => <<"item1,item2">>, type => string}},
|
|
|
- {<<"comma_separated_atoms">>, #{example => <<"item1,item2">>, type => string}},
|
|
|
- {<<"log_level">>,
|
|
|
- #{enum => [debug, info, notice, warning, error, critical, alert, emergency, all],
|
|
|
- type => string}},
|
|
|
- {<<"fix_integer">>, #{default => 100, enum => [100],type => integer}}
|
|
|
- ],
|
|
|
- <<"type">> => object}}}},
|
|
|
+ Object = #{
|
|
|
+ <<"content">> => #{
|
|
|
+ <<"application/json">> =>
|
|
|
+ #{
|
|
|
+ <<"schema">> => #{
|
|
|
+ <<"properties">> =>
|
|
|
+ [
|
|
|
+ {<<"no_neg_integer">>, #{minimum => 0, type => integer}},
|
|
|
+ {<<"url">>, #{example => <<"http://127.0.0.1">>, type => string}},
|
|
|
+ {<<"server">>, #{example => <<"127.0.0.1:80">>, type => string}},
|
|
|
+ {<<"connect_timeout">>, #{
|
|
|
+ example => infinity,
|
|
|
+ <<"oneOf">> => [
|
|
|
+ #{example => infinity, type => string},
|
|
|
+ #{type => integer}
|
|
|
+ ]
|
|
|
+ }},
|
|
|
+ {<<"pool_type">>, #{enum => [random, hash], type => string}},
|
|
|
+ {<<"timeout">>, #{
|
|
|
+ example => infinity,
|
|
|
+ <<"oneOf">> => [
|
|
|
+ #{example => infinity, type => string}, #{type => integer}
|
|
|
+ ]
|
|
|
+ }},
|
|
|
+ {<<"bytesize">>, #{example => <<"32MB">>, type => string}},
|
|
|
+ {<<"wordsize">>, #{example => <<"1024KB">>, type => string}},
|
|
|
+ {<<"maps">>, #{example => #{}, type => object}},
|
|
|
+ {<<"comma_separated_list">>, #{
|
|
|
+ example => <<"item1,item2">>, type => string
|
|
|
+ }},
|
|
|
+ {<<"comma_separated_atoms">>, #{
|
|
|
+ example => <<"item1,item2">>, type => string
|
|
|
+ }},
|
|
|
+ {<<"log_level">>, #{
|
|
|
+ enum => [
|
|
|
+ debug,
|
|
|
+ info,
|
|
|
+ notice,
|
|
|
+ warning,
|
|
|
+ error,
|
|
|
+ critical,
|
|
|
+ alert,
|
|
|
+ emergency,
|
|
|
+ all
|
|
|
+ ],
|
|
|
+ type => string
|
|
|
+ }},
|
|
|
+ {<<"fix_integer">>, #{
|
|
|
+ default => 100, enum => [100], type => integer
|
|
|
+ }}
|
|
|
+ ],
|
|
|
+ <<"type">> => object
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
{OperationId, Spec, Refs} = emqx_dashboard_swagger:parse_spec_ref(?MODULE, Path, #{}),
|
|
|
?assertEqual(test, OperationId),
|
|
|
Response = maps:get(responses, maps:get(post, Spec)),
|
|
|
@@ -211,79 +374,165 @@ t_complicated_type(_Config) ->
|
|
|
?assertEqual([], Refs),
|
|
|
ok.
|
|
|
|
|
|
-
|
|
|
t_ref_array_with_key(_Config) ->
|
|
|
Path = "/ref/array/with/key",
|
|
|
- Object = #{<<"content">> => #{<<"application/json">> => #{<<"schema">> => #{
|
|
|
- required => [<<"timeout">>], <<"type">> => object, <<"properties">> => [
|
|
|
- {<<"per_page">>, #{description => <<"good per page desc">>,
|
|
|
- maximum => 100, minimum => 1, type => integer}},
|
|
|
- {<<"timeout">>, #{default => 5, <<"oneOf">> =>
|
|
|
- [#{example => <<"1h">>, type => string}, #{enum => [infinity], type => string}]}},
|
|
|
- {<<"assert">>, #{description => <<"money">>, type => number}},
|
|
|
- {<<"number_ex">>, #{description => <<"number example">>, type => number}},
|
|
|
- {<<"percent_ex">>, #{description => <<"percent example">>,
|
|
|
- example => <<"12%">>, type => number}},
|
|
|
- {<<"duration_ms_ex">>, #{description => <<"duration ms example">>,
|
|
|
- example => <<"32s">>, type => string}},
|
|
|
- {<<"atom_ex">>, #{description => <<"atom ex">>, type => string}},
|
|
|
- {<<"array_refs">>, #{items => #{<<"$ref">> =>
|
|
|
- <<"#/components/schemas/emqx_swagger_response_SUITE.good_ref">>}, type => array}}
|
|
|
- ]}
|
|
|
- }}},
|
|
|
+ Object = #{
|
|
|
+ <<"content">> => #{
|
|
|
+ <<"application/json">> => #{
|
|
|
+ <<"schema">> => #{
|
|
|
+ required => [<<"timeout">>],
|
|
|
+ <<"type">> => object,
|
|
|
+ <<"properties">> => [
|
|
|
+ {<<"per_page">>, #{
|
|
|
+ description => <<"good per page desc">>,
|
|
|
+ maximum => 100,
|
|
|
+ minimum => 1,
|
|
|
+ type => integer
|
|
|
+ }},
|
|
|
+ {<<"timeout">>, #{
|
|
|
+ default => 5,
|
|
|
+ <<"oneOf">> =>
|
|
|
+ [
|
|
|
+ #{example => <<"1h">>, type => string},
|
|
|
+ #{enum => [infinity], type => string}
|
|
|
+ ]
|
|
|
+ }},
|
|
|
+ {<<"assert">>, #{description => <<"money">>, type => number}},
|
|
|
+ {<<"number_ex">>, #{description => <<"number example">>, type => number}},
|
|
|
+ {<<"percent_ex">>, #{
|
|
|
+ description => <<"percent example">>,
|
|
|
+ example => <<"12%">>,
|
|
|
+ type => number
|
|
|
+ }},
|
|
|
+ {<<"duration_ms_ex">>, #{
|
|
|
+ description => <<"duration ms example">>,
|
|
|
+ example => <<"32s">>,
|
|
|
+ type => string
|
|
|
+ }},
|
|
|
+ {<<"atom_ex">>, #{description => <<"atom ex">>, type => string}},
|
|
|
+ {<<"array_refs">>, #{
|
|
|
+ items => #{
|
|
|
+ <<"$ref">> =>
|
|
|
+ <<"#/components/schemas/emqx_swagger_response_SUITE.good_ref">>
|
|
|
+ },
|
|
|
+ type => array
|
|
|
+ }}
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
ExpectRefs = [{?MODULE, good_ref}],
|
|
|
validate(Path, Object, ExpectRefs),
|
|
|
ok.
|
|
|
|
|
|
t_ref_array_without_key(_Config) ->
|
|
|
Path = "/ref/array/without/key",
|
|
|
- Object = #{<<"content">> => #{<<"application/json">> => #{<<"schema">> => #{
|
|
|
- items => #{<<"$ref">> => <<"#/components/schemas/emqx_swagger_response_SUITE.good_ref">>},
|
|
|
- type => array}}}},
|
|
|
+ Object = #{
|
|
|
+ <<"content">> => #{
|
|
|
+ <<"application/json">> => #{
|
|
|
+ <<"schema">> => #{
|
|
|
+ items => #{
|
|
|
+ <<"$ref">> =>
|
|
|
+ <<"#/components/schemas/emqx_swagger_response_SUITE.good_ref">>
|
|
|
+ },
|
|
|
+ type => array
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
ExpectRefs = [{?MODULE, good_ref}],
|
|
|
validate(Path, Object, ExpectRefs),
|
|
|
ok.
|
|
|
t_hocon_schema_function(_Config) ->
|
|
|
Path = "/ref/hocon/schema/function",
|
|
|
- Object = #{<<"content">> => #{<<"application/json">> => #{<<"schema">> =>
|
|
|
- #{<<"$ref">> => <<"#/components/schemas/emqx_swagger_remote_schema.root">>}}}},
|
|
|
+ Object = #{
|
|
|
+ <<"content">> => #{
|
|
|
+ <<"application/json">> => #{
|
|
|
+ <<"schema">> =>
|
|
|
+ #{<<"$ref">> => <<"#/components/schemas/emqx_swagger_remote_schema.root">>}
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
ExpectComponents = [
|
|
|
- #{<<"emqx_swagger_remote_schema.ref1">> => #{<<"type">> => object,
|
|
|
- <<"properties">> => [
|
|
|
- {<<"protocol">>, #{enum => [http, https], type => string}},
|
|
|
- {<<"port">>, #{default => 18083, type => integer}}]
|
|
|
- }},
|
|
|
- #{<<"emqx_swagger_remote_schema.ref2">> => #{<<"type">> => object,
|
|
|
- <<"properties">> => [
|
|
|
- {<<"page">>, #{description => <<"good page">>,
|
|
|
- maximum => 100, minimum => 1, type => integer}},
|
|
|
- {<<"another_ref">>, #{<<"$ref">> =>
|
|
|
- <<"#/components/schemas/emqx_swagger_remote_schema.ref3">>}}
|
|
|
- ]
|
|
|
- }},
|
|
|
- #{<<"emqx_swagger_remote_schema.ref3">> => #{<<"type">> => object,
|
|
|
- <<"properties">> => [
|
|
|
- {<<"ip">>, #{description => <<"IP:Port">>,
|
|
|
- example => <<"127.0.0.1:80">>, type => string}},
|
|
|
- {<<"version">>, #{description => <<"a good version">>,
|
|
|
- example => <<"1.0.0">>, type => string}}]
|
|
|
- }},
|
|
|
- #{<<"emqx_swagger_remote_schema.root">> =>
|
|
|
- #{required => [<<"default_password">>, <<"default_username">>],
|
|
|
- <<"properties">> => [{<<"listeners">>, #{items =>
|
|
|
- #{<<"oneOf">> =>
|
|
|
- [#{<<"$ref">> => <<"#/components/schemas/emqx_swagger_remote_schema.ref2">>},
|
|
|
- #{<<"$ref">> => <<"#/components/schemas/emqx_swagger_remote_schema.ref1">>}]},
|
|
|
- type => array}},
|
|
|
- {<<"default_username">>,
|
|
|
- #{default => <<"admin">>, type => string}},
|
|
|
- {<<"default_password">>,
|
|
|
- #{default => <<"public">>, type => string}},
|
|
|
- {<<"sample_interval">>,
|
|
|
- #{default => <<"10s">>, example => <<"1h">>, type => string}},
|
|
|
- {<<"token_expired_time">>,
|
|
|
- #{default => <<"30m">>, example => <<"12m">>, type => string}}],
|
|
|
- <<"type">> => object}}],
|
|
|
+ #{
|
|
|
+ <<"emqx_swagger_remote_schema.ref1">> => #{
|
|
|
+ <<"type">> => object,
|
|
|
+ <<"properties">> => [
|
|
|
+ {<<"protocol">>, #{enum => [http, https], type => string}},
|
|
|
+ {<<"port">>, #{default => 18083, type => integer}}
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ },
|
|
|
+ #{
|
|
|
+ <<"emqx_swagger_remote_schema.ref2">> => #{
|
|
|
+ <<"type">> => object,
|
|
|
+ <<"properties">> => [
|
|
|
+ {<<"page">>, #{
|
|
|
+ description => <<"good page">>,
|
|
|
+ maximum => 100,
|
|
|
+ minimum => 1,
|
|
|
+ type => integer
|
|
|
+ }},
|
|
|
+ {<<"another_ref">>, #{
|
|
|
+ <<"$ref">> =>
|
|
|
+ <<"#/components/schemas/emqx_swagger_remote_schema.ref3">>
|
|
|
+ }}
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ },
|
|
|
+ #{
|
|
|
+ <<"emqx_swagger_remote_schema.ref3">> => #{
|
|
|
+ <<"type">> => object,
|
|
|
+ <<"properties">> => [
|
|
|
+ {<<"ip">>, #{
|
|
|
+ description => <<"IP:Port">>,
|
|
|
+ example => <<"127.0.0.1:80">>,
|
|
|
+ type => string
|
|
|
+ }},
|
|
|
+ {<<"version">>, #{
|
|
|
+ description => <<"a good version">>,
|
|
|
+ example => <<"1.0.0">>,
|
|
|
+ type => string
|
|
|
+ }}
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ },
|
|
|
+ #{
|
|
|
+ <<"emqx_swagger_remote_schema.root">> =>
|
|
|
+ #{
|
|
|
+ required => [<<"default_password">>, <<"default_username">>],
|
|
|
+ <<"properties">> => [
|
|
|
+ {<<"listeners">>, #{
|
|
|
+ items =>
|
|
|
+ #{
|
|
|
+ <<"oneOf">> =>
|
|
|
+ [
|
|
|
+ #{
|
|
|
+ <<"$ref">> =>
|
|
|
+ <<"#/components/schemas/emqx_swagger_remote_schema.ref2">>
|
|
|
+ },
|
|
|
+ #{
|
|
|
+ <<"$ref">> =>
|
|
|
+ <<"#/components/schemas/emqx_swagger_remote_schema.ref1">>
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ type => array
|
|
|
+ }},
|
|
|
+ {<<"default_username">>, #{default => <<"admin">>, type => string}},
|
|
|
+ {<<"default_password">>, #{default => <<"public">>, type => string}},
|
|
|
+ {<<"sample_interval">>, #{
|
|
|
+ default => <<"10s">>, example => <<"1h">>, type => string
|
|
|
+ }},
|
|
|
+ {<<"token_expired_time">>, #{
|
|
|
+ default => <<"30m">>, example => <<"12m">>, type => string
|
|
|
+ }}
|
|
|
+ ],
|
|
|
+ <<"type">> => object
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ],
|
|
|
ExpectRefs = [{emqx_swagger_remote_schema, "root"}],
|
|
|
{_, Components} = validate(Path, Object, ExpectRefs),
|
|
|
?assertEqual(ExpectComponents, Components),
|
|
|
@@ -296,31 +545,46 @@ t_api_spec(_Config) ->
|
|
|
api_spec() -> emqx_dashboard_swagger:spec(?MODULE).
|
|
|
|
|
|
paths() ->
|
|
|
- ["/simple/bin", "/object", "/nest/object", "/ref/local",
|
|
|
- "/ref/nest/ref", "/raw/ref/local", "/raw/ref/remote",
|
|
|
- "/ref/array/with/key", "/ref/array/without/key",
|
|
|
- "/ref/hocon/schema/function"].
|
|
|
+ [
|
|
|
+ "/simple/bin",
|
|
|
+ "/object",
|
|
|
+ "/nest/object",
|
|
|
+ "/ref/local",
|
|
|
+ "/ref/nest/ref",
|
|
|
+ "/raw/ref/local",
|
|
|
+ "/raw/ref/remote",
|
|
|
+ "/ref/array/with/key",
|
|
|
+ "/ref/array/without/key",
|
|
|
+ "/ref/hocon/schema/function"
|
|
|
+ ].
|
|
|
|
|
|
schema("/simple/bin") ->
|
|
|
to_schema(<<"binary ok">>);
|
|
|
schema("/object") ->
|
|
|
Object = [
|
|
|
{per_page, mk(range(1, 100), #{required => true, desc => <<"good per page desc">>})},
|
|
|
- {timeout, mk(hoconsc:union([infinity, emqx_schema:duration_s()]),
|
|
|
- #{default => 5, required => true})},
|
|
|
+ {timeout,
|
|
|
+ mk(
|
|
|
+ hoconsc:union([infinity, emqx_schema:duration_s()]),
|
|
|
+ #{default => 5, required => true}
|
|
|
+ )},
|
|
|
{inner_ref, mk(hoconsc:ref(?MODULE, good_ref), #{})}
|
|
|
],
|
|
|
to_schema(Object);
|
|
|
schema("/nest/object") ->
|
|
|
Response = [
|
|
|
{per_page, mk(range(1, 100), #{desc => <<"good per page desc">>})},
|
|
|
- {timeout, mk(hoconsc:union([infinity, emqx_schema:duration_s()]),
|
|
|
- #{default => 5, required => true})},
|
|
|
+ {timeout,
|
|
|
+ mk(
|
|
|
+ hoconsc:union([infinity, emqx_schema:duration_s()]),
|
|
|
+ #{default => 5, required => true}
|
|
|
+ )},
|
|
|
{nest_object, [
|
|
|
{good_nest_1, mk(integer(), #{})},
|
|
|
{good_nest_2, mk(hoconsc:ref(?MODULE, good_ref), #{})}
|
|
|
]},
|
|
|
- {inner_ref, mk(hoconsc:ref(?MODULE, good_ref), #{})}],
|
|
|
+ {inner_ref, mk(hoconsc:ref(?MODULE, good_ref), #{})}
|
|
|
+ ],
|
|
|
to_schema(Response);
|
|
|
schema("/empty") ->
|
|
|
to_schema([]);
|
|
|
@@ -339,8 +603,11 @@ schema("/ref/nest/ref") ->
|
|
|
schema("/ref/array/with/key") ->
|
|
|
to_schema([
|
|
|
{per_page, mk(range(1, 100), #{desc => <<"good per page desc">>})},
|
|
|
- {timeout, mk(hoconsc:union([infinity, emqx_schema:duration_s()]),
|
|
|
- #{default => 5, required => true})},
|
|
|
+ {timeout,
|
|
|
+ mk(
|
|
|
+ hoconsc:union([infinity, emqx_schema:duration_s()]),
|
|
|
+ #{default => 5, required => true}
|
|
|
+ )},
|
|
|
{assert, mk(float(), #{desc => <<"money">>})},
|
|
|
{number_ex, mk(number(), #{desc => <<"number example">>})},
|
|
|
{percent_ex, mk(emqx_schema:percent(), #{desc => <<"percent example">>})},
|
|
|
@@ -355,31 +622,35 @@ schema("/ref/hocon/schema/function") ->
|
|
|
schema("/error") ->
|
|
|
#{
|
|
|
operationId => test,
|
|
|
- get => #{responses => #{
|
|
|
- 400 => emqx_dashboard_swagger:error_codes(['Bad1', 'Bad2'], <<"Bad request desc">>),
|
|
|
- 404 => emqx_dashboard_swagger:error_codes(['Not-Found'])
|
|
|
- }}
|
|
|
+ get => #{
|
|
|
+ responses => #{
|
|
|
+ 400 => emqx_dashboard_swagger:error_codes(['Bad1', 'Bad2'], <<"Bad request desc">>),
|
|
|
+ 404 => emqx_dashboard_swagger:error_codes(['Not-Found'])
|
|
|
+ }
|
|
|
+ }
|
|
|
};
|
|
|
schema("/ref/complicated_type") ->
|
|
|
#{
|
|
|
operationId => test,
|
|
|
- post => #{responses => #{
|
|
|
- 200 => [
|
|
|
- {no_neg_integer, hoconsc:mk(non_neg_integer(), #{})},
|
|
|
- {url, hoconsc:mk(emqx_connector_http:url(), #{})},
|
|
|
- {server, hoconsc:mk(emqx_schema:ip_port(), #{})},
|
|
|
- {connect_timeout, hoconsc:mk(emqx_connector_http:connect_timeout(), #{})},
|
|
|
- {pool_type, hoconsc:mk(emqx_connector_http:pool_type(), #{})},
|
|
|
- {timeout, hoconsc:mk(timeout(), #{})},
|
|
|
- {bytesize, hoconsc:mk(emqx_schema:bytesize(), #{})},
|
|
|
- {wordsize, hoconsc:mk(emqx_schema:wordsize(), #{})},
|
|
|
- {maps, hoconsc:mk(map(), #{})},
|
|
|
- {comma_separated_list, hoconsc:mk(emqx_schema:comma_separated_list(), #{})},
|
|
|
- {comma_separated_atoms, hoconsc:mk(emqx_schema:comma_separated_atoms(), #{})},
|
|
|
- {log_level, hoconsc:mk(emqx_conf_schema:log_level(), #{})},
|
|
|
- {fix_integer, hoconsc:mk(typerefl:integer(100), #{})}
|
|
|
- ]
|
|
|
- }}
|
|
|
+ post => #{
|
|
|
+ responses => #{
|
|
|
+ 200 => [
|
|
|
+ {no_neg_integer, hoconsc:mk(non_neg_integer(), #{})},
|
|
|
+ {url, hoconsc:mk(emqx_connector_http:url(), #{})},
|
|
|
+ {server, hoconsc:mk(emqx_schema:ip_port(), #{})},
|
|
|
+ {connect_timeout, hoconsc:mk(emqx_connector_http:connect_timeout(), #{})},
|
|
|
+ {pool_type, hoconsc:mk(emqx_connector_http:pool_type(), #{})},
|
|
|
+ {timeout, hoconsc:mk(timeout(), #{})},
|
|
|
+ {bytesize, hoconsc:mk(emqx_schema:bytesize(), #{})},
|
|
|
+ {wordsize, hoconsc:mk(emqx_schema:wordsize(), #{})},
|
|
|
+ {maps, hoconsc:mk(map(), #{})},
|
|
|
+ {comma_separated_list, hoconsc:mk(emqx_schema:comma_separated_list(), #{})},
|
|
|
+ {comma_separated_atoms, hoconsc:mk(emqx_schema:comma_separated_atoms(), #{})},
|
|
|
+ {log_level, hoconsc:mk(emqx_conf_schema:log_level(), #{})},
|
|
|
+ {fix_integer, hoconsc:mk(typerefl:integer(100), #{})}
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ }
|
|
|
};
|
|
|
schema("/fields/sub") ->
|
|
|
to_schema(hoconsc:ref(sub_fields)).
|
|
|
@@ -411,18 +682,20 @@ fields(nest_ref) ->
|
|
|
{env, mk(hoconsc:enum([test, dev, prod]), #{})},
|
|
|
{another_ref, mk(hoconsc:ref(good_ref), #{desc => "nest ref"})}
|
|
|
];
|
|
|
-
|
|
|
-fields(bad_ref) -> %% don't support maps
|
|
|
+%% don't support maps
|
|
|
+fields(bad_ref) ->
|
|
|
#{
|
|
|
username => mk(string(), #{}),
|
|
|
is_admin => mk(boolean(), #{})
|
|
|
};
|
|
|
fields(sub_fields) ->
|
|
|
- #{fields => [
|
|
|
- {enable, fun enable/1},
|
|
|
- {init_file, fun init_file/1}
|
|
|
- ],
|
|
|
- desc => <<"test sub fields">>}.
|
|
|
+ #{
|
|
|
+ fields => [
|
|
|
+ {enable, fun enable/1},
|
|
|
+ {init_file, fun init_file/1}
|
|
|
+ ],
|
|
|
+ desc => <<"test sub fields">>
|
|
|
+ }.
|
|
|
|
|
|
enable(type) -> boolean();
|
|
|
enable(desc) -> <<"Whether to enable tls psk support">>;
|