Skip to content
This repository was archived by the owner on Nov 8, 2022. It is now read-only.

Commit f60bf10

Browse files
authored
feat(editor-schema): add new option (#299)
* feat(editor-validator): add starts_with to string option * feat(editor-validator): add type and allow_empty to list option
1 parent f2af8d7 commit f60bf10

File tree

5 files changed

+129
-37
lines changed

5 files changed

+129
-37
lines changed

lib/helper/converter/editor_to_html/validator/editor_schema.ex

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ defmodule Helper.Converter.EditorToHTML.Validator.EditorSchema do
5858
parent: %{
5959
"id" => [:string, required: false],
6060
"mode" => [enum: @valid_list_mode],
61-
"items" => [:list]
61+
"items" => [:list, type: :map, allow_empty: false]
6262
},
6363
item: %{
6464
"checked" => [:boolean],
@@ -77,7 +77,7 @@ defmodule Helper.Converter.EditorToHTML.Validator.EditorSchema do
7777
parent: %{
7878
"id" => [:string, required: false],
7979
"columnCount" => [:number, min: 2],
80-
"items" => [:list]
80+
"items" => [:list, type: :map, allow_empty: false]
8181
},
8282
item: %{
8383
"text" => [:string],
@@ -94,10 +94,10 @@ defmodule Helper.Converter.EditorToHTML.Validator.EditorSchema do
9494
parent: %{
9595
"id" => [:string, required: false],
9696
"mode" => [enum: @valid_image_mode],
97-
"items" => [:list]
97+
"items" => [:list, type: :map, allow_empty: false]
9898
},
9999
item: %{
100-
"src" => [:string],
100+
"src" => [:string, starts_with: "https://"],
101101
"index" => [:number],
102102
"caption" => [:string, required: false],
103103
"height" => [:string, required: false],

lib/helper/validator/schema.ex

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ defmodule Helper.Validator.Schema do
5858

5959
defp option_valid?({:min, v}) when is_integer(v), do: true
6060
defp option_valid?({:required, v}) when is_boolean(v), do: true
61+
defp option_valid?({:starts_with, v}) when is_binary(v), do: true
62+
defp option_valid?({:type, :map}), do: true
63+
defp option_valid?({:allow_empty, v}) when is_boolean(v), do: true
64+
6165
defp option_valid?(_), do: false
6266

6367
defp match(field, nil, enum: _, required: false), do: done(field, nil)
@@ -82,6 +86,7 @@ defmodule Helper.Validator.Schema do
8286
end
8387

8488
# custom validate logic
89+
# min option for @support_min types
8590
defp match(field, value, type, [{:min, min} | options])
8691
when type in @support_min and g_not_nil(value) and g_pos_int(min) do
8792
case Utils.large_than(value, min) do
@@ -93,6 +98,42 @@ defmodule Helper.Validator.Schema do
9398
end
9499
end
95100

101+
# starts_with option for string
102+
defp match(field, value, type, [{:starts_with, starts} | options]) when is_binary(value) do
103+
case String.starts_with?(value, starts) do
104+
true ->
105+
match(field, value, type, options)
106+
107+
false ->
108+
error(field, value, :starts_with, starts)
109+
end
110+
end
111+
112+
# item type for list
113+
defp match(field, value, type, [{:type, :map} | options]) when is_list(value) do
114+
case Enum.all?(value, &is_map(&1)) do
115+
true ->
116+
match(field, value, type, options)
117+
118+
false ->
119+
error(field, value, :list_type_map)
120+
end
121+
end
122+
123+
defp match(field, value, type, [{:allow_empty, false} | options]) when is_list(value) do
124+
case length(value) do
125+
0 ->
126+
error(field, value, :allow_empty)
127+
128+
_ ->
129+
match(field, value, type, options)
130+
end
131+
end
132+
133+
defp match(field, value, type, [{:allow_empty, true} | options]) when is_list(value) do
134+
match(field, value, type, options)
135+
end
136+
96137
# custom validate logic end
97138

98139
# main type
@@ -120,10 +161,25 @@ defmodule Helper.Validator.Schema do
120161

121162
defp done(field, value), do: {:ok, %{field: field, value: value}}
122163

123-
defp error(field, value, :min, min) do
124-
{:error, %{field: field |> to_string, value: value, message: "min size: #{min}"}}
164+
# custom error hint
165+
defp error(field, value, :min, expect) do
166+
{:error, %{field: field |> to_string, value: value, message: "min size: #{expect}"}}
125167
end
126168

169+
defp error(field, value, :starts_with, expect) do
170+
{:error, %{field: field |> to_string, value: value, message: "should starts with: #{expect}"}}
171+
end
172+
173+
defp error(field, value, :list_type_map) do
174+
{:error, %{field: field |> to_string, value: value, message: "item should be map"}}
175+
end
176+
177+
defp error(field, value, :allow_empty) do
178+
{:error, %{field: field |> to_string, value: value, message: "empty is not allowed"}}
179+
end
180+
181+
# custom error hint end
182+
127183
defp error(field, value, option: option) do
128184
{:error, %{field: field |> to_string, value: value, message: "unknow option: #{option}"}}
129185
end

test/helper/converter/editor_to_html_test/image_test.exs

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Image do
117117
assert Utils.str_occurence(converted, image_caption_class) == 0
118118
end
119119

120-
@tag :wip2
120+
@tag :wip
121121
test "jiugongge image parse should work" do
122122
editor_json =
123123
set_items(
@@ -143,7 +143,7 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Image do
143143
assert Utils.str_occurence(converted, jiugongge_image_class) == length(@images)
144144
end
145145

146-
@tag :wip2
146+
@tag :wip
147147
test "gallery image parse should work" do
148148
editor_json =
149149
set_items(
@@ -192,19 +192,20 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Image do
192192
assert Utils.str_occurence(converted, "id=\"exsit\"") == 1
193193
end
194194

195-
@tag :wip2
195+
@tag :wip
196196
test "invalid mode parse should raise error message" do
197197
editor_json = set_items("invalid-mode", [])
198198
{:ok, editor_string} = Jason.encode(editor_json)
199199
{:error, err_msg} = Parser.to_html(editor_string)
200200

201-
assert err_msg == [
201+
assert [
202+
%{block: "image", field: "items", message: "empty is not allowed", value: []},
202203
%{
203204
block: "image",
204205
field: "mode",
205206
message: "should be: single | jiugongge | gallery"
206207
}
207-
]
208+
] == err_msg
208209
end
209210

210211
@tag :wip2
@@ -213,7 +214,7 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Image do
213214
set_items("single", [
214215
%{
215216
"index" => "invalid",
216-
"src" => "src"
217+
"src" => "https://xxx"
217218
}
218219
])
219220

@@ -230,28 +231,28 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Image do
230231
]
231232
end
232233

233-
# @tag :wip2
234-
# test "invalid src parse should raise error message" do
235-
# editor_json =
236-
# set_items("single", [
237-
# %{
238-
# "index" => 0,
239-
# "src" => "src"
240-
# }
241-
# ])
242-
243-
# {:ok, editor_string} = Jason.encode(editor_json)
244-
# {:error, err_msg} = Parser.to_html(editor_string)
245-
# IO.inspect(err_msg, label: "err_msg")
246-
247-
# assert err_msg == [
248-
# %{
249-
# block: "image(single)",
250-
# field: "index",
251-
# message: "should be: number",
252-
# value: "invalid"
253-
# }
254-
# ]
255-
# end
234+
@tag :wip2
235+
test "src should starts with https://" do
236+
editor_json =
237+
set_items("single", [
238+
%{
239+
"index" => 0,
240+
"src" => "src"
241+
}
242+
])
243+
244+
{:ok, editor_string} = Jason.encode(editor_json)
245+
{:error, err_msg} = Parser.to_html(editor_string)
246+
247+
assert err_msg ==
248+
[
249+
%{
250+
block: "image(single)",
251+
field: "src",
252+
message: "should starts with: https://",
253+
value: "src"
254+
}
255+
]
256+
end
256257
end
257258
end

test/helper/converter/editor_to_html_test/list_test.exs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,13 +215,14 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.List do
215215
{:ok, editor_string} = Jason.encode(editor_json)
216216
{:error, err_msg} = Parser.to_html(editor_string)
217217

218-
assert err_msg == [
218+
assert [
219+
%{block: "list", field: "items", message: "empty is not allowed", value: []},
219220
%{
220221
block: "list",
221222
field: "mode",
222223
message: "should be: checklist | order_list | unorder_list"
223224
}
224-
]
225+
] == err_msg
225226
end
226227

227228
@tag :wip

test/helper/validator/schema_test.exs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ defmodule GroupherServer.Test.Helper.Validator.Schema do
66
alias Helper.Validator.Schema
77

88
describe "[basic schema]" do
9+
@tag :wip2
910
test "string with options" do
1011
schema = %{"text" => [:string, required: false]}
1112
data = %{"no_exsit" => "text"}
@@ -44,9 +45,15 @@ defmodule GroupherServer.Test.Helper.Validator.Schema do
4445
data = %{"text" => "text"}
4546
{:error, error} = Schema.cast(schema, data)
4647
assert error == [%{field: "text", message: "unknow option: min: 5", value: "text"}]
48+
49+
schema = %{"text" => [:string, starts_with: "https://"]}
50+
data = %{"text" => "text"}
51+
assert {:error, error} = Schema.cast(schema, data)
52+
assert error == [%{field: "text", message: "should starts with: https://", value: "text"}]
4753
# IO.inspect(Schema.cast(schema, data), label: "schema result")
4854
end
4955

56+
@tag :wip2
5057
test "number with options" do
5158
schema = %{"text" => [:number, required: false]}
5259
data = %{"no_exsit" => 1}
@@ -85,6 +92,7 @@ defmodule GroupherServer.Test.Helper.Validator.Schema do
8592
# hello world
8693
end
8794

95+
@tag :wip2
8896
test "number with wrong option" do
8997
schema = %{"text" => [:number, required: true, min: "5"]}
9098
data = %{"text" => 1}
@@ -99,6 +107,7 @@ defmodule GroupherServer.Test.Helper.Validator.Schema do
99107
assert error == [%{field: "text", message: "unknow option: no_exsit_option: xxx", value: 1}]
100108
end
101109

110+
@tag :wip2
102111
test "number with options edage case" do
103112
schema = %{"text" => [:number, min: 2]}
104113
data = %{"text" => "aa"}
@@ -107,6 +116,7 @@ defmodule GroupherServer.Test.Helper.Validator.Schema do
107116
assert error == [%{field: "text", message: "should be: number", value: "aa"}]
108117
end
109118

119+
@tag :wip2
110120
test "list with options" do
111121
schema = %{"text" => [:list, required: false]}
112122
data = %{"no_exsit" => []}
@@ -120,8 +130,31 @@ defmodule GroupherServer.Test.Helper.Validator.Schema do
120130
schema = %{"text" => [:list, required: true]}
121131
data = %{"text" => []}
122132
assert {:ok, _} = Schema.cast(schema, data)
133+
134+
schema = %{"text" => [:list]}
135+
data = %{"text" => []}
136+
assert {:ok, _} = Schema.cast(schema, data)
137+
138+
schema = %{"text" => [:list, allow_empty: true]}
139+
data = %{"text" => []}
140+
assert {:ok, _} = Schema.cast(schema, data)
141+
142+
schema = %{"text" => [:list, type: :map]}
143+
data = %{"text" => [1, 2, 3]}
144+
{:error, error} = Schema.cast(schema, data)
145+
146+
assert error ==
147+
[%{field: "text", message: "item should be map", value: [1, 2, 3]}]
148+
149+
schema = %{"text" => [:list, allow_empty: false]}
150+
data = %{"text" => []}
151+
{:error, error} = Schema.cast(schema, data)
152+
assert [%{field: "text", message: "empty is not allowed", value: []}] == error
153+
154+
# IO.inspect(Schema.cast(schema, data), label: "schema result")
123155
end
124156

157+
@tag :wip2
125158
test "boolean with options" do
126159
schema = %{"text" => [:boolean, required: false]}
127160
data = %{"no_exsit" => false}
@@ -137,6 +170,7 @@ defmodule GroupherServer.Test.Helper.Validator.Schema do
137170
assert {:ok, _} = Schema.cast(schema, data)
138171
end
139172

173+
@tag :wip2
140174
test "enum with options" do
141175
schema = %{"text" => [enum: [1, 2, 3], required: false]}
142176
data = %{"no_exsit" => false}

0 commit comments

Comments
 (0)