All checks were successful
continuous-integration/drone/push Build is passing
- Remove redundant setup blocks from member_live tests - Add build_unauthenticated_conn helper for AuthController tests - Add global setup in conn_case.ex
196 lines
5.1 KiB
Elixir
196 lines
5.1 KiB
Elixir
defmodule Mv.Fixtures do
|
|
@moduledoc """
|
|
Shared test fixtures for consistent test data creation.
|
|
|
|
This module provides factory functions for creating test data across
|
|
different test suites, ensuring consistency and reducing duplication.
|
|
"""
|
|
|
|
@doc """
|
|
Creates a member with default or custom attributes.
|
|
|
|
## Parameters
|
|
- `attrs` - Map or keyword list of attributes to override defaults
|
|
|
|
## Returns
|
|
- Member struct
|
|
|
|
## Examples
|
|
|
|
iex> member_fixture()
|
|
%Mv.Membership.Member{first_name: "Test", ...}
|
|
|
|
iex> member_fixture(%{first_name: "Alice", email: "alice@example.com"})
|
|
%Mv.Membership.Member{first_name: "Alice", email: "alice@example.com"}
|
|
|
|
"""
|
|
def member_fixture(attrs \\ %{}) do
|
|
attrs
|
|
|> Enum.into(%{
|
|
first_name: "Test",
|
|
last_name: "Member",
|
|
email: "test#{System.unique_integer([:positive])}@example.com"
|
|
})
|
|
|> Mv.Membership.create_member()
|
|
|> case do
|
|
{:ok, member} -> member
|
|
{:error, error} -> raise "Failed to create member: #{inspect(error)}"
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Creates a user with default or custom attributes.
|
|
|
|
## Parameters
|
|
- `attrs` - Map or keyword list of attributes to override defaults
|
|
|
|
## Returns
|
|
- User struct
|
|
|
|
## Examples
|
|
|
|
iex> user_fixture()
|
|
%Mv.Accounts.User{email: "user123@example.com"}
|
|
|
|
iex> user_fixture(%{email: "custom@example.com"})
|
|
%Mv.Accounts.User{email: "custom@example.com"}
|
|
|
|
"""
|
|
def user_fixture(attrs \\ %{}) do
|
|
attrs
|
|
|> Enum.into(%{
|
|
email: "user#{System.unique_integer([:positive])}@example.com"
|
|
})
|
|
|> Mv.Accounts.create_user()
|
|
|> case do
|
|
{:ok, user} -> user
|
|
{:error, error} -> raise "Failed to create user: #{inspect(error)}"
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Creates a user linked to a member.
|
|
|
|
## Parameters
|
|
- `user_attrs` - Map or keyword list of user attributes
|
|
- `member_attrs` - Map or keyword list of member attributes
|
|
|
|
## Returns
|
|
- Tuple of {user, member}
|
|
|
|
## Examples
|
|
|
|
iex> {user, member} = linked_user_member_fixture()
|
|
iex> user.member_id == member.id
|
|
true
|
|
|
|
"""
|
|
def linked_user_member_fixture(user_attrs \\ %{}, member_attrs \\ %{}) do
|
|
member = member_fixture(member_attrs)
|
|
|
|
user_attrs = Map.put(user_attrs, :member, %{id: member.id})
|
|
user = user_fixture(user_attrs)
|
|
|
|
{user, member}
|
|
end
|
|
|
|
@doc """
|
|
Creates a role with a specific permission set.
|
|
|
|
## Parameters
|
|
- `permission_set_name` - The permission set name (e.g., "admin", "read_only", "normal_user", "own_data")
|
|
|
|
## Returns
|
|
- Role struct
|
|
|
|
## Examples
|
|
|
|
iex> role_fixture("admin")
|
|
%Mv.Authorization.Role{permission_set_name: "admin", ...}
|
|
|
|
"""
|
|
def role_fixture(permission_set_name) do
|
|
role_name = "Test Role #{permission_set_name} #{System.unique_integer([:positive])}"
|
|
|
|
case Mv.Authorization.create_role(%{
|
|
name: role_name,
|
|
description: "Test role for #{permission_set_name}",
|
|
permission_set_name: permission_set_name
|
|
}) do
|
|
{:ok, role} -> role
|
|
{:error, error} -> raise "Failed to create role: #{inspect(error)}"
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Creates a user with a specific permission set (role).
|
|
|
|
## Parameters
|
|
- `permission_set_name` - The permission set name (e.g., "admin", "read_only", "normal_user", "own_data")
|
|
- `user_attrs` - Optional user attributes
|
|
|
|
## Returns
|
|
- User struct with role preloaded
|
|
|
|
## Examples
|
|
|
|
iex> admin_user = user_with_role_fixture("admin")
|
|
iex> admin_user.role.permission_set_name
|
|
"admin"
|
|
|
|
"""
|
|
def user_with_role_fixture(permission_set_name \\ "admin", user_attrs \\ %{}) do
|
|
# Create role with permission set
|
|
role = role_fixture(permission_set_name)
|
|
|
|
# Create user
|
|
{:ok, user} =
|
|
user_attrs
|
|
|> Enum.into(%{
|
|
email: "user#{System.unique_integer([:positive])}@example.com"
|
|
})
|
|
|> Mv.Accounts.create_user()
|
|
|
|
# Assign role to user
|
|
{:ok, user} =
|
|
user
|
|
|> Ash.Changeset.for_update(:update, %{})
|
|
|> Ash.Changeset.manage_relationship(:role, role, type: :append_and_remove)
|
|
|> Ash.update()
|
|
|
|
# Reload user with role preloaded (critical for authorization!)
|
|
{:ok, user_with_role} = Ash.load(user, :role, domain: Mv.Accounts)
|
|
user_with_role
|
|
end
|
|
|
|
@doc """
|
|
Creates a member with an actor (for use in tests with policies).
|
|
|
|
## Parameters
|
|
- `attrs` - Map or keyword list of attributes to override defaults
|
|
- `actor` - The actor (user) to use for authorization
|
|
|
|
## Returns
|
|
- Member struct
|
|
|
|
## Examples
|
|
|
|
iex> admin = user_with_role_fixture("admin")
|
|
iex> member_fixture_with_actor(%{first_name: "Alice"}, admin)
|
|
%Mv.Membership.Member{first_name: "Alice", ...}
|
|
|
|
"""
|
|
def member_fixture_with_actor(attrs \\ %{}, actor) do
|
|
attrs
|
|
|> Enum.into(%{
|
|
first_name: "Test",
|
|
last_name: "Member",
|
|
email: "test#{System.unique_integer([:positive])}@example.com"
|
|
})
|
|
|> Mv.Membership.create_member(actor: actor)
|
|
|> case do
|
|
{:ok, member} -> member
|
|
{:error, error} -> raise "Failed to create member: #{inspect(error)}"
|
|
end
|
|
end
|
|
end
|