2023-05-03 12:00:18 +12:00
|
|
|
defmodule Ash.Test.Actions.GenericActionsTest do
|
2023-05-02 17:54:53 +12:00
|
|
|
@moduledoc false
|
|
|
|
use ExUnit.Case, async: true
|
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
alias Ash.Test.Domain, as: Domain
|
|
|
|
|
2023-05-02 17:54:53 +12:00
|
|
|
defmodule PassingFredOrGeorge do
|
|
|
|
use Ash.Policy.SimpleCheck
|
|
|
|
|
|
|
|
def describe(_), do: "is one of the twins"
|
|
|
|
|
|
|
|
def match?(_, %{action_input: action_input}, _) do
|
|
|
|
String.downcase(action_input.arguments.name) in ["fred", "george"]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
defmodule Post do
|
|
|
|
@moduledoc false
|
2024-03-28 09:06:40 +13:00
|
|
|
use Ash.Resource,
|
|
|
|
domain: Domain,
|
|
|
|
data_layer: Ash.DataLayer.Ets,
|
|
|
|
authorizers: [Ash.Policy.Authorizer]
|
2023-05-02 17:54:53 +12:00
|
|
|
|
|
|
|
ets do
|
|
|
|
private?(true)
|
|
|
|
end
|
|
|
|
|
|
|
|
actions do
|
2024-03-28 09:06:40 +13:00
|
|
|
default_accept :*
|
|
|
|
defaults [:read, :destroy, create: :*, update: :*]
|
2023-05-02 17:54:53 +12:00
|
|
|
|
|
|
|
action :hello, :string do
|
|
|
|
argument :name, :string, allow_nil?: false
|
|
|
|
|
|
|
|
run(fn input, _context ->
|
|
|
|
{:ok, "Hello #{input.arguments.name}"}
|
|
|
|
end)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
attributes do
|
|
|
|
uuid_primary_key :id
|
2024-03-28 09:06:40 +13:00
|
|
|
attribute(:title, :string, allow_nil?: false, public?: true)
|
2023-05-02 17:54:53 +12:00
|
|
|
|
|
|
|
timestamps()
|
|
|
|
end
|
|
|
|
|
|
|
|
policies do
|
|
|
|
policy action(:hello) do
|
|
|
|
authorize_if PassingFredOrGeorge
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-05-03 12:00:18 +12:00
|
|
|
describe "generic actions can be called" do
|
|
|
|
test "generic actions can be run" do
|
2023-05-02 17:54:53 +12:00
|
|
|
assert "Hello fred" =
|
|
|
|
Post
|
|
|
|
|> Ash.ActionInput.for_action(:hello, %{name: "fred"})
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.run_action!()
|
2023-05-02 17:54:53 +12:00
|
|
|
end
|
2023-05-02 18:07:53 +12:00
|
|
|
|
2023-05-03 12:00:18 +12:00
|
|
|
test "generic actions validate their input" do
|
2023-05-02 18:07:53 +12:00
|
|
|
assert {:error, %Ash.Error.Invalid{}} =
|
|
|
|
Post
|
|
|
|
|> Ash.ActionInput.for_action(:hello, %{name: %{a: 10}})
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.run_action()
|
2023-05-02 18:07:53 +12:00
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
assert_raise Ash.Error.Invalid, ~r/Invalid Error/, fn ->
|
2023-05-02 18:07:53 +12:00
|
|
|
Post
|
|
|
|
|> Ash.ActionInput.for_action(:hello, %{name: %{a: 10}})
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.run_action!()
|
2023-05-02 18:07:53 +12:00
|
|
|
end
|
|
|
|
end
|
2023-10-25 05:27:33 +13:00
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
test "generic actions don't accept unknown keys" do
|
2023-10-25 05:27:33 +13:00
|
|
|
assert {:error, %Ash.Error.Invalid{}} =
|
|
|
|
Post
|
|
|
|
|> Ash.ActionInput.for_action(:hello, %{name: "fred", one: 1})
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.run_action()
|
2023-10-25 05:27:33 +13:00
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
assert_raise Ash.Error.Invalid, ~r/Invalid Error/, fn ->
|
2023-10-25 05:27:33 +13:00
|
|
|
Post
|
|
|
|
|> Ash.ActionInput.for_action(:hello, %{name: "fred", one: 1})
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.run_action!()
|
2023-10-25 05:27:33 +13:00
|
|
|
end
|
|
|
|
end
|
2023-05-02 17:54:53 +12:00
|
|
|
end
|
|
|
|
|
|
|
|
describe "authorization" do
|
2023-05-03 12:00:18 +12:00
|
|
|
test "generic actions can be authorized" do
|
2023-05-02 17:54:53 +12:00
|
|
|
assert "Hello fred" =
|
|
|
|
Post
|
|
|
|
|> Ash.ActionInput.for_action(:hello, %{name: "fred"})
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.run_action!(authorize?: true)
|
2023-05-02 17:54:53 +12:00
|
|
|
|
|
|
|
assert_raise Ash.Error.Forbidden, ~r/Forbidden/, fn ->
|
|
|
|
Post
|
|
|
|
|> Ash.ActionInput.for_action(:hello, %{name: "mike"})
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.run_action!(authorize?: true)
|
2023-05-02 17:54:53 +12:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|