mirror of
https://github.com/ash-project/ash.git
synced 2024-09-19 21:13:10 +12:00
fix: Validate all conditions in a numericality
validation instead of only the last (#997)
The previous `reduce` loop did not break on the first failure and return the error, it returned the last iteration of the loop Some more work may need to be done on the atomic side of the validation, I'm not familiar with how they work!
This commit is contained in:
parent
f504ab6a67
commit
3fce34cda6
2 changed files with 39 additions and 33 deletions
|
@ -34,41 +34,30 @@ defmodule Ash.Resource.Validation.Compare do
|
|||
|
||||
case value do
|
||||
{:ok, value} ->
|
||||
Enum.reduce(
|
||||
Keyword.take(opts, [
|
||||
:greater_than,
|
||||
:less_than,
|
||||
:greater_than_or_equal_to,
|
||||
:less_than_or_equal_to
|
||||
]),
|
||||
:ok,
|
||||
fn validation, _ ->
|
||||
case validation do
|
||||
{:greater_than, attribute} ->
|
||||
if Comp.greater_than?(value, attribute_value(changeset, attribute)),
|
||||
do: :ok,
|
||||
else: invalid_attribute_error(opts, value)
|
||||
opts
|
||||
|> Keyword.take([
|
||||
:greater_than,
|
||||
:less_than,
|
||||
:greater_than_or_equal_to,
|
||||
:less_than_or_equal_to
|
||||
])
|
||||
|> Enum.find_value(fn
|
||||
{:greater_than, attribute} ->
|
||||
if !Comp.greater_than?(value, attribute_value(changeset, attribute)),
|
||||
do: invalid_attribute_error(opts, value)
|
||||
|
||||
{:greater_than_or_equal_to, attribute} ->
|
||||
if Comp.greater_or_equal?(value, attribute_value(changeset, attribute)),
|
||||
do: :ok,
|
||||
else: invalid_attribute_error(opts, value)
|
||||
{:greater_than_or_equal_to, attribute} ->
|
||||
if !Comp.greater_or_equal?(value, attribute_value(changeset, attribute)),
|
||||
do: invalid_attribute_error(opts, value)
|
||||
|
||||
{:less_than, attribute} ->
|
||||
if Comp.less_than?(value, attribute_value(changeset, attribute)),
|
||||
do: :ok,
|
||||
else: invalid_attribute_error(opts, value)
|
||||
{:less_than, attribute} ->
|
||||
if !Comp.less_than?(value, attribute_value(changeset, attribute)),
|
||||
do: invalid_attribute_error(opts, value)
|
||||
|
||||
{:less_than_or_equal_to, attribute} ->
|
||||
if Comp.less_or_equal?(value, attribute_value(changeset, attribute)),
|
||||
do: :ok,
|
||||
else: invalid_attribute_error(opts, value)
|
||||
|
||||
true ->
|
||||
:ok
|
||||
end
|
||||
end
|
||||
)
|
||||
{:less_than_or_equal_to, attribute} ->
|
||||
if !Comp.less_or_equal?(value, attribute_value(changeset, attribute)),
|
||||
do: invalid_attribute_error(opts, value)
|
||||
end) || :ok
|
||||
|
||||
_ ->
|
||||
:ok
|
||||
|
|
|
@ -136,8 +136,25 @@ defmodule Ash.Test.Resource.Validation.CompareTest do
|
|||
end
|
||||
end
|
||||
|
||||
test "validate against a range of values" do
|
||||
{:ok, opts} =
|
||||
Compare.init(attribute: :number_one, greater_than: 0, less_than_or_equal_to: 10)
|
||||
|
||||
# Below range
|
||||
changeset = Post |> Ash.Changeset.for_create(:create, %{number_one: -1})
|
||||
assert_error(changeset, opts, "must be greater than 0 and must be less than or equal to 10")
|
||||
|
||||
# In range
|
||||
changeset = Post |> Ash.Changeset.for_create(:create, %{number_one: 5})
|
||||
assert :ok = Compare.validate(changeset, opts, %{})
|
||||
|
||||
# Above range
|
||||
changeset = Post |> Ash.Changeset.for_create(:create, %{number_one: 11})
|
||||
assert_error(changeset, opts, "must be greater than 0 and must be less than or equal to 10")
|
||||
end
|
||||
|
||||
defp assert_error(changeset, opts, expected_message) do
|
||||
{:error, %{message: message, vars: vars}} = Compare.validate(changeset, opts, %{})
|
||||
assert {:error, %{message: message, vars: vars}} = Compare.validate(changeset, opts, %{})
|
||||
assert expected_message == translate_message(message, vars)
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue