defmodule DecentralisedBookIndex.Generators do @moduledoc "Generators for tests" use Ash.Generator alias DecentralisedBookIndex.Metadata alias DecentralisedBookIndex.Accounts @doc """ Generates user changesets with the `:register_with_password` action. """ def user(opts \\ []) do changeset_generator( DecentralisedBookIndex.Accounts.User, :register_with_password, defaults: [ # Generates unique values using an auto-incrementing sequence # eg. `user1@example.com`, `user2@example.com`, etc. email: sequence(:user_email, &"user#{&1}@example.com"), password: "password", password_confirmation: "password" ], overrides: opts, after_action: fn user -> role = opts[:role] || :user Accounts.User.set_role!(user, role, authorize?: false) end, authorize?: false ) end def author(opts \\ []) do actor = opts[:actor] || once(:default_actor, fn -> generate(user(role: :moderator)) end) changeset_generator( Metadata.Author, :create, defaults: [ name: sequence(:name, &"Author #{&1}"), description: sequence(:name, &"Description #{&1}"), author_alias_registry_id: nil ], overrides: opts, actor: actor ) end @doc """ Generates a list of author roles. Example: > author_roles = author_roles() """ def author_roles(opts \\ []) do actor = opts[:actor] || once(:default_actor, fn -> generate(user(role: :moderator)) end) authors = opts[:authors] || for id <- 1..2 do generate(author(actor: actor)) #.id end count = min(opts[:count], length(authors)) for {order, author} <- Enum.zip(1..count, authors) do %{order: order, author_id: author.id, role: ""} end end def dbi_server(opts \\ []) do actor = opts[:actor] || once(:default_actor, fn -> generate(user(role: :admin)) end) url = opts[:url] || once(:default_actor, fn -> "http://localhost:4002" end) changeset_generator( Metadata.DBIServer, :create, defaults: [ name: sequence(:name, &"Server #{&1}"), url: url ], overrides: opts, actor: actor ) end @doc """ Generates a list of bids. Example: > bids = bids() """ def bids(opts \\ []) do actor = opts[:actor] || once(:default_actor, fn -> generate(user(role: :moderator)) end) count = opts[:count] || 2 types = ["isbn10", "isbn13", "asin"] if count > length(types), do: count = length(types) random_types = Enum.take_random(types, count) for {order, type} <- Enum.zip(1..count, random_types) do %{order: order, type: type, bid: "1234567890"} end end @doc """ Generates a publisher. """ def publisher(opts \\ []) do actor = opts[:actor] || once(:default_actor, fn -> generate(user(role: :moderator)) end) changeset_generator( Metadata.Publisher, :create, defaults: [ name: sequence(:name, &"Publisher #{&1}"), ], overrides: opts, actor: actor ) end @doc """ Generates a book. """ def book(opts \\ []) do actor = opts[:actor] || once(:default_actor, fn -> generate(user(role: :moderator)) end) bids = opts[:bids] || once(:default_bids, fn -> bids() end) authors = opts[:authors] || nil author_roles = opts[:author_roles] || once(:default_author_roles, fn -> author_roles(authors: authors) end) publisher_id = opts[:publisher_id] || once(:default_publisher, fn -> generate(publisher()).id end) related_book = opts[:related_book] || nil book_editions_registry_id = if related_book do related_book.book_editions_registry_id else nil end changeset_generator( Metadata.Book, :create, defaults: [ title: sequence(:name, &"Book #{&1}"), description: sequence(:description, &"Description #{&1}"), language: sequence(:language, &"Language #{&1}"), format: sequence(:format, &"Format #{&1}"), page_count: sequence(:page_count, &(abs(&1)+1)), published: sequence(:published, &Date.add(~D[2025-03-04], &1)), bids: bids, author_roles: author_roles, publisher_id: publisher_id, book_editions_registry_id: book_editions_registry_id, ], overrides: opts, actor: actor ) end end