2021-06-02 05:32:22 +12:00
|
|
|
defmodule Ash.Test.Resource.Validation.CompareTest do
|
|
|
|
@moduledoc false
|
|
|
|
use ExUnit.Case, async: true
|
|
|
|
|
|
|
|
alias Ash.Resource.Validation.Compare
|
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
alias Ash.Test.Domain, as: Domain
|
|
|
|
|
2021-06-02 05:32:22 +12:00
|
|
|
defmodule Post do
|
2024-03-28 09:06:40 +13:00
|
|
|
use Ash.Resource, domain: Domain
|
|
|
|
|
|
|
|
actions do
|
|
|
|
default_accept :*
|
|
|
|
defaults [:read, :destroy, create: :*, update: :*]
|
|
|
|
end
|
2021-06-02 05:32:22 +12:00
|
|
|
|
|
|
|
attributes do
|
|
|
|
uuid_primary_key :id
|
2024-03-28 09:06:40 +13:00
|
|
|
|
|
|
|
attribute :number_one, :integer do
|
|
|
|
public?(true)
|
|
|
|
end
|
|
|
|
|
|
|
|
attribute :number_two, :integer do
|
|
|
|
public?(true)
|
|
|
|
end
|
|
|
|
|
|
|
|
attribute :number_three, :decimal do
|
|
|
|
public?(true)
|
|
|
|
end
|
|
|
|
|
|
|
|
attribute :number_four, :float do
|
|
|
|
public?(true)
|
|
|
|
end
|
2021-06-02 05:32:22 +12:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "greater than" do
|
|
|
|
test "validate success against number" do
|
|
|
|
{:ok, opts} = Compare.init(attribute: :number_one, greater_than: 1)
|
2024-03-28 09:06:40 +13:00
|
|
|
changeset = Post |> Ash.Changeset.for_create(:create, %{number_one: 100})
|
2021-06-02 05:32:22 +12:00
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
assert :ok = Compare.validate(changeset, opts, %{})
|
2021-06-02 05:32:22 +12:00
|
|
|
end
|
|
|
|
|
|
|
|
test "validate success against argument" do
|
|
|
|
{:ok, opts} = Compare.init(attribute: :number_one, greater_than: :foo)
|
|
|
|
|
|
|
|
changeset =
|
|
|
|
Post
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.Changeset.new()
|
2021-06-02 05:32:22 +12:00
|
|
|
|> Ash.Changeset.set_argument(:foo, 1)
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{number_one: 100})
|
2021-06-02 05:32:22 +12:00
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
assert :ok = Compare.validate(changeset, opts, %{})
|
2021-06-02 05:32:22 +12:00
|
|
|
end
|
|
|
|
|
|
|
|
test "validate success against attribute" do
|
|
|
|
{:ok, opts} = Compare.init(attribute: :number_one, greater_than: :number_two)
|
|
|
|
|
|
|
|
changeset =
|
|
|
|
Post
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{number_one: 100, number_two: 1})
|
2021-06-02 05:32:22 +12:00
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
assert :ok = Compare.validate(changeset, opts, %{})
|
2021-06-02 05:32:22 +12:00
|
|
|
end
|
|
|
|
|
2022-10-22 03:46:46 +13:00
|
|
|
test "decimals can be compared against" do
|
|
|
|
{:ok, opts} = Compare.init(attribute: :number_three, greater_than: 0)
|
|
|
|
|
|
|
|
changeset =
|
|
|
|
Post
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{number_three: Decimal.new(1)})
|
2022-10-22 03:46:46 +13:00
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
assert :ok = Compare.validate(changeset, opts, %{})
|
2022-10-22 03:46:46 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
test "floats can be compared against" do
|
|
|
|
{:ok, opts} = Compare.init(attribute: :number_four, greater_than: 0)
|
|
|
|
|
|
|
|
changeset =
|
|
|
|
Post
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{number_four: 1.0})
|
2022-10-22 03:46:46 +13:00
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
assert :ok = Compare.validate(changeset, opts, %{})
|
2022-10-22 03:46:46 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
test "decimals can be compared with" do
|
2024-03-28 09:06:40 +13:00
|
|
|
{:ok, opts} =
|
|
|
|
Compare.init(attribute: :number_one, greater_than: Decimal.new(0))
|
2022-10-22 03:46:46 +13:00
|
|
|
|
|
|
|
changeset =
|
|
|
|
Post
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{number_one: 1})
|
2022-10-22 03:46:46 +13:00
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
assert :ok = Compare.validate(changeset, opts, %{})
|
2022-10-22 03:46:46 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
test "floats can be compared with" do
|
|
|
|
{:ok, opts} = Compare.init(attribute: :number_one, greater_than: 0.0)
|
|
|
|
|
|
|
|
changeset =
|
|
|
|
Post
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{number_one: 1})
|
2022-10-22 03:46:46 +13:00
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
assert :ok = Compare.validate(changeset, opts, %{})
|
2022-10-22 03:46:46 +13:00
|
|
|
end
|
|
|
|
|
2021-06-02 05:32:22 +12:00
|
|
|
test "validate failure against number" do
|
|
|
|
{:ok, opts} = Compare.init(attribute: :number_one, greater_than: 100)
|
2024-03-28 09:06:40 +13:00
|
|
|
changeset = Post |> Ash.Changeset.for_create(:create, %{number_one: 1})
|
2021-06-02 05:32:22 +12:00
|
|
|
|
|
|
|
assert_error(changeset, opts, "must be greater than 100")
|
|
|
|
end
|
|
|
|
|
|
|
|
test "validate failure against argument" do
|
|
|
|
{:ok, opts} = Compare.init(attribute: :number_one, greater_than: :foo)
|
|
|
|
|
|
|
|
changeset =
|
|
|
|
Post
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.Changeset.new()
|
2021-06-02 05:32:22 +12:00
|
|
|
|> Ash.Changeset.set_argument(:foo, 100)
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{number_one: 1})
|
2021-06-02 05:32:22 +12:00
|
|
|
|
|
|
|
assert_error(changeset, opts, "must be greater than foo")
|
|
|
|
end
|
|
|
|
|
|
|
|
test "validate failure against attribute" do
|
|
|
|
{:ok, opts} = Compare.init(attribute: :number_one, greater_than: :number_two)
|
|
|
|
|
|
|
|
changeset =
|
|
|
|
Post
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{number_one: 1, number_two: 100})
|
2021-06-02 05:32:22 +12:00
|
|
|
|
|
|
|
assert_error(changeset, opts, "must be greater than number_two")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2024-04-11 01:25:42 +12:00
|
|
|
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
|
|
|
|
|
2021-06-02 05:32:22 +12:00
|
|
|
defp assert_error(changeset, opts, expected_message) do
|
2024-04-11 01:25:42 +12:00
|
|
|
assert {:error, %{message: message, vars: vars}} = Compare.validate(changeset, opts, %{})
|
2021-06-02 05:32:22 +12:00
|
|
|
assert expected_message == translate_message(message, vars)
|
|
|
|
end
|
|
|
|
|
|
|
|
defp translate_message(message, vars) do
|
|
|
|
Enum.reduce(vars, message, fn {key, value}, acc ->
|
|
|
|
if String.contains?(acc, "%{#{key}}") do
|
|
|
|
String.replace(acc, "%{#{key}}", to_string(value))
|
|
|
|
else
|
|
|
|
acc
|
|
|
|
end
|
|
|
|
end)
|
|
|
|
end
|
|
|
|
end
|