125 lines
5.3 KiB
Elixir
125 lines
5.3 KiB
Elixir
defmodule Mv.SeedsTest do
|
|
@moduledoc """
|
|
Minimal test suite for database seeds.
|
|
|
|
This test suite focuses on critical deployment requirements:
|
|
- Seeds run without errors (smoke test)
|
|
- Seeds are idempotent (can be run multiple times)
|
|
- Critical bootstrap invariants are met (Admin user, system roles)
|
|
|
|
## Removed Tests
|
|
|
|
The following tests were removed to reduce test execution time.
|
|
Their functionality is covered by domain-specific tests:
|
|
|
|
- Member/fee type distribution tests → covered by `membership_fees/*_test.exs`
|
|
- Cycle status variation tests → covered by `membership_fees/cycle_generator_test.exs`
|
|
- Detailed role configuration tests → covered by `authorization/*_test.exs`
|
|
- Permission set validation → covered by `authorization/permission_sets_test.exs`
|
|
|
|
See `docs/test-optimization-seeds.md` for detailed rationale and coverage mapping.
|
|
"""
|
|
|
|
use Mv.DataCase, async: false
|
|
|
|
require Ash.Query
|
|
|
|
# Module attribute to track if seeds have been run
|
|
# This allows us to run seeds once per test module while respecting sandbox isolation
|
|
@seeds_run_key :seeds_test_run
|
|
|
|
setup do
|
|
system_actor = Mv.Helpers.SystemActor.get_system_actor()
|
|
|
|
# Run seeds once per test process (due to sandbox isolation, each test runs in its own process)
|
|
# Process.get/put ensures seeds are only executed once per test process, not once per test
|
|
# Note: With async: false and sandbox isolation, this effectively runs seeds once per test,
|
|
# but the guard prevents multiple executions within the same test process if setup is called multiple times
|
|
unless Process.get(@seeds_run_key) do
|
|
Code.eval_file("priv/repo/seeds.exs")
|
|
Process.put(@seeds_run_key, true)
|
|
end
|
|
|
|
%{actor: system_actor}
|
|
end
|
|
|
|
describe "Seeds script" do
|
|
test "runs successfully and creates basic data", %{actor: actor} do
|
|
# Smoke test: verify seeds created essential data structures
|
|
{:ok, users} = Ash.read(Mv.Accounts.User, actor: actor)
|
|
{:ok, members} = Ash.read(Mv.Membership.Member, actor: actor)
|
|
{:ok, custom_fields} = Ash.read(Mv.Membership.CustomField, actor: actor)
|
|
{:ok, roles} = Ash.read(Mv.Authorization.Role, domain: Mv.Authorization, authorize?: false)
|
|
|
|
assert not Enum.empty?(users), "Seeds should create at least one user"
|
|
assert not Enum.empty?(members), "Seeds should create at least one member"
|
|
assert not Enum.empty?(custom_fields), "Seeds should create at least one custom field"
|
|
assert length(roles) >= 5, "Seeds should create at least 5 authorization roles"
|
|
end
|
|
|
|
test "is idempotent when run multiple times", %{actor: actor} do
|
|
# Seeds already run once in setup - count current state
|
|
{:ok, users_count_1} = Ash.read(Mv.Accounts.User, actor: actor)
|
|
{:ok, members_count_1} = Ash.read(Mv.Membership.Member, actor: actor)
|
|
|
|
{:ok, roles_count_1} =
|
|
Ash.read(Mv.Authorization.Role, domain: Mv.Authorization, authorize?: false)
|
|
|
|
# Run seeds again - should not raise errors and should be idempotent
|
|
assert Code.eval_file("priv/repo/seeds.exs")
|
|
|
|
# Count records again - should be the same (upsert, not duplicate)
|
|
{:ok, users_count_2} = Ash.read(Mv.Accounts.User, actor: actor)
|
|
{:ok, members_count_2} = Ash.read(Mv.Membership.Member, actor: actor)
|
|
|
|
{:ok, roles_count_2} =
|
|
Ash.read(Mv.Authorization.Role, domain: Mv.Authorization, authorize?: false)
|
|
|
|
assert length(users_count_1) == length(users_count_2),
|
|
"Users count should remain same after re-running seeds"
|
|
|
|
assert length(members_count_1) == length(members_count_2),
|
|
"Members count should remain same after re-running seeds"
|
|
|
|
assert length(roles_count_1) == length(roles_count_2),
|
|
"Roles count should remain same after re-running seeds"
|
|
end
|
|
end
|
|
|
|
describe "Critical bootstrap invariants" do
|
|
test "Admin user has Admin role and can authenticate", %{actor: _actor} do
|
|
# Critical: Without this, initial system setup fails
|
|
admin_email = System.get_env("ADMIN_EMAIL") || "admin@localhost"
|
|
|
|
{:ok, admin_user} =
|
|
Mv.Accounts.User
|
|
|> Ash.Query.filter(email == ^admin_email)
|
|
|> Ash.read_one(domain: Mv.Accounts, authorize?: false)
|
|
|
|
assert admin_user != nil, "Admin user must exist after seeds run"
|
|
|
|
{:ok, admin_user_with_role} =
|
|
Ash.load(admin_user, :role, domain: Mv.Accounts, authorize?: false)
|
|
|
|
assert admin_user_with_role.role != nil, "Admin user must have a role assigned"
|
|
assert admin_user_with_role.role.name == "Admin", "Admin user must have Admin role"
|
|
|
|
assert admin_user_with_role.role.permission_set_name == "admin",
|
|
"Admin role must have admin permission set"
|
|
end
|
|
|
|
test "Mitglied system role exists and is correctly configured" do
|
|
# Critical: Default role for new users - system breaks without this
|
|
{:ok, mitglied} =
|
|
Mv.Authorization.Role
|
|
|> Ash.Query.filter(name == "Mitglied")
|
|
|> Ash.read_one(domain: Mv.Authorization, authorize?: false)
|
|
|
|
assert mitglied != nil, "Mitglied role must exist"
|
|
assert mitglied.is_system_role == true, "Mitglied role must be marked as system role"
|
|
|
|
assert mitglied.permission_set_name == "own_data",
|
|
"Mitglied role must have own_data permission set"
|
|
end
|
|
end
|
|
end
|