ash/test/resource/validation/changing_test.exs

200 lines
5 KiB
Elixir
Raw Permalink Normal View History

defmodule Ash.Test.Resource.Validation.ChangingTest do
@moduledoc false
use ExUnit.Case, async: true
require Ash.Query
alias Ash.Test.Domain, as: Domain
defmodule Author do
use Ash.Resource, domain: Domain, data_layer: Ash.DataLayer.Ets
actions do
default_accept :*
defaults [:read, :destroy, create: :*, update: :*]
end
attributes do
uuid_primary_key :id
attribute :name, :string do
public?(true)
end
end
end
defmodule Comment do
use Ash.Resource, domain: Domain, data_layer: Ash.DataLayer.Ets
actions do
default_accept :*
defaults [:read, :destroy, create: :*, update: :*]
end
attributes do
uuid_primary_key :id
attribute :text, :string do
public?(true)
end
end
relationships do
belongs_to :post, Post
end
end
defmodule Post do
use Ash.Resource, domain: Domain, data_layer: Ash.DataLayer.Ets
actions do
default_accept :*
defaults [:read, :destroy, create: :*, update: :*]
update :ensure_order_changing do
accept([:order])
validate(changing(:order))
end
update :ensure_author_changing do
accept([:author_id])
validate(changing(:author))
end
update :ensure_comments_changing do
validate(changing(:comments))
end
end
attributes do
uuid_primary_key :id
attribute :title, :string do
public?(true)
end
attribute :order, :integer do
public?(true)
end
end
relationships do
belongs_to :author, Author, public?: true
has_many :comments, Comment, public?: true
end
end
describe "Ash.Resource.Validation.Changing" do
test "fails atomic validation if attribute is not changing" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "foo", order: 1})
|> Ash.create!()
assert_raise Ash.Error.Invalid, ~r/must be changing/, fn ->
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.bulk_update!(:ensure_order_changing, %{})
end
end
test "fails atomic validation if attribute is being set to the same value" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "foo", order: 1})
|> Ash.create!()
assert_raise Ash.Error.Invalid, ~r/must be changing/, fn ->
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.bulk_update!(:ensure_order_changing, %{order: 1})
end
end
test "succeeds atomic validation if attribute changing to another value" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "foo", order: 1})
|> Ash.create!()
assert %Ash.BulkResult{status: :success} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.bulk_update!(:ensure_order_changing, %{order: 2})
end
test "fails atomic validation if relationship is not changing" do
author =
Author
|> Ash.Changeset.for_create(:create, %{name: "fred"})
|> Ash.create!()
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "foo", author_id: author.id})
|> Ash.create!()
assert_raise Ash.Error.Invalid, ~r/must be changing/, fn ->
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.bulk_update!(:ensure_author_changing, %{})
end
end
test "fails atomic validation if relationship is being set to the same value" do
author =
Author
|> Ash.Changeset.for_create(:create, %{name: "fred"})
|> Ash.create!()
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "foo", author_id: author.id})
|> Ash.create!()
assert_raise Ash.Error.Invalid, ~r/must be changing/, fn ->
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.bulk_update!(:ensure_author_changing, %{author_id: author.id})
end
end
test "succeeds atomic validation if relationship is being set to another value" do
author1 =
Author
|> Ash.Changeset.for_create(:create, %{name: "fred"})
|> Ash.create!()
author2 =
Author
|> Ash.Changeset.for_create(:create, %{name: "george"})
|> Ash.create!()
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "foo", author_id: author1.id})
|> Ash.create!()
assert %Ash.BulkResult{status: :success} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.bulk_update!(:ensure_author_changing, %{author_id: author2.id})
end
test "returns not_atomic on has_many relationships" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "foo"})
|> Ash.create!()
assert_raise Ash.Error.Invalid, ~r/can't atomically check/, fn ->
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.bulk_update!(:ensure_comments_changing, %{}, return_errors?: true)
end
end
end
end