mitgliederverwaltung/test/mv_web/member_live/index_test.exs
2025-10-30 16:42:19 +01:00

252 lines
8.1 KiB
Elixir
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

defmodule MvWeb.MemberLive.IndexTest do
use MvWeb.ConnCase, async: true
import Phoenix.LiveViewTest
require Ash.Query
test "shows translated title in German", %{conn: conn} do
conn = conn_with_oidc_user(conn)
conn = Plug.Test.init_test_session(conn, locale: "de")
{:ok, _view, html} = live(conn, "/members")
# Expected German title
assert html =~ "Mitglieder"
end
test "shows translated title in English", %{conn: conn} do
conn = conn_with_oidc_user(conn)
Gettext.put_locale(MvWeb.Gettext, "en")
{:ok, _view, html} = live(conn, "/members")
# Expected English title
assert html =~ "Members"
end
test "shows translated button text in German", %{conn: conn} do
conn = conn_with_oidc_user(conn)
conn = Plug.Test.init_test_session(conn, locale: "de")
{:ok, _view, html} = live(conn, "/members/new")
assert html =~ "Speichern"
end
test "shows translated button text in English", %{conn: conn} do
conn = conn_with_oidc_user(conn)
Gettext.put_locale(MvWeb.Gettext, "en")
{:ok, _view, html} = live(conn, "/members/new")
assert html =~ "Save"
end
test "shows translated flash message after creating a member in German", %{conn: conn} do
conn = conn_with_oidc_user(conn)
conn = Plug.Test.init_test_session(conn, locale: "de")
{:ok, form_view, _html} = live(conn, "/members/new")
form_data = %{
"member[first_name]" => "Max",
"member[last_name]" => "Mustermann",
"member[email]" => "max@example.com"
}
# Submit form and follow the redirect to get the flash message
{:ok, index_view, _html} =
form_view
|> form("#member-form", form_data)
|> render_submit()
|> follow_redirect(conn, "/members")
assert has_element?(index_view, "#flash-group", "Mitglied erstellt erfolgreich")
end
test "shows translated flash message after creating a member in English", %{conn: conn} do
conn = conn_with_oidc_user(conn)
{:ok, form_view, _html} = live(conn, "/members/new")
form_data = %{
"member[first_name]" => "Max",
"member[last_name]" => "Mustermann",
"member[email]" => "max@example.com"
}
# Submit form and follow the redirect to get the flash message
{:ok, index_view, _html} =
form_view
|> form("#member-form", form_data)
|> render_submit()
|> follow_redirect(conn, "/members")
assert has_element?(index_view, "#flash-group", "Member create successfully")
end
describe "sorting integration" do
test "clicking a column header toggles sort order and updates the URL", %{conn: conn} do
conn = conn_with_oidc_user(conn)
{:ok, view, _html} = live(conn, "/members")
# The component data test ids are built with the name of the field
# First click should sort ASC
view
|> element("[data-testid='email']")
|> render_click()
# The LiveView pushes a patch with the new query params
assert_patch(view, "/members?query=&sort_field=email&sort_order=asc")
# Second click toggles to DESC
view
|> element("[data-testid='email']")
|> render_click()
assert_patch(view, "/members?query=&sort_field=email&sort_order=desc")
end
test "clicking different column header resets order to ascending", %{conn: conn} do
conn = conn_with_oidc_user(conn)
{:ok, view, _html} = live(conn, "/members?sort_field=email&sort_order=desc")
# Click on a different column
view
|> element("[data-testid='first_name']")
|> render_click()
assert_patch(view, "/members?query=&sort_field=first_name&sort_order=asc")
end
test "all sortable columns work correctly", %{conn: conn} do
conn = conn_with_oidc_user(conn)
{:ok, view, _html} = live(conn, "/members")
# default ascending sorting with first name
assert has_element?(view, "[data-testid='first_name'][aria-label='ascending']")
sortable_fields = [
:email,
:street,
:house_number,
:postal_code,
:city,
:phone_number,
:join_date
]
for field <- sortable_fields do
view
|> element("[data-testid='#{field}']")
|> render_click()
assert_patch(view, "/members?query=&sort_field=#{field}&sort_order=asc")
end
end
test "sorting works with search query", %{conn: conn} do
conn = conn_with_oidc_user(conn)
{:ok, view, _html} = live(conn, "/members?query=test")
view
|> element("[data-testid='email']")
|> render_click()
assert_patch(view, "/members?query=test&sort_field=email&sort_order=asc")
end
test "sorting maintains search query when toggling order", %{conn: conn} do
conn = conn_with_oidc_user(conn)
{:ok, view, _html} = live(conn, "/members?query=test&sort_field=email&sort_order=asc")
view
|> element("[data-testid='email']")
|> render_click()
assert_patch(view, "/members?query=test&sort_field=email&sort_order=desc")
end
end
describe "URL param handling" do
test "handle_params reads sort query and applies it", %{conn: conn} do
conn = conn_with_oidc_user(conn)
{:ok, view, _html} = live(conn, "/members?query=&sort_field=email&sort_order=desc")
# Check that the sort state is correctly applied
assert has_element?(view, "[data-testid='email'][aria-label='descending']")
end
test "handle_params handles invalid sort field gracefully", %{conn: conn} do
conn = conn_with_oidc_user(conn)
{:ok, view, _html} = live(conn, "/members?query=&sort_field=invalid_field&sort_order=asc")
# Should not crash and should show default first name order
assert has_element?(view, "[data-testid='first_name'][aria-label='ascending']")
end
test "handle_params preserves search query with sort params", %{conn: conn} do
conn = conn_with_oidc_user(conn)
{:ok, view, _html} = live(conn, "/members?query=test&sort_field=email&sort_order=desc")
# Both search and sort should be preserved
assert has_element?(view, "[data-testid='email'][aria-label='descending']")
end
end
describe "search and sort integration" do
test "search maintains sort state", %{conn: conn} do
conn = conn_with_oidc_user(conn)
{:ok, view, _html} = live(conn, "/members?query=&sort_field=email&sort_order=desc")
# Perform search
view
|> element("[data-testid='search-input']")
|> render_change(%{value: "test"})
# Sort state should be maintained
assert has_element?(view, "[data-testid='email'][aria-label='descending']")
end
test "sort maintains search state", %{conn: conn} do
conn = conn_with_oidc_user(conn)
{:ok, view, _html} = live(conn, "/members?query=test&sort_field=email&sort_order=asc")
# Perform sort
view
|> element("[data-testid='email']")
|> render_click()
# Search state should be maintained
assert_patch(view, "/members?query=test&sort_field=email&sort_order=desc")
end
end
test "handle_info(:search_changed) updates assigns with search results", %{conn: conn} do
conn = conn_with_oidc_user(conn)
{:ok, view, _html} = live(conn, "/members")
send(view.pid, {:search_changed, "Friedrich"})
state = :sys.get_state(view.pid)
assert state.socket.assigns.query == "Friedrich"
assert is_list(state.socket.assigns.members)
end
test "can delete a member without error", %{conn: conn} do
# Create a test member first
{:ok, member} =
Mv.Membership.create_member(%{
first_name: "Test",
last_name: "User",
email: "test@example.com"
})
conn = conn_with_oidc_user(conn)
{:ok, index_view, _html} = live(conn, "/members")
# Verify the member is displayed
assert has_element?(index_view, "#members", "Test User")
# Click the delete link for this member
index_view
|> element("a", "Delete")
|> render_click()
# Verify the member is no longer displayed
refute has_element?(index_view, "#members", "Test User")
# Verify the member was actually deleted from the database
assert not (Mv.Membership.Member |> Ash.Query.filter(id == ^member.id) |> Ash.exists?())
end
end