diff --git a/lib/decentralised_book_index/metadata/author.ex b/lib/decentralised_book_index/metadata/author.ex index 5f520e4..50e24b5 100644 --- a/lib/decentralised_book_index/metadata/author.ex +++ b/lib/decentralised_book_index/metadata/author.ex @@ -18,7 +18,7 @@ defmodule DecentralisedBookIndex.Metadata.Author do end actions do - defaults [:read, :update, :destroy] + defaults [:read, :destroy] create :create do primary? true @@ -62,6 +62,22 @@ defmodule DecentralisedBookIndex.Metadata.Author do end end + create :sync do + accept [:id, :name, :description, :author_alias_registry_id] + + change fn changeset, _ -> + registry_id = Ash.Changeset.get_attribute(changeset, :author_alias_registry_id) + + if registry_id == nil do + {:ok, registry} = DecentralisedBookIndex.Metadata.create_author_alias_registry() + + Ash.Changeset.force_change_attribute(changeset, :author_alias_registry_id, registry.id) + else + changeset + end + end + end + read :by_id do argument :id, :uuid, allow_nil?: false get? true @@ -109,13 +125,18 @@ defmodule DecentralisedBookIndex.Metadata.Author do pagination offset?: true, default_limit: 10 end + update :update do + primary? true + accept [:name, :description, :avatar_url] + end + update :assign_avatar_image do accept [:avatar_url] end end attributes do - uuid_primary_key :id + uuid_primary_key :id, writable?: true attribute :name, :string do allow_nil? false diff --git a/lib/decentralised_book_index/sync/sync/author_sync.ex b/lib/decentralised_book_index/sync/sync/author_sync.ex new file mode 100644 index 0000000..6bb6c70 --- /dev/null +++ b/lib/decentralised_book_index/sync/sync/author_sync.ex @@ -0,0 +1,25 @@ +defmodule DecentralisedBookIndex.Sync.AuthorSync do + alias DecentralisedBookIndex.Metadata.Author + + def create_update(author_attrs) do + case DecentralisedBookIndex.Metadata.get_author_by_id(author_attrs.id) do + {:ok, author} -> + author_attrs = + author_attrs + |> Map.delete(:id) + |> Map.delete(:author_alias_registry_id) + + author + |> Ash.Changeset.for_update(:update, author_attrs) + |> Ash.update!() + + :ok + {:error, %Ash.Error.Query.NotFound{}} -> + DecentralisedBookIndex.Metadata.Author + |> Ash.Changeset.for_create(:sync, author_attrs) + |> Ash.create!() + + :ok + end + end +end diff --git a/test/decentralised_book_index/sync/sync/author_sync_test.exs b/test/decentralised_book_index/sync/sync/author_sync_test.exs new file mode 100644 index 0000000..6f7ba5d --- /dev/null +++ b/test/decentralised_book_index/sync/sync/author_sync_test.exs @@ -0,0 +1,43 @@ +defmodule DecentralisedBookIndex.Sync.DataTransformers.AuthorSyncTest do + use DecentralisedBookIndex.DataCase, async: true + + alias DecentralisedBookIndex.Sync.AuthorSync + alias DecentralisedBookIndex.Metadata.Author + alias DecentralisedBookIndex.Metadata + + describe "sync author transformations" do + test "a new author will be created" do + author = %{ + id: "889a323e-d104-4b5d-b276-dad5a9b1da9d", + name: "Author", + description: "Something", + author_alias_registry_id: nil + } + + assert :ok = AuthorSync.create_update(author) + assert {:ok, saved_author} = Metadata.get_author_by_id(author.id) + + assert author.id == saved_author.id + assert author.name == saved_author.name + assert nil != saved_author.author_alias_registry_id + end + + test "update an existing author" do + {:ok, author} = Metadata.create_author("Author", "An description") + + author_attrs = %{ + id: author.id, + name: "Author2", + description: "Something2", + author_alias_registry_id: nil + } + + assert :ok = AuthorSync.create_update(author_attrs) + assert {:ok, saved_author} = Metadata.get_author_by_id(author.id) + + assert author.id == saved_author.id + assert author_attrs.name == saved_author.name + assert author_attrs.description == saved_author.description + end + end +end