tests: added tests
This commit is contained in:
parent
d039e4bb7d
commit
45a9bc0cc0
4 changed files with 1554 additions and 0 deletions
|
|
@ -0,0 +1,363 @@
|
|||
defmodule MvWeb.Components.FieldVisibilityDropdownComponentTest do
|
||||
@moduledoc """
|
||||
Tests for FieldVisibilityDropdownComponent LiveComponent.
|
||||
"""
|
||||
use MvWeb.ConnCase, async: true
|
||||
|
||||
import Phoenix.LiveViewTest
|
||||
|
||||
alias MvWeb.Components.FieldVisibilityDropdownComponent
|
||||
|
||||
# Helper to create test assigns
|
||||
defp create_assigns(overrides \\ %{}) do
|
||||
default_assigns = %{
|
||||
id: "test-dropdown",
|
||||
all_fields: [:first_name, :email, :street, "custom_field_123"],
|
||||
custom_fields: [
|
||||
%{id: "123", name: "Custom Field 1"}
|
||||
],
|
||||
selected_fields: %{
|
||||
"first_name" => true,
|
||||
"email" => true,
|
||||
"street" => false,
|
||||
"custom_field_123" => true
|
||||
}
|
||||
}
|
||||
|
||||
Map.merge(default_assigns, overrides)
|
||||
end
|
||||
|
||||
describe "update/2" do
|
||||
test "initializes with default values" do
|
||||
assigns = create_assigns()
|
||||
|
||||
{:ok, socket} = FieldVisibilityDropdownComponent.update(assigns, %{})
|
||||
|
||||
assert socket.assigns.id == "test-dropdown"
|
||||
assert socket.assigns.open == false
|
||||
assert socket.assigns.all_fields == assigns.all_fields
|
||||
assert socket.assigns.selected_fields == assigns.selected_fields
|
||||
end
|
||||
|
||||
test "preserves existing open state" do
|
||||
assigns = create_assigns()
|
||||
existing_socket = %{assigns: %{open: true}}
|
||||
|
||||
{:ok, socket} = FieldVisibilityDropdownComponent.update(assigns, existing_socket)
|
||||
|
||||
assert socket.assigns.open == true
|
||||
end
|
||||
|
||||
test "handles missing optional assigns" do
|
||||
minimal_assigns = %{id: "test"}
|
||||
|
||||
{:ok, socket} = FieldVisibilityDropdownComponent.update(minimal_assigns, %{})
|
||||
|
||||
assert socket.assigns.all_fields == []
|
||||
assert socket.assigns.custom_fields == []
|
||||
assert socket.assigns.selected_fields == %{}
|
||||
end
|
||||
end
|
||||
|
||||
describe "render/1" do
|
||||
test "renders dropdown button" do
|
||||
assigns = create_assigns()
|
||||
|
||||
html = render_component(FieldVisibilityDropdownComponent, assigns)
|
||||
|
||||
assert html =~ "Columns"
|
||||
assert html =~ "hero-adjustments-horizontal"
|
||||
assert has_element?(html, "button[aria-controls='field-visibility-menu']")
|
||||
end
|
||||
|
||||
test "renders dropdown menu when open" do
|
||||
assigns = create_assigns() |> Map.put(:open, true)
|
||||
|
||||
html = render_component(FieldVisibilityDropdownComponent, assigns)
|
||||
|
||||
assert has_element?(html, "ul#field-visibility-menu")
|
||||
assert html =~ "All"
|
||||
assert html =~ "None"
|
||||
end
|
||||
|
||||
test "does not render menu when closed" do
|
||||
assigns = create_assigns() |> Map.put(:open, false)
|
||||
|
||||
html = render_component(FieldVisibilityDropdownComponent, assigns)
|
||||
|
||||
refute has_element?(html, "ul#field-visibility-menu")
|
||||
end
|
||||
|
||||
test "renders member fields" do
|
||||
assigns = create_assigns() |> Map.put(:open, true)
|
||||
|
||||
html = render_component(FieldVisibilityDropdownComponent, assigns)
|
||||
|
||||
# Field names should be formatted (first_name -> First Name)
|
||||
assert html =~ "First Name" or html =~ "first_name"
|
||||
assert html =~ "Email" or html =~ "email"
|
||||
assert html =~ "Street" or html =~ "street"
|
||||
end
|
||||
|
||||
test "renders custom fields when custom fields exist" do
|
||||
assigns = create_assigns() |> Map.put(:open, true)
|
||||
|
||||
html = render_component(FieldVisibilityDropdownComponent, assigns)
|
||||
|
||||
# Custom field name
|
||||
assert html =~ "Custom Field 1"
|
||||
end
|
||||
|
||||
test "renders checkboxes with correct checked state" do
|
||||
assigns = create_assigns() |> Map.put(:open, true)
|
||||
|
||||
html = render_component(FieldVisibilityDropdownComponent, assigns)
|
||||
|
||||
# first_name should be checked (aria-checked="true")
|
||||
assert html =~ ~s(aria-checked="true")
|
||||
assert html =~ ~s(phx-value-item="first_name")
|
||||
|
||||
# street should not be checked (aria-checked="false")
|
||||
assert html =~ ~s(phx-value-item="street")
|
||||
# Note: The visual checkbox state is handled by CSS classes and aria-checked attribute
|
||||
end
|
||||
|
||||
test "includes accessibility attributes" do
|
||||
assigns = create_assigns() |> Map.put(:open, true)
|
||||
|
||||
html = render_component(FieldVisibilityDropdownComponent, assigns)
|
||||
|
||||
assert html =~ ~s(aria-controls="field-visibility-menu")
|
||||
assert html =~ ~s(aria-haspopup="menu")
|
||||
assert html =~ ~s(role="button")
|
||||
assert html =~ ~s(role="menu")
|
||||
assert html =~ ~s(role="menuitemcheckbox")
|
||||
end
|
||||
|
||||
test "formats member field labels correctly" do
|
||||
assigns = create_assigns() |> Map.put(:open, true)
|
||||
|
||||
html = render_component(FieldVisibilityDropdownComponent, assigns)
|
||||
|
||||
# Field names should be formatted (first_name -> First Name)
|
||||
assert html =~ "First Name" or html =~ "first_name"
|
||||
end
|
||||
|
||||
test "uses custom field names from custom_fields prop" do
|
||||
assigns =
|
||||
create_assigns()
|
||||
|> Map.put(:open, true)
|
||||
|> Map.put(:custom_fields, [
|
||||
%{id: "123", name: "Membership Number"}
|
||||
])
|
||||
|
||||
html = render_component(FieldVisibilityDropdownComponent, assigns)
|
||||
|
||||
assert html =~ "Membership Number"
|
||||
end
|
||||
|
||||
test "falls back to ID when custom field not found" do
|
||||
assigns =
|
||||
create_assigns()
|
||||
|> Map.put(:open, true)
|
||||
# Empty custom fields list
|
||||
|> Map.put(:custom_fields, [])
|
||||
|
||||
html = render_component(FieldVisibilityDropdownComponent, assigns)
|
||||
|
||||
# Should show something like "Custom Field 123"
|
||||
assert html =~ "custom_field_123" or html =~ "Custom Field"
|
||||
end
|
||||
end
|
||||
|
||||
describe "handle_event/2" do
|
||||
test "toggle_dropdown toggles open state" do
|
||||
assigns = create_assigns()
|
||||
{:ok, socket} = FieldVisibilityDropdownComponent.update(assigns, %{})
|
||||
|
||||
assert socket.assigns.open == false
|
||||
|
||||
{:noreply, socket} =
|
||||
FieldVisibilityDropdownComponent.handle_event("toggle_dropdown", %{}, socket)
|
||||
|
||||
assert socket.assigns.open == true
|
||||
|
||||
{:noreply, socket} =
|
||||
FieldVisibilityDropdownComponent.handle_event("toggle_dropdown", %{}, socket)
|
||||
|
||||
assert socket.assigns.open == false
|
||||
end
|
||||
|
||||
test "close_dropdown sets open to false" do
|
||||
assigns = create_assigns()
|
||||
{:ok, socket} = FieldVisibilityDropdownComponent.update(assigns, %{})
|
||||
socket = assign(socket, :open, true)
|
||||
|
||||
{:noreply, socket} =
|
||||
FieldVisibilityDropdownComponent.handle_event("close_dropdown", %{}, socket)
|
||||
|
||||
assert socket.assigns.open == false
|
||||
end
|
||||
|
||||
test "select_item toggles field visibility" do
|
||||
assigns = create_assigns()
|
||||
{:ok, socket} = FieldVisibilityDropdownComponent.update(assigns, %{})
|
||||
|
||||
assert socket.assigns.selected_fields["first_name"] == true
|
||||
|
||||
{:noreply, socket} =
|
||||
FieldVisibilityDropdownComponent.handle_event(
|
||||
"select_item",
|
||||
%{"item" => "first_name"},
|
||||
socket
|
||||
)
|
||||
|
||||
assert socket.assigns.selected_fields["first_name"] == false
|
||||
|
||||
{:noreply, socket} =
|
||||
FieldVisibilityDropdownComponent.handle_event(
|
||||
"select_item",
|
||||
%{"item" => "first_name"},
|
||||
socket
|
||||
)
|
||||
|
||||
assert socket.assigns.selected_fields["first_name"] == true
|
||||
end
|
||||
|
||||
test "select_item defaults to true for missing fields" do
|
||||
assigns = create_assigns()
|
||||
{:ok, socket} = FieldVisibilityDropdownComponent.update(assigns, %{})
|
||||
|
||||
{:noreply, socket} =
|
||||
FieldVisibilityDropdownComponent.handle_event(
|
||||
"select_item",
|
||||
%{"item" => "new_field"},
|
||||
socket
|
||||
)
|
||||
|
||||
# Toggled from default true
|
||||
assert socket.assigns.selected_fields["new_field"] == false
|
||||
end
|
||||
|
||||
test "select_item sends message to parent" do
|
||||
assigns = create_assigns()
|
||||
{:ok, socket} = FieldVisibilityDropdownComponent.update(assigns, %{})
|
||||
|
||||
FieldVisibilityDropdownComponent.handle_event(
|
||||
"select_item",
|
||||
%{"item" => "first_name"},
|
||||
socket
|
||||
)
|
||||
|
||||
# Check that message was sent (would be verified in integration test)
|
||||
# For unit test, we just verify the state change
|
||||
assert_receive {:field_toggled, "first_name", false}
|
||||
end
|
||||
|
||||
test "select_all sets all fields to true" do
|
||||
assigns = create_assigns()
|
||||
{:ok, socket} = FieldVisibilityDropdownComponent.update(assigns, %{})
|
||||
|
||||
{:noreply, socket} =
|
||||
FieldVisibilityDropdownComponent.handle_event("select_all", %{}, socket)
|
||||
|
||||
assert socket.assigns.selected_fields["first_name"] == true
|
||||
assert socket.assigns.selected_fields["email"] == true
|
||||
assert socket.assigns.selected_fields["street"] == true
|
||||
assert socket.assigns.selected_fields["custom_field_123"] == true
|
||||
end
|
||||
|
||||
test "select_all sends message to parent" do
|
||||
assigns = create_assigns()
|
||||
{:ok, socket} = FieldVisibilityDropdownComponent.update(assigns, %{})
|
||||
|
||||
FieldVisibilityDropdownComponent.handle_event("select_all", %{}, socket)
|
||||
|
||||
assert_receive {:fields_selected, selection}
|
||||
assert selection["first_name"] == true
|
||||
assert selection["email"] == true
|
||||
end
|
||||
|
||||
test "select_none sets all fields to false" do
|
||||
assigns = create_assigns()
|
||||
{:ok, socket} = FieldVisibilityDropdownComponent.update(assigns, %{})
|
||||
|
||||
{:noreply, socket} =
|
||||
FieldVisibilityDropdownComponent.handle_event("select_none", %{}, socket)
|
||||
|
||||
assert socket.assigns.selected_fields["first_name"] == false
|
||||
assert socket.assigns.selected_fields["email"] == false
|
||||
assert socket.assigns.selected_fields["street"] == false
|
||||
assert socket.assigns.selected_fields["custom_field_123"] == false
|
||||
end
|
||||
|
||||
test "select_none sends message to parent" do
|
||||
assigns = create_assigns()
|
||||
{:ok, socket} = FieldVisibilityDropdownComponent.update(assigns, %{})
|
||||
|
||||
FieldVisibilityDropdownComponent.handle_event("select_none", %{}, socket)
|
||||
|
||||
assert_receive {:fields_selected, selection}
|
||||
assert selection["first_name"] == false
|
||||
assert selection["email"] == false
|
||||
end
|
||||
|
||||
test "handles custom field toggle" do
|
||||
assigns = create_assigns()
|
||||
{:ok, socket} = FieldVisibilityDropdownComponent.update(assigns, %{})
|
||||
|
||||
{:noreply, socket} =
|
||||
FieldVisibilityDropdownComponent.handle_event(
|
||||
"select_item",
|
||||
%{"item" => "custom_field_123"},
|
||||
socket
|
||||
)
|
||||
|
||||
assert socket.assigns.selected_fields["custom_field_123"] == false
|
||||
end
|
||||
end
|
||||
|
||||
describe "integration with LiveView" do
|
||||
test "component can be rendered in LiveView" do
|
||||
conn = conn_with_oidc_user(build_conn())
|
||||
{:ok, view, _html} = live(conn, "/members")
|
||||
|
||||
# Check that component is rendered
|
||||
assert has_element?(view, "button[aria-controls='field-visibility-menu']")
|
||||
end
|
||||
|
||||
test "clicking button opens dropdown" do
|
||||
conn = conn_with_oidc_user(build_conn())
|
||||
{:ok, view, _html} = live(conn, "/members")
|
||||
|
||||
# Initially closed
|
||||
refute has_element?(view, "ul#field-visibility-menu")
|
||||
|
||||
# Click button
|
||||
view
|
||||
|> element("button[aria-controls='field-visibility-menu']")
|
||||
|> render_click()
|
||||
|
||||
# Should be open now
|
||||
assert has_element?(view, "ul#field-visibility-menu")
|
||||
end
|
||||
|
||||
test "toggling field updates selection" do
|
||||
conn = conn_with_oidc_user(build_conn())
|
||||
{:ok, view, _html} = live(conn, "/members")
|
||||
|
||||
# Open dropdown
|
||||
view
|
||||
|> element("button[aria-controls='field-visibility-menu']")
|
||||
|> render_click()
|
||||
|
||||
# Toggle a field
|
||||
view
|
||||
|> element("button[phx-click='select_item'][phx-value-item='first_name']")
|
||||
|> render_click()
|
||||
|
||||
# Component should update (verified by state change)
|
||||
# In a real scenario, this would trigger a reload of members
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue