diff --git a/lib/helper/converter/editor_to_html/index.ex b/lib/helper/converter/editor_to_html/index.ex
index 04b123f89..3538bb9f0 100644
--- a/lib/helper/converter/editor_to_html/index.ex
+++ b/lib/helper/converter/editor_to_html/index.ex
@@ -1,10 +1,3 @@
-# defmodule Helper.Converter.EditorToHTML.Parser do
-# @moduledoc false
-
-# # TODO: map should be editor_block
-# @callback parse_block(editor_json :: Map.t()) :: String.t()
-# end
-
defmodule Helper.Converter.EditorToHTML do
@moduledoc """
parse editor.js's json data to raw html and sanitize it
diff --git a/lib/helper/converter/editor_to_html/validator/editor_schema.ex b/lib/helper/converter/editor_to_html/validator/editor_schema.ex
index 2d2840269..4d5449560 100644
--- a/lib/helper/converter/editor_to_html/validator/editor_schema.ex
+++ b/lib/helper/converter/editor_to_html/validator/editor_schema.ex
@@ -48,7 +48,7 @@ defmodule Helper.Converter.EditorToHTML.Validator.EditorSchema do
def get("table") do
[
- parent: %{"columnCount" => [:number], "items" => [:list]},
+ parent: %{"columnCount" => [:number, min: 2], "items" => [:list]},
item: %{
"text" => [:string],
"align" => [enum: @valid_table_align],
diff --git a/lib/helper/validator/schema.ex b/lib/helper/validator/schema.ex
index bef9f2969..a56f1f4f2 100644
--- a/lib/helper/validator/schema.ex
+++ b/lib/helper/validator/schema.ex
@@ -5,7 +5,7 @@ defmodule Helper.Validator.Schema do
currently support boolean / string / number / enum
"""
- use Helper.Validator.Schema.Matchers, [:string, :number, :list, :boolean]
+ # use Helper.Validator.Schema.Matchers, [:string, :number, :list, :boolean]
@doc """
cast data by given schema
@@ -49,10 +49,9 @@ defmodule Helper.Validator.Schema do
end)
end
- # enum
defp match(field, nil, enum: _, required: false), do: done(field, nil)
- defp match(field, value, enum: enum, required: false) do
+ defp match(field, value, enum: enum, required: _) do
match(field, value, enum: enum)
end
@@ -70,9 +69,84 @@ defmodule Helper.Validator.Schema do
end
end
+ defp match(field, value, [type | options]) do
+ match(field, value, type, options)
+ end
+
+ defp match(field, nil, _type, [{:required, false} | _options]) do
+ done(field, nil)
+ end
+
+ defp match(field, value, type, [{:required, _} | options]) do
+ match(field, value, type, options)
+ end
+
+ # custom validate logic
+ defp match(field, value, :string, [{:min, min} | options])
+ when is_binary(value) and is_integer(min) do
+ case String.length(value) >= min do
+ true ->
+ match(field, value, :string, options)
+
+ false ->
+ error(field, value, :min, min)
+ end
+ end
+
+ defp match(field, value, :number, [{:min, min} | options])
+ when is_integer(value) and is_integer(min) do
+ case value >= min do
+ true ->
+ match(field, value, :number, options)
+
+ false ->
+ error(field, value, :min, min)
+ end
+ end
+
+ # custom validate logic end
+
+ # main type
+ defp match(field, value, :string, []) when is_binary(value), do: done(field, value)
+ defp match(field, value, :number, []) when is_integer(value), do: done(field, value)
+ defp match(field, value, :list, []) when is_list(value), do: done(field, value)
+ defp match(field, value, :boolean, []) when is_boolean(value), do: done(field, value)
+ # main type end
+
+ # judge option
+ defp match(field, value, type, [option]) when is_tuple(option) do
+ # 如果这里不判断的话会和下面的 match 冲突,是否有更好的写法?
+ case option_valid?(option) do
+ true ->
+ error(field, value, type)
+
+ false ->
+ {k, v} = option
+ error(field, value, option: "#{to_string(k)}: #{to_string(v)}")
+ end
+ end
+
+ defp match(field, value, type, _), do: error(field, value, type)
+
defp done(field, value), do: {:ok, %{field: field, value: value}}
+ defp error(field, value, :min, min) do
+ {:error, %{field: field |> to_string, value: value, message: "min size: #{min}"}}
+ end
+
+ defp error(field, value, option: option) do
+ {:error, %{field: field |> to_string, value: value, message: "unknow option: #{option}"}}
+ end
+
+ defp error(field, value, :option) do
+ {:error, %{field: field |> to_string, value: value, message: "unknow option"}}
+ end
+
defp error(field, value, schema) do
{:error, %{field: field |> to_string, value: value, message: "should be: #{schema}"}}
end
+
+ defp option_valid?({:min, v}) when is_integer(v), do: true
+ defp option_valid?({:required, v}) when is_boolean(v), do: true
+ defp option_valid?(_), do: false
end
diff --git a/test/helper/converter/editor_to_html_test/header_test.exs b/test/helper/converter/editor_to_html_test/header_test.exs
index 3b61e067c..bac2f08cd 100644
--- a/test/helper/converter/editor_to_html_test/header_test.exs
+++ b/test/helper/converter/editor_to_html_test/header_test.exs
@@ -127,8 +127,6 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Header do
{:ok, editor_string} = Jason.encode(json)
{:ok, converted} = Parser.to_html(editor_string)
- IO.inspect(converted, label: "converted --")
-
assert Utils.str_occurence(converted, @eyebrow_class) == 0
assert Utils.str_occurence(converted, @footer_class) == 1
end
diff --git a/test/helper/converter/editor_to_html_test/list_test.exs b/test/helper/converter/editor_to_html_test/list_test.exs
index 795655d2e..7577a0c4d 100644
--- a/test/helper/converter/editor_to_html_test/list_test.exs
+++ b/test/helper/converter/editor_to_html_test/list_test.exs
@@ -12,7 +12,7 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.List do
describe "[list block unit]" do
defp set_items(mode, items) do
- editor_json = %{
+ %{
"time" => 1_567_250_876_713,
"blocks" => [
%{
diff --git a/test/helper/converter/editor_to_html_test/table_test.exs b/test/helper/converter/editor_to_html_test/table_test.exs
index 44e64262b..acf1885bb 100644
--- a/test/helper/converter/editor_to_html_test/table_test.exs
+++ b/test/helper/converter/editor_to_html_test/table_test.exs
@@ -119,6 +119,15 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Table do
},
%{block: "table", field: "items", message: "should be: list", value: "bb"}
]
+
+ editor_json = set_items(-2, "bb")
+ {:ok, editor_string} = Jason.encode(editor_json)
+ {:error, err_msg} = Parser.to_html(editor_string)
+
+ assert err_msg == [
+ %{block: "table", field: "columnCount", message: "min size: 2", value: -2},
+ %{block: "table", field: "items", message: "should be: list", value: "bb"}
+ ]
end
end
end
diff --git a/test/helper/validator/schema_test.exs b/test/helper/validator/schema_test.exs
new file mode 100644
index 000000000..690204f03
--- /dev/null
+++ b/test/helper/validator/schema_test.exs
@@ -0,0 +1,158 @@
+defmodule GroupherServer.Test.Helper.Validator.Schema do
+ @moduledoc false
+
+ use GroupherServerWeb.ConnCase, async: true
+
+ alias Helper.Validator.Schema
+
+ describe "[basic schema]" do
+ test "string with options" do
+ schema = %{"text" => [:string, required: false]}
+ data = %{"no_exsit" => "text"}
+ assert {:ok, _} = Schema.cast(schema, data)
+
+ schema = %{"text" => [:string, required: true]}
+ data = %{"no_exsit" => "text"}
+ {:error, error} = Schema.cast(schema, data)
+ assert error == [%{field: "text", message: "should be: string", value: nil}]
+
+ schema = %{"text" => [:string, required: true]}
+ data = %{"text" => "text"}
+ assert {:ok, _} = Schema.cast(schema, data)
+
+ schema = %{"text" => [:string, min: 5]}
+ data = %{"text" => "text"}
+ {:error, error} = Schema.cast(schema, data)
+ assert error == [%{field: "text", message: "min size: 5", value: "text"}]
+
+ schema = %{"text" => [:string, required: false, min: 5]}
+ data = %{"text" => "text"}
+ {:error, error} = Schema.cast(schema, data)
+ assert error == [%{field: "text", message: "min size: 5", value: "text"}]
+
+ schema = %{"text" => [:string, min: 5]}
+ data = %{"no_exsit" => "text"}
+ {:error, error} = Schema.cast(schema, data)
+ assert error == [%{field: "text", message: "should be: string", value: nil}]
+
+ schema = %{"text" => [:string, required: true, min: 5]}
+ data = %{"no_exsit" => "text"}
+ {:error, error} = Schema.cast(schema, data)
+ assert error == [%{field: "text", message: "should be: string", value: nil}]
+
+ schema = %{"text" => [:string, required: true, min: "5"]}
+ data = %{"text" => "text"}
+ {:error, error} = Schema.cast(schema, data)
+ assert error == [%{field: "text", message: "unknow option: min: 5", value: "text"}]
+ # IO.inspect(Schema.cast(schema, data), label: "schema result")
+ end
+
+ test "number with options" do
+ schema = %{"text" => [:number, required: false]}
+ data = %{"no_exsit" => 1}
+ assert {:ok, _} = Schema.cast(schema, data)
+
+ schema = %{"text" => [:number, required: true]}
+ data = %{"no_exsit" => 1}
+ {:error, error} = Schema.cast(schema, data)
+ assert error == [%{field: "text", message: "should be: number", value: nil}]
+
+ schema = %{"text" => [:number, required: true]}
+ data = %{"text" => 1}
+ assert {:ok, _} = Schema.cast(schema, data)
+
+ schema = %{"text" => [:number, min: 5]}
+ data = %{"text" => 4}
+ {:error, error} = Schema.cast(schema, data)
+ assert error == [%{field: "text", message: "min size: 5", value: 4}]
+
+ schema = %{"text" => [:number, required: false, min: 5]}
+ data = %{"text" => 4}
+ {:error, error} = Schema.cast(schema, data)
+ assert error == [%{field: "text", message: "min size: 5", value: 4}]
+
+ schema = %{"text" => [:number, min: 5]}
+ data = %{"no_exsit" => 4}
+ {:error, error} = Schema.cast(schema, data)
+ assert error == [%{field: "text", message: "should be: number", value: nil}]
+
+ schema = %{"text" => [:number, required: true, min: 5]}
+ data = %{"no_exsit" => 1}
+ {:error, error} = Schema.cast(schema, data)
+ assert error == [%{field: "text", message: "should be: number", value: nil}]
+
+ # IO.inspect(Schema.cast(schema, data), label: "schema result")
+ # hello world
+ end
+
+ test "number with wrong option" do
+ schema = %{"text" => [:number, required: true, min: "5"]}
+ data = %{"text" => 1}
+
+ {:error, error} = Schema.cast(schema, data)
+ assert error == [%{field: "text", message: "unknow option: min: 5", value: 1}]
+
+ schema = %{"text" => [:number, required: true, no_exsit_option: "xxx"]}
+ data = %{"text" => 1}
+
+ {:error, error} = Schema.cast(schema, data)
+ assert error == [%{field: "text", message: "unknow option: no_exsit_option: xxx", value: 1}]
+ end
+
+ test "number with options edage case" do
+ schema = %{"text" => [:number, min: 2]}
+ data = %{"text" => "aa"}
+
+ {:error, error} = Schema.cast(schema, data)
+ assert error == [%{field: "text", message: "should be: number", value: "aa"}]
+ end
+
+ test "list with options" do
+ schema = %{"text" => [:list, required: false]}
+ data = %{"no_exsit" => []}
+ assert {:ok, _} = Schema.cast(schema, data)
+
+ schema = %{"text" => [:list, required: true]}
+ data = %{"no_exsit" => []}
+ {:error, error} = Schema.cast(schema, data)
+ assert error == [%{field: "text", message: "should be: list", value: nil}]
+
+ schema = %{"text" => [:list, required: true]}
+ data = %{"text" => []}
+ assert {:ok, _} = Schema.cast(schema, data)
+ end
+
+ test "boolean with options" do
+ schema = %{"text" => [:boolean, required: false]}
+ data = %{"no_exsit" => false}
+ assert {:ok, _} = Schema.cast(schema, data)
+
+ schema = %{"text" => [:boolean, required: true]}
+ data = %{"no_exsit" => false}
+ {:error, error} = Schema.cast(schema, data)
+ assert error == [%{field: "text", message: "should be: boolean", value: nil}]
+
+ schema = %{"text" => [:boolean, required: true]}
+ data = %{"text" => false}
+ assert {:ok, _} = Schema.cast(schema, data)
+ end
+
+ test "enum with options" do
+ schema = %{"text" => [enum: [1, 2, 3], required: false]}
+ data = %{"no_exsit" => false}
+ assert {:ok, _} = Schema.cast(schema, data)
+
+ schema = %{"text" => [enum: [1, 2, 3], required: true]}
+ data = %{"no_exsit" => false}
+ {:error, error} = Schema.cast(schema, data)
+ assert error == [%{field: "text", message: "should be: 1 | 2 | 3"}]
+
+ schema = %{"text" => [enum: [1, 2, 3]]}
+ data = %{"text" => 1}
+ assert {:ok, _} = Schema.cast(schema, data)
+
+ # IO.inspect(Schema.cast(schema, data), label: "schema result")
+ # hello world
+ end
+ end
+end