fix: run action changes on destroy

test: test manual actions
fix: pattern match manage_relationship notifications fix
This commit is contained in:
Zach Daniel 2021-05-09 16:56:44 -04:00
parent 7d37f8ae3d
commit 097447bf38
6 changed files with 107 additions and 7 deletions

View file

@ -222,8 +222,9 @@ defmodule Ash.Actions.Create do
|> add_tenant(changeset)
|> manage_relationships(api, changeset, engine_opts)
|> case do
{:ok, result} ->
{:ok, result, instructions}
{:ok, result, %{notifications: new_notifications}} ->
{:ok, result,
Map.update!(instructions, :notifications, &(&1 ++ new_notifications))}
{:error, error} ->
{:error, error}
@ -249,7 +250,7 @@ defmodule Ash.Actions.Create do
end
defp manage_relationships({:ok, nil}, _, _, _) do
{:ok, nil}
{:ok, nil, %{notifications: []}}
end
defp manage_relationships({:ok, created}, api, changeset, engine_opts) do

View file

@ -157,7 +157,7 @@ defmodule Ash.Actions.Update do
if changeset.valid? do
if action.manual? do
{:ok, nil}
{:ok, changeset.data}
else
resource
|> Ash.DataLayer.update(changeset)
@ -178,8 +178,9 @@ defmodule Ash.Actions.Update do
|> add_tenant(changeset)
|> manage_relationships(api, changeset, engine_opts)
|> case do
{:ok, data} ->
{:ok, data, instructions}
{:ok, data, %{notifications: new_notifications}} ->
{:ok, data,
Map.update!(instructions, :notifications, &(&1 ++ new_notifications))}
{:error, error} ->
{:error, error}

View file

@ -430,6 +430,7 @@ defmodule Ash.Changeset do
|> Map.put(:__validated_for_action__, action.name)
|> Map.put(:action, action)
|> cast_params(action, params, opts)
|> run_action_changes(action, opts[:actor])
|> add_validations()
|> mark_validated(action.name)
|> require_arguments(action)

View file

@ -90,6 +90,20 @@ defmodule Ash.Test.Actions.CreateTest do
end
end
defmodule ManualCreateAuthor do
@moduledoc false
use Ash.Resource.Change
def change(changeset, _, _) do
Ash.Changeset.after_action(changeset, fn _, nil ->
{:ok,
Ash.Test.Actions.CreateTest.Author
|> Ash.Changeset.for_create(:create, %{name: "manual"})
|> Ash.Test.Actions.CreateTest.Api.create!()}
end)
end
end
defmodule Author do
@moduledoc false
use Ash.Resource, data_layer: Ash.DataLayer.Ets
@ -110,6 +124,12 @@ defmodule Ash.Test.Actions.CreateTest do
change {DuplicateName, []}
end
create :manual_create do
accept []
manual? true
change ManualCreateAuthor
end
update :update
end
@ -328,6 +348,16 @@ defmodule Ash.Test.Actions.CreateTest do
end
end
describe "manual creates" do
test "the manual action succeeds" do
Author
|> Ash.Changeset.for_create(:manual_create)
|> Api.create!()
assert [%{name: "manual"}] = Api.read!(Author)
end
end
describe "require_attributes" do
test "it requires attributes that have a default" do
assert_raise Ash.Error.Invalid, ~r/attribute tag is required/, fn ->

View file

@ -29,6 +29,19 @@ defmodule Ash.Test.Actions.DestroyTest do
end
end
defmodule ManualDestroyAuthor do
@moduledoc false
use Ash.Resource.Change
def change(changeset, _, _) do
Ash.Changeset.after_action(changeset, fn _changeset, data ->
Ash.Test.Actions.DestroyTest.Api.destroy!(data)
{:ok, data}
end)
end
end
defmodule Author do
@moduledoc false
use Ash.Resource, data_layer: Ash.DataLayer.Ets, authorizers: [Ash.Test.Authorizer]
@ -41,7 +54,16 @@ defmodule Ash.Test.Actions.DestroyTest do
read :read
create :create
update :update
destroy :destroy
destroy :destroy do
primary? true
end
destroy :manual do
accept []
manual? true
change ManualDestroyAuthor
end
end
attributes do
@ -129,4 +151,17 @@ defmodule Ash.Test.Actions.DestroyTest do
assert Api.get!(Author, author.id)
end
end
describe "manual destroy" do
test "allows destroying a record" do
author =
Author
|> new(%{name: "foo"})
|> Api.create!()
assert Api.destroy!(author, action: :manual) == :ok
refute Api.get!(Author, author.id)
end
end
end

View file

@ -67,6 +67,21 @@ defmodule Ash.Test.Actions.UpdateTest do
end
end
defmodule ManualUpdateAuthor do
@moduledoc false
use Ash.Resource.Change
def change(changeset, _, _) do
Ash.Changeset.after_action(changeset, fn _changeset, data ->
{:ok,
data
|> Ash.Changeset.new()
|> Ash.Changeset.change_attribute(:name, "manual")
|> Ash.Test.Actions.UpdateTest.Api.update!()}
end)
end
end
defmodule Author do
@moduledoc false
use Ash.Resource, data_layer: Ash.DataLayer.Ets
@ -87,6 +102,12 @@ defmodule Ash.Test.Actions.UpdateTest do
update :duplicate_name do
change {DuplicateName, []}
end
update :manual_update do
accept []
manual? true
change ManualUpdateAuthor
end
end
attributes do
@ -188,6 +209,17 @@ defmodule Ash.Test.Actions.UpdateTest do
end
end
describe "manual updates" do
test "the update occurs properly" do
author =
Author
|> new(%{name: "auto"})
|> Api.create!()
assert %Author{name: "manual"} = author |> new() |> Api.update!(action: :manual_update)
end
end
describe "allow_nil?" do
test "it does not allow updating a value to `nil` when `allow_nil?: false`" do
profile =