test: add tdd tests for groups administration #372
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
parent
0a2aa3bad0
commit
f05fae3ea3
6 changed files with 962 additions and 4 deletions
209
test/mv_web/live/group_live/integration_test.exs
Normal file
209
test/mv_web/live/group_live/integration_test.exs
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
defmodule MvWeb.GroupLive.IntegrationTest do
|
||||
@moduledoc """
|
||||
Integration tests for complete group management workflows.
|
||||
|
||||
Tests cover:
|
||||
- Complete workflows (Create → View → Edit → Delete)
|
||||
- Slug-based navigation
|
||||
- Member-group associations
|
||||
- URL persistence
|
||||
"""
|
||||
use MvWeb.ConnCase, async: false
|
||||
import Phoenix.LiveViewTest
|
||||
require Ash.Query
|
||||
import Ash.Expr
|
||||
use Gettext, backend: MvWeb.Gettext
|
||||
|
||||
alias Mv.Membership
|
||||
alias Mv.Fixtures
|
||||
|
||||
describe "complete workflow" do
|
||||
test "create → view via slug → edit → view via slug (slug unchanged)", %{
|
||||
conn: conn,
|
||||
current_user: current_user
|
||||
} do
|
||||
# Create group
|
||||
{:ok, view, _html} = live(conn, "/groups/new")
|
||||
|
||||
form_data = %{
|
||||
"name" => "Workflow Test Group",
|
||||
"description" => "Initial description"
|
||||
}
|
||||
|
||||
view
|
||||
|> form("form", group: form_data)
|
||||
|> render_submit()
|
||||
|
||||
# Get the created group by name using current user (tests authorization)
|
||||
{:ok, groups} = Membership.list_groups(actor: current_user)
|
||||
group = Enum.find(groups, &(&1.name == "Workflow Test Group"))
|
||||
original_slug = group.slug
|
||||
|
||||
# View via slug
|
||||
{:ok, _view, html} = live(conn, "/groups/#{group.slug}")
|
||||
|
||||
assert html =~ "Workflow Test Group"
|
||||
assert html =~ "Initial description"
|
||||
|
||||
# Edit group
|
||||
{:ok, view, _html} = live(conn, "/groups/#{group.slug}/edit")
|
||||
|
||||
form_data = %{
|
||||
"name" => "Updated Workflow Test Group",
|
||||
"description" => "Updated description"
|
||||
}
|
||||
|
||||
view
|
||||
|> form("form", group: form_data)
|
||||
|> render_submit()
|
||||
|
||||
# View again via slug (should still work with original slug)
|
||||
{:ok, _view, html} = live(conn, "/groups/#{original_slug}")
|
||||
|
||||
assert html =~ "Updated Workflow Test Group"
|
||||
assert html =~ "Updated description"
|
||||
# Slug should remain unchanged
|
||||
assert html =~ original_slug || html =~ "workflow-test-group"
|
||||
end
|
||||
|
||||
test "create group → add members → view (member count updated)", %{
|
||||
conn: conn,
|
||||
current_user: current_user
|
||||
} do
|
||||
# Create group
|
||||
{:ok, view, _html} = live(conn, "/groups/new")
|
||||
|
||||
form_data = %{
|
||||
"name" => "Member Test Group"
|
||||
}
|
||||
|
||||
view
|
||||
|> form("form", group: form_data)
|
||||
|> render_submit()
|
||||
|
||||
# Get the created group using current user (tests authorization)
|
||||
{:ok, groups} = Membership.list_groups(actor: current_user)
|
||||
group = Enum.find(groups, &(&1.name == "Member Test Group"))
|
||||
|
||||
# Add members to group (use system_actor for test data setup)
|
||||
system_actor = Mv.Helpers.SystemActor.get_system_actor()
|
||||
member1 = Fixtures.member_fixture()
|
||||
member2 = Fixtures.member_fixture()
|
||||
|
||||
Membership.create_member_group(%{member_id: member1.id, group_id: group.id},
|
||||
actor: system_actor
|
||||
)
|
||||
|
||||
Membership.create_member_group(%{member_id: member2.id, group_id: group.id},
|
||||
actor: system_actor
|
||||
)
|
||||
|
||||
# View group via slug
|
||||
{:ok, _view, html} = live(conn, "/groups/#{group.slug}")
|
||||
|
||||
# Member count should be 2
|
||||
assert html =~ "2" || html =~ gettext("Members")
|
||||
assert html =~ member1.first_name || html =~ member1.last_name
|
||||
assert html =~ member2.first_name || html =~ member2.last_name
|
||||
end
|
||||
|
||||
test "create group → add members → delete (cascade works)", %{
|
||||
conn: conn,
|
||||
current_user: current_user
|
||||
} do
|
||||
# Create group
|
||||
{:ok, view, _html} = live(conn, "/groups/new")
|
||||
|
||||
form_data = %{
|
||||
"name" => "Delete Test Group"
|
||||
}
|
||||
|
||||
view
|
||||
|> form("form", group: form_data)
|
||||
|> render_submit()
|
||||
|
||||
# Get the created group using current user (tests authorization)
|
||||
{:ok, groups} = Membership.list_groups(actor: current_user)
|
||||
group = Enum.find(groups, &(&1.name == "Delete Test Group"))
|
||||
|
||||
# Add member to group (use system_actor for test data setup)
|
||||
system_actor = Mv.Helpers.SystemActor.get_system_actor()
|
||||
member = Fixtures.member_fixture()
|
||||
|
||||
Membership.create_member_group(%{member_id: member.id, group_id: group.id},
|
||||
actor: system_actor
|
||||
)
|
||||
|
||||
# Delete group (via UI - would need delete confirmation modal test)
|
||||
# For now, test via API that cascade works
|
||||
# Use current_user to test authorization (admin can delete)
|
||||
:ok = Membership.destroy_group(group, actor: current_user)
|
||||
|
||||
# Verify member still exists (use system_actor for verification - this is test verification, not user action)
|
||||
system_actor = Mv.Helpers.SystemActor.get_system_actor()
|
||||
{:ok, member_reloaded} = Ash.get(Mv.Membership.Member, member.id, actor: system_actor)
|
||||
assert member_reloaded != nil
|
||||
|
||||
# Verify member-group association is deleted
|
||||
{:ok, mgs} =
|
||||
Ash.read(
|
||||
Mv.Membership.MemberGroup
|
||||
|> Ash.Query.filter(expr(group_id == ^group.id)),
|
||||
actor: system_actor,
|
||||
domain: Mv.Membership
|
||||
)
|
||||
|
||||
assert mgs == []
|
||||
end
|
||||
end
|
||||
|
||||
describe "slug-based navigation" do
|
||||
test "links to group detail use slug (not ID)", %{conn: conn} do
|
||||
group = Fixtures.group_fixture(%{name: "Navigation Test Group"})
|
||||
|
||||
{:ok, _view, html} = live(conn, "/groups")
|
||||
|
||||
# Links should use slug, not UUID
|
||||
assert html =~ "/groups/#{group.slug}"
|
||||
refute html =~ "/groups/#{group.id}"
|
||||
end
|
||||
|
||||
test "deep links to group detail per slug work", %{conn: conn} do
|
||||
group = Fixtures.group_fixture(%{name: "Deep Link Test"})
|
||||
|
||||
# Direct navigation to slug URL
|
||||
{:ok, _view, html} = live(conn, "/groups/#{group.slug}")
|
||||
|
||||
assert html =~ "Deep Link Test"
|
||||
end
|
||||
|
||||
test "browser back button works correctly", %{conn: conn} do
|
||||
group = Fixtures.group_fixture()
|
||||
|
||||
# Navigate to group detail
|
||||
{:ok, _view1, _html} = live(conn, "/groups/#{group.slug}")
|
||||
|
||||
# Navigate to edit
|
||||
{:ok, view2, _html} = live(conn, "/groups/#{group.slug}/edit")
|
||||
|
||||
# Browser back should work (tested via navigation)
|
||||
assert view2 != nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "URL persistence" do
|
||||
test "slug-based URLs persist across page reloads", %{conn: conn} do
|
||||
group = Fixtures.group_fixture(%{name: "Persistent URL Test"})
|
||||
|
||||
# First visit
|
||||
{:ok, _view1, html1} = live(conn, "/groups/#{group.slug}")
|
||||
|
||||
assert html1 =~ "Persistent URL Test"
|
||||
|
||||
# Simulate page reload (new connection)
|
||||
{:ok, _view2, html2} = live(conn, "/groups/#{group.slug}")
|
||||
|
||||
assert html2 =~ "Persistent URL Test"
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue