From 097447bf3894b9f7c3efb200cd18b365ceb724b3 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sun, 9 May 2021 16:56:44 -0400 Subject: [PATCH] fix: run action changes on destroy test: test manual actions fix: pattern match manage_relationship notifications fix --- lib/ash/actions/create.ex | 7 ++++--- lib/ash/actions/update.ex | 7 ++++--- lib/ash/changeset/changeset.ex | 1 + test/actions/create_test.exs | 30 +++++++++++++++++++++++++++ test/actions/destroy_test.exs | 37 +++++++++++++++++++++++++++++++++- test/actions/update_test.exs | 32 +++++++++++++++++++++++++++++ 6 files changed, 107 insertions(+), 7 deletions(-) diff --git a/lib/ash/actions/create.ex b/lib/ash/actions/create.ex index aa590413..6c2a5f38 100644 --- a/lib/ash/actions/create.ex +++ b/lib/ash/actions/create.ex @@ -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 diff --git a/lib/ash/actions/update.ex b/lib/ash/actions/update.ex index 0079a191..fa6a7aa0 100644 --- a/lib/ash/actions/update.ex +++ b/lib/ash/actions/update.ex @@ -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} diff --git a/lib/ash/changeset/changeset.ex b/lib/ash/changeset/changeset.ex index 5af88d75..7fdb9aec 100644 --- a/lib/ash/changeset/changeset.ex +++ b/lib/ash/changeset/changeset.ex @@ -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) diff --git a/test/actions/create_test.exs b/test/actions/create_test.exs index 7cff38f6..4225ebba 100644 --- a/test/actions/create_test.exs +++ b/test/actions/create_test.exs @@ -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 -> diff --git a/test/actions/destroy_test.exs b/test/actions/destroy_test.exs index 3e88acf0..dd1d9d6a 100644 --- a/test/actions/destroy_test.exs +++ b/test/actions/destroy_test.exs @@ -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 diff --git a/test/actions/update_test.exs b/test/actions/update_test.exs index 31e0dbcd..d05d5647 100644 --- a/test/actions/update_test.exs +++ b/test/actions/update_test.exs @@ -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 =