2023-12-14 10:47:11 +13:00
|
|
|
defmodule Ash.Test.Resource.Validation.EmbeddedResourceTest do
|
|
|
|
@moduledoc false
|
|
|
|
|
|
|
|
use ExUnit.Case, async: true
|
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
alias Ash.Test.Domain, as: Domain
|
|
|
|
|
2023-12-14 10:47:11 +13:00
|
|
|
defmodule ActorAndAuthorizeMustBeInContext do
|
|
|
|
use Ash.Resource.Validation
|
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
def validate(changeset, _opts, _) do
|
2023-12-14 11:11:52 +13:00
|
|
|
case changeset.context do
|
|
|
|
%{private: %{actor: _, authorize?: _}} ->
|
|
|
|
:ok
|
|
|
|
|
|
|
|
_ ->
|
|
|
|
{:error, "not good"}
|
2023-12-14 10:47:11 +13:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
defmodule ActorAndAuthorizeMustBeInSourceContext do
|
|
|
|
use Ash.Resource.Validation
|
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
def validate(changeset, _opts, _) do
|
2023-12-14 11:11:52 +13:00
|
|
|
case changeset.context do
|
2023-12-29 07:25:49 +13:00
|
|
|
%{__source__: %{data: %{name: _}, context: %{private: %{actor: _, authorize?: _}}}} ->
|
2023-12-14 11:11:52 +13:00
|
|
|
:ok
|
|
|
|
|
|
|
|
_ ->
|
|
|
|
{:error, "not good"}
|
2023-12-14 10:47:11 +13:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-12-29 07:25:49 +13:00
|
|
|
defmodule SubSubEmbeddedResource do
|
2024-04-12 14:28:28 +12:00
|
|
|
use Ash.Resource, data_layer: :embedded
|
2023-12-29 07:25:49 +13:00
|
|
|
|
|
|
|
attributes do
|
|
|
|
uuid_primary_key :id
|
2024-03-28 09:06:40 +13:00
|
|
|
attribute :name, :string, allow_nil?: true, public?: true
|
2023-12-29 07:25:49 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
validations do
|
|
|
|
validate {ActorAndAuthorizeMustBeInSourceContext, []}
|
|
|
|
end
|
|
|
|
|
|
|
|
changes do
|
|
|
|
change fn changeset, _ ->
|
|
|
|
case changeset.context do
|
|
|
|
%{__source__: %{data: %{name: _}}, private: %{actor: _, authorize?: _}} ->
|
|
|
|
changeset
|
|
|
|
|
|
|
|
_ ->
|
|
|
|
Ash.Changeset.add_error(changeset, "uh oh!")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
defmodule SubEmbeddedResource do
|
2024-04-12 14:28:28 +12:00
|
|
|
use Ash.Resource, data_layer: :embedded
|
2023-12-29 07:25:49 +13:00
|
|
|
|
|
|
|
attributes do
|
|
|
|
uuid_primary_key :id
|
2024-03-28 09:06:40 +13:00
|
|
|
attribute :name, :string, allow_nil?: true, public?: true
|
|
|
|
attribute :sub_sub_embedded_resource, SubSubEmbeddedResource, public?: true
|
2023-12-29 07:25:49 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
validations do
|
|
|
|
validate {ActorAndAuthorizeMustBeInSourceContext, []}
|
|
|
|
end
|
|
|
|
|
|
|
|
changes do
|
|
|
|
change fn changeset, _ ->
|
|
|
|
case changeset.context do
|
|
|
|
%{__source__: %{data: %{name: _}}, private: %{actor: _, authorize?: _}} ->
|
|
|
|
changeset
|
|
|
|
|
|
|
|
_ ->
|
|
|
|
Ash.Changeset.add_error(changeset, "uh oh!")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-12-14 10:47:11 +13:00
|
|
|
defmodule EmbeddedResource do
|
2024-04-12 14:28:28 +12:00
|
|
|
use Ash.Resource, data_layer: :embedded
|
2023-12-14 10:47:11 +13:00
|
|
|
|
|
|
|
attributes do
|
|
|
|
uuid_primary_key :id
|
2024-03-28 09:06:40 +13:00
|
|
|
attribute :name, :string, allow_nil?: true, public?: true
|
|
|
|
|
|
|
|
attribute :sub_embedded_resources, {:array, SubEmbeddedResource},
|
|
|
|
allow_nil?: true,
|
|
|
|
public?: true
|
2023-12-14 10:47:11 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
validations do
|
|
|
|
validate {ActorAndAuthorizeMustBeInSourceContext, []}
|
|
|
|
end
|
|
|
|
|
|
|
|
changes do
|
|
|
|
change fn changeset, _ ->
|
2023-12-14 11:11:52 +13:00
|
|
|
case changeset.context do
|
2023-12-29 07:25:49 +13:00
|
|
|
%{__source__: %{data: %{name: _}}, private: %{actor: _, authorize?: _}} ->
|
2023-12-14 11:11:52 +13:00
|
|
|
changeset
|
|
|
|
|
|
|
|
_ ->
|
|
|
|
Ash.Changeset.add_error(changeset, "uh oh!")
|
2023-12-14 10:47:11 +13:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
defmodule Resource do
|
2024-03-28 09:06:40 +13:00
|
|
|
use Ash.Resource, domain: Domain, data_layer: Ash.DataLayer.Ets
|
2023-12-14 10:47:11 +13:00
|
|
|
|
|
|
|
attributes do
|
|
|
|
uuid_primary_key :id
|
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
attribute :embedded_resource, EmbeddedResource do
|
|
|
|
public?(true)
|
|
|
|
end
|
|
|
|
|
|
|
|
attribute :name, :string do
|
|
|
|
public?(true)
|
|
|
|
end
|
2023-12-14 10:47:11 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
actions do
|
2024-03-28 09:06:40 +13:00
|
|
|
default_accept :*
|
2023-12-14 10:47:11 +13:00
|
|
|
defaults [:read, :create]
|
|
|
|
default_accept [:embedded_resource]
|
|
|
|
|
|
|
|
update :update do
|
2024-04-26 14:18:38 +12:00
|
|
|
require_atomic? false
|
2023-12-14 10:47:11 +13:00
|
|
|
argument :embedded_resource_arg, EmbeddedResource, allow_nil?: false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
validations do
|
|
|
|
validate {ActorAndAuthorizeMustBeInContext, []}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
test "changeset during validation and changes includes actor, authorize and tenant for an embedded resource" do
|
|
|
|
# The embedded resource's validation will raise an error if the context is missing the actor or authorize? keys
|
2023-12-29 07:25:49 +13:00
|
|
|
params = %{
|
|
|
|
embedded_resource: %{
|
|
|
|
name: "anything will trigger a validation",
|
|
|
|
sub_embedded_resources: [%{name: "foo", sub_sub_embedded_resource: %{name: "bar"}}]
|
|
|
|
}
|
|
|
|
}
|
2023-12-14 11:11:52 +13:00
|
|
|
|
2024-01-20 04:49:26 +13:00
|
|
|
Resource
|
|
|
|
|> Ash.Changeset.for_create(:create, params,
|
|
|
|
actor: %{},
|
|
|
|
authorize?: true,
|
|
|
|
tenant: "one"
|
|
|
|
)
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.create!()
|
2023-12-14 10:47:11 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
test "changeset during validation and changes includes actor, authorize and tenant for an embedded resource used as an argument" do
|
|
|
|
# The embedded resource's validation will raise an error if the context is missing the actor or authorize? keys
|
2023-12-29 07:25:49 +13:00
|
|
|
params = %{
|
|
|
|
embedded_resource_arg: %{
|
|
|
|
name: "anything will trigger a validation",
|
|
|
|
sub_embedded_resources: [%{name: "foo", sub_sub_embedded_resource: %{name: "bar"}}]
|
|
|
|
}
|
|
|
|
}
|
2023-12-14 11:11:52 +13:00
|
|
|
|
|
|
|
assert {:ok, _} =
|
|
|
|
%Resource{}
|
|
|
|
|> Ash.Changeset.for_update(:update, params,
|
|
|
|
actor: %{},
|
|
|
|
authorize?: true,
|
|
|
|
tenant: "one"
|
|
|
|
)
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.update()
|
2023-12-14 10:47:11 +13:00
|
|
|
end
|
|
|
|
end
|