mirror of
https://github.com/ash-project/ash.git
synced 2024-09-20 13:33:20 +12:00
9fc5ddfe2b
- Use the correct option key to select the field - Fail without hitting the data layer if the attribute is not changing - Allow checking relationships like the non-atomic counterpart
199 lines
5 KiB
Elixir
199 lines
5 KiB
Elixir
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
|