mirror of
https://github.com/ash-project/ash_postgres.git
synced 2024-09-19 13:03:14 +12:00
test validation aggregates individually as well (#360)
* test aggregates individually as well * test with atomic and non atomic actions * test atomic and non atomic actions * use message in context
This commit is contained in:
parent
9e4efa7b9b
commit
306dc84ac2
2 changed files with 93 additions and 29 deletions
|
@ -294,7 +294,15 @@ defmodule AshPostgres.AtomicsTest do
|
||||||
|> Map.get(:records)
|
|> Map.get(:records)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "can use aggregates in validation" do
|
Enum.each(
|
||||||
|
[
|
||||||
|
:exists,
|
||||||
|
:list,
|
||||||
|
:count,
|
||||||
|
:combined
|
||||||
|
],
|
||||||
|
fn aggregate ->
|
||||||
|
test "can use #{aggregate} in validation" do
|
||||||
post =
|
post =
|
||||||
Post
|
Post
|
||||||
|> Ash.Changeset.for_create(:create, %{title: "foo", price: 1})
|
|> Ash.Changeset.for_create(:create, %{title: "foo", price: 1})
|
||||||
|
@ -304,16 +312,38 @@ defmodule AshPostgres.AtomicsTest do
|
||||||
|> Ash.Changeset.for_create(:create, %{post_id: post.id, title: "foo"})
|
|> Ash.Changeset.for_create(:create, %{post_id: post.id, title: "foo"})
|
||||||
|> Ash.create!()
|
|> Ash.create!()
|
||||||
|
|
||||||
assert_raise Ash.Error.Invalid, ~r/Can only delete if Post has no comments/, fn ->
|
assert_raise Ash.Error.Invalid, ~r/Can only update if Post has no comments/, fn ->
|
||||||
post
|
post
|
||||||
|
|> Ash.Changeset.new()
|
||||||
|
|> Ash.Changeset.put_context(:aggregate, unquote(aggregate))
|
||||||
|> Ash.Changeset.for_update(:update_if_no_comments, %{title: "bar"})
|
|> Ash.Changeset.for_update(:update_if_no_comments, %{title: "bar"})
|
||||||
|> Ash.update!()
|
|> Ash.update!()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
assert_raise Ash.Error.Invalid, ~r/Can only update if Post has no comments/, fn ->
|
||||||
|
post
|
||||||
|
|> Ash.Changeset.new()
|
||||||
|
|> Ash.Changeset.put_context(:aggregate, unquote(aggregate))
|
||||||
|
|> Ash.Changeset.for_update(:update_if_no_comments_non_atomic, %{title: "bar"})
|
||||||
|
|> Ash.update!()
|
||||||
|
end
|
||||||
|
|
||||||
assert_raise Ash.Error.Invalid, ~r/Can only delete if Post has no comments/, fn ->
|
assert_raise Ash.Error.Invalid, ~r/Can only delete if Post has no comments/, fn ->
|
||||||
post
|
post
|
||||||
|
|> Ash.Changeset.new()
|
||||||
|
|> Ash.Changeset.put_context(:aggregate, unquote(aggregate))
|
||||||
|
|> Ash.Changeset.for_destroy(:destroy_if_no_comments_non_atomic, %{})
|
||||||
|
|> Ash.destroy!()
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_raise Ash.Error.Invalid, ~r/Can only delete if Post has no comments/, fn ->
|
||||||
|
post
|
||||||
|
|> Ash.Changeset.new()
|
||||||
|
|> Ash.Changeset.put_context(:aggregate, unquote(aggregate))
|
||||||
|> Ash.Changeset.for_destroy(:destroy_if_no_comments, %{})
|
|> Ash.Changeset.for_destroy(:destroy_if_no_comments, %{})
|
||||||
|> Ash.destroy!()
|
|> Ash.destroy!()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
|
@ -17,18 +17,32 @@ defmodule HasNoComments do
|
||||||
@moduledoc false
|
@moduledoc false
|
||||||
use Ash.Resource.Validation
|
use Ash.Resource.Validation
|
||||||
|
|
||||||
def atomic(_changeset, _opts, _context) do
|
def atomic(changeset, _opts, context) do
|
||||||
# Test multiple types of aggregates in a single validation
|
# Test multiple types of aggregates in a single validation
|
||||||
[
|
condition =
|
||||||
{:atomic, [],
|
case changeset.context.aggregate do
|
||||||
|
:exists ->
|
||||||
|
expr(exists(comments, true))
|
||||||
|
|
||||||
|
:list ->
|
||||||
|
expr(length(list(comments, field: :id)) > 0)
|
||||||
|
|
||||||
|
:count ->
|
||||||
|
expr(count(comments) > 0)
|
||||||
|
|
||||||
|
:combined ->
|
||||||
expr(
|
expr(
|
||||||
length(list(comments, field: :id)) > 0 or
|
exists(comments, true) and
|
||||||
count(comments) > 0 or
|
length(list(comments, field: :id)) > 0 and
|
||||||
exists(comments, true)
|
count(comments) > 0
|
||||||
),
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
[
|
||||||
|
{:atomic, [], condition,
|
||||||
expr(
|
expr(
|
||||||
error(^Ash.Error.Changes.InvalidChanges, %{
|
error(^Ash.Error.Changes.InvalidChanges, %{
|
||||||
message: "Can only delete if Post has no comments"
|
message: ^context.message || "Post has comments"
|
||||||
})
|
})
|
||||||
)}
|
)}
|
||||||
]
|
]
|
||||||
|
@ -115,11 +129,31 @@ defmodule AshPostgres.Test.Post do
|
||||||
end
|
end
|
||||||
|
|
||||||
destroy :destroy_if_no_comments do
|
destroy :destroy_if_no_comments do
|
||||||
validate(HasNoComments)
|
validate HasNoComments do
|
||||||
|
message "Can only delete if Post has no comments"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
update :update_if_no_comments do
|
update :update_if_no_comments do
|
||||||
validate(HasNoComments)
|
validate HasNoComments do
|
||||||
|
message "Can only update if Post has no comments"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
destroy :destroy_if_no_comments_non_atomic do
|
||||||
|
require_atomic?(false)
|
||||||
|
|
||||||
|
validate HasNoComments do
|
||||||
|
message "Can only delete if Post has no comments"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
update :update_if_no_comments_non_atomic do
|
||||||
|
require_atomic?(false)
|
||||||
|
|
||||||
|
validate HasNoComments do
|
||||||
|
message "Can only update if Post has no comments"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
update :update_only_freds do
|
update :update_only_freds do
|
||||||
|
|
Loading…
Reference in a new issue