mirror of
https://github.com/ash-project/ash.git
synced 2024-09-20 21:43:02 +12:00
9882037780
fixes #1220
162 lines
3.9 KiB
Elixir
162 lines
3.9 KiB
Elixir
defmodule Ash.Test.Actions.GenericActionsTest do
|
|
@moduledoc false
|
|
use ExUnit.Case, async: true
|
|
|
|
alias Ash.Test.Domain, as: Domain
|
|
|
|
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
|
|
use Ash.Resource,
|
|
domain: Domain,
|
|
data_layer: Ash.DataLayer.Ets,
|
|
authorizers: [Ash.Policy.Authorizer]
|
|
|
|
ets do
|
|
private?(true)
|
|
end
|
|
|
|
actions do
|
|
default_accept :*
|
|
defaults [:read, :destroy, create: :*, update: :*]
|
|
|
|
action :hello_with_default, :string do
|
|
argument :name, :string, allow_nil?: false, default: "default"
|
|
|
|
run(fn input, _context ->
|
|
{:ok, "Hello #{input.arguments.name}"}
|
|
end)
|
|
end
|
|
|
|
action :hello, :string do
|
|
argument :name, :string, allow_nil?: false
|
|
|
|
run(fn input, _context ->
|
|
{:ok, "Hello #{input.arguments.name}"}
|
|
end)
|
|
end
|
|
|
|
action :do_nothing do
|
|
run fn _, _ -> :ok end
|
|
end
|
|
end
|
|
|
|
attributes do
|
|
uuid_primary_key :id
|
|
attribute(:title, :string, allow_nil?: false, public?: true)
|
|
|
|
timestamps()
|
|
end
|
|
|
|
policies do
|
|
policy action(:hello) do
|
|
authorize_if PassingFredOrGeorge
|
|
end
|
|
|
|
policy action(:hello_with_default) do
|
|
authorize_if always()
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "generic actions can be called" do
|
|
test "generic actions can be run" do
|
|
assert "Hello fred" =
|
|
Post
|
|
|> Ash.ActionInput.for_action(:hello, %{name: "fred"})
|
|
|> Ash.run_action!()
|
|
end
|
|
|
|
test "generic actions validate their input" do
|
|
assert {:error, %Ash.Error.Invalid{}} =
|
|
Post
|
|
|> Ash.ActionInput.for_action(:hello, %{name: %{a: 10}})
|
|
|> Ash.run_action()
|
|
|
|
assert_raise Ash.Error.Invalid, ~r/Invalid Error/, fn ->
|
|
Post
|
|
|> Ash.ActionInput.for_action(:hello, %{name: %{a: 10}})
|
|
|> Ash.run_action!()
|
|
end
|
|
end
|
|
|
|
test "generic actions set default values for arguments" do
|
|
assert "Hello default" ==
|
|
Post
|
|
|> Ash.ActionInput.for_action(:hello_with_default, %{})
|
|
|> Ash.run_action!()
|
|
end
|
|
|
|
test "generic actions don't accept unknown keys" do
|
|
assert {:error, %Ash.Error.Invalid{}} =
|
|
Post
|
|
|> Ash.ActionInput.for_action(:hello, %{name: "fred", one: 1})
|
|
|> Ash.run_action()
|
|
|
|
assert_raise Ash.Error.Invalid, ~r/Invalid Error/, fn ->
|
|
Post
|
|
|> Ash.ActionInput.for_action(:hello, %{name: "fred", one: 1})
|
|
|> Ash.run_action!()
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "authorization" do
|
|
test "generic actions can be authorized" do
|
|
assert "Hello fred" =
|
|
Post
|
|
|> Ash.ActionInput.for_action(:hello, %{name: "fred"})
|
|
|> Ash.run_action!(authorize?: true)
|
|
|
|
assert_raise Ash.Error.Forbidden, ~r/Forbidden/, fn ->
|
|
Post
|
|
|> Ash.ActionInput.for_action(:hello, %{name: "mike"})
|
|
|> Ash.run_action!(authorize?: true)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "generic actions wrapping a reactor" do
|
|
defmodule EchoReactor do
|
|
@moduledoc false
|
|
use Reactor
|
|
|
|
input :input
|
|
|
|
step :echo do
|
|
argument :echo, input(:input)
|
|
run &Map.fetch(&1, :echo)
|
|
end
|
|
end
|
|
|
|
defmodule EchoResource do
|
|
@moduledoc false
|
|
use Ash.Resource, domain: Domain
|
|
|
|
actions do
|
|
action :echo, :string do
|
|
argument :input, :string, allow_nil?: false
|
|
|
|
run EchoReactor
|
|
end
|
|
end
|
|
|
|
code_interface do
|
|
define :echo, args: [:input]
|
|
end
|
|
end
|
|
|
|
test "it automatically runs the reactor" do
|
|
assert {:ok, "Marty"} = EchoResource.echo("Marty")
|
|
end
|
|
end
|
|
end
|