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

Commit 2ece8ea

Browse files
committed
refactor(editor): use common schema to validate editor-fmt json
1 parent 39ff354 commit 2ece8ea

File tree

5 files changed

+118
-57
lines changed

5 files changed

+118
-57
lines changed

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

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,9 @@ defmodule Helper.Converter.EditorToHTML.Validator do
1010
# blocks with "mode" and "items" fields
1111
@complex_blocks ["list"]
1212

13-
@valid_list_mode ["checklist", "order_list", "unorder_list"]
14-
@valid_list_label_type ["success", "done", "todo"]
15-
@valid_list_indent [0, 1, 2, 3, 4]
16-
17-
def is_valid(map) when is_map(map) do
18-
with true <- is_valid_editorjs_fmt(map) do
19-
blocks = map["blocks"]
20-
13+
def is_valid(data) when is_map(data) do
14+
with {:ok, _} <- validate_editor_fmt(data),
15+
blocks <- Map.get(data, "blocks") do
2116
try do
2217
validate_blocks(blocks)
2318
rescue
@@ -30,15 +25,13 @@ defmodule Helper.Converter.EditorToHTML.Validator do
3025
e ->
3126
format_parse_error()
3227
end
33-
else
34-
false ->
35-
{:error, "invalid editor json format"}
36-
37-
_ ->
38-
{:error, "invalid editor json"}
3928
end
4029
end
4130

31+
defp validate_editor_fmt(data) do
32+
validate_with("editor", Schema.get("editor"), data)
33+
end
34+
4235
defp validate_blocks([]), do: {:ok, :pass}
4336

4437
defp validate_blocks(blocks) do
@@ -75,7 +68,7 @@ defmodule Helper.Converter.EditorToHTML.Validator do
7568
end
7669

7770
defp validate_block(%{"type" => type}), do: raise("undown #{type} block")
78-
defp validate_block(_), do: raise("undown block")
71+
defp validate_block(e), do: raise("undown block: #{e}")
7972

8073
# validate with given schema
8174
defp validate_with(block, schema, data) do

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ defmodule Helper.Converter.EditorToHTML.Validator.Schema do
99
@valid_list_label_type ["success", "done", "todo"]
1010
@valid_list_indent [0, 1, 2, 3, 4]
1111

12+
def get("editor") do
13+
%{
14+
"time" => [:number],
15+
"version" => [:string],
16+
"blocks" => [:list]
17+
}
18+
end
19+
1220
def get("header") do
1321
%{
1422
"text" => [:string],

lib/helper/validate_by_schema.ex

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ defmodule Helper.ValidateBySchema do
88
@doc """
99
cast data by given schema
1010
11-
e.g:
11+
## example
1212
schema = %{
1313
checked: [:boolean],
1414
hideLabel: [:boolean],
@@ -22,28 +22,35 @@ defmodule Helper.ValidateBySchema do
2222
ValidateBySchema.cast(schema, data)
2323
"""
2424
def cast(schema, data) do
25-
schema_fields = Map.keys(schema)
26-
27-
errors_info =
28-
Enum.reduce(schema_fields, [], fn field, acc ->
29-
value = get_in(data, [field])
30-
field_schema = get_in(schema, [field])
31-
32-
case match(field, value, field_schema) do
33-
{:error, error} ->
34-
acc ++ [error]
35-
36-
_ ->
37-
acc
38-
end
39-
end)
25+
errors_info = cast_errors(schema, data)
4026

4127
case errors_info do
4228
[] -> {:ok, :pass}
4329
_ -> {:error, errors_info}
4430
end
4531
end
4632

33+
defp cast_errors(schema, data) do
34+
schema_fields = Map.keys(schema)
35+
36+
Enum.reduce(schema_fields, [], fn field, acc ->
37+
value = get_in(data, [field])
38+
field_schema = get_in(schema, [field])
39+
40+
case match(field, value, field_schema) do
41+
{:error, error} ->
42+
acc ++ [error]
43+
44+
_ ->
45+
acc
46+
end
47+
end)
48+
end
49+
50+
# 这里试过用 macro 消除重复代码,但是不可行。
51+
# macro 对于重复定义的 quote 只会覆盖掉,除非每个 quote 中定义的内容不一样
52+
# 参考: https://elixirforum.com/t/define-multiple-modules-in-macro-only-last-one-gets-created/1654
53+
4754
# boolean field
4855
defp match(field, nil, [:boolean, required: false]), do: done(field, nil)
4956

@@ -66,7 +73,9 @@ defmodule Helper.ValidateBySchema do
6673
defp match(field, value, [:string, required: false]), do: error(field, value, :string)
6774
defp match(field, value, [:string]), do: error(field, value, :string)
6875

69-
# number field
76+
defp match(field, nil, [:string, required: false]), do: done(field, nil)
77+
78+
# number
7079
defp match(field, nil, [:number, required: false]), do: done(field, nil)
7180

7281
defp match(field, value, [:number, required: false]) when is_number(value) do
@@ -77,6 +86,18 @@ defmodule Helper.ValidateBySchema do
7786
defp match(field, value, [:number, required: false]), do: error(field, value, :number)
7887
defp match(field, value, [:number]), do: error(field, value, :number)
7988

89+
# list
90+
defp match(field, nil, [:list, required: false]), do: done(field, nil)
91+
92+
defp match(field, value, [:list, required: false]) when is_list(value) do
93+
done(field, value)
94+
end
95+
96+
defp match(field, value, [:list]) when is_list(value), do: done(field, value)
97+
defp match(field, value, [:list, required: false]), do: error(field, value, :list)
98+
defp match(field, value, [:list]), do: error(field, value, :list)
99+
100+
# enum
80101
defp match(field, nil, enum: _, required: false), do: done(field, nil)
81102

82103
defp match(field, value, enum: enum, required: false) do

test/helper/converter/editor_to_html_test/index_test.exs

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML do
4141
assert {:ok, _} = Parser.to_html(editor_string)
4242
end
4343

44-
@tag :wip
44+
@tag :wip2
4545
test "invalid editorjs json fmt should raise error" do
4646
editor_json = %{
4747
"invalid_time" => 1_567_250_876_713,
@@ -50,7 +50,29 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML do
5050
}
5151

5252
{:ok, editor_string} = Jason.encode(editor_json)
53-
assert {:error, "invalid editor json format"} = Parser.to_html(editor_string)
53+
{:error, error} = Parser.to_html(editor_string)
54+
55+
assert error == [
56+
%{block: "editor", field: "time", message: "should be: number", value: nil}
57+
]
58+
59+
editor_json = %{
60+
"time" => "1_567_250_876_713",
61+
"blocks" => [],
62+
"version" => "2.15.0"
63+
}
64+
65+
{:ok, editor_string} = Jason.encode(editor_json)
66+
{:error, error} = Parser.to_html(editor_string)
67+
68+
assert error == [
69+
%{
70+
block: "editor",
71+
field: "time",
72+
message: "should be: number",
73+
value: "1_567_250_876_713"
74+
}
75+
]
5476

5577
editor_json = %{
5678
"time" => 1_567_250_876_713,
@@ -60,7 +82,22 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML do
6082
}
6183

6284
{:ok, editor_string} = Jason.encode(editor_json)
63-
assert {:error, "invalid editor json format"} = Parser.to_html(editor_string)
85+
{:error, error} = Parser.to_html(editor_string)
86+
87+
assert error == [
88+
%{block: "editor", field: "blocks", message: "should be: list", value: "blocks"}
89+
]
90+
91+
editor_json = %{
92+
"time" => 1_567_250_876_713,
93+
"blocks" => [1, 2, 3],
94+
"version" => "2.15.0"
95+
}
96+
97+
{:ok, editor_string} = Jason.encode(editor_json)
98+
{:error, error} = Parser.to_html(editor_string)
99+
100+
assert error == "undown block: 1"
64101
end
65102

66103
test "real-world editor.js data should work" do

test/helper/converter/editor_to_html_test/list_test.exs

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.List do
1919
"items" => [
2020
%{
2121
"checked" => true,
22-
"hideLabel" => "invalid",
23-
"indent" => 5,
22+
"hideLabel" => false,
23+
"indent" => 0,
2424
"label" => "label",
2525
"labelType" => "success",
2626
"text" => "list item"
@@ -32,23 +32,11 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.List do
3232
"version" => "2.15.0"
3333
}
3434
@tag :wip
35-
test "invalid list data parse should raise error message" do
35+
test "valid list parse should work" do
3636
{:ok, editor_string} = Jason.encode(@editor_json)
37-
{:error, err_msg} = Parser.to_html(editor_string)
38-
39-
assert err_msg == [
40-
%{
41-
block: "list(checklist)",
42-
field: "hideLabel",
43-
message: "should be: boolean",
44-
value: "invalid"
45-
},
46-
%{
47-
block: "list(checklist)",
48-
field: "indent",
49-
message: "should be: 0 | 1 | 2 | 3 | 4"
50-
}
51-
]
37+
# assert {:ok, converted} = Parser.to_html(editor_string)
38+
{:ok, converted} = Parser.to_html(editor_string)
39+
IO.inspect(converted, label: "list converted")
5240
end
5341

5442
@editor_json %{
@@ -61,8 +49,8 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.List do
6149
"items" => [
6250
%{
6351
"checked" => true,
64-
"hideLabel" => false,
65-
"indent" => 0,
52+
"hideLabel" => "invalid",
53+
"indent" => 5,
6654
"label" => "label",
6755
"labelType" => "success",
6856
"text" => "list item"
@@ -74,9 +62,23 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.List do
7462
"version" => "2.15.0"
7563
}
7664
@tag :wip
77-
test "valid list parse should work" do
65+
test "invalid list data parse should raise error message" do
7866
{:ok, editor_string} = Jason.encode(@editor_json)
79-
assert {:ok, _} = Parser.to_html(editor_string)
67+
{:error, err_msg} = Parser.to_html(editor_string)
68+
69+
assert err_msg == [
70+
%{
71+
block: "list(checklist)",
72+
field: "hideLabel",
73+
message: "should be: boolean",
74+
value: "invalid"
75+
},
76+
%{
77+
block: "list(checklist)",
78+
field: "indent",
79+
message: "should be: 0 | 1 | 2 | 3 | 4"
80+
}
81+
]
8082
end
8183

8284
@editor_json %{

0 commit comments

Comments
 (0)