From 95b666f04f77e9e1253974352d55f782421a617a Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 6 May 2026 11:14:09 +0200 Subject: [PATCH] test: verify that join view respects custom field types --- test/mv_web/live/join_live_test.exs | 123 ++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/test/mv_web/live/join_live_test.exs b/test/mv_web/live/join_live_test.exs index 273e786..20cd5cf 100644 --- a/test/mv_web/live/join_live_test.exs +++ b/test/mv_web/live/join_live_test.exs @@ -167,6 +167,120 @@ defmodule MvWeb.JoinLiveTest do end end + describe "join field input types" do + @tag role: :unauthenticated + test "renders boolean custom field as checkbox input", %{conn: conn} do + system_actor = Mv.Helpers.SystemActor.get_system_actor() + {:ok, settings} = Membership.get_settings() + + {:ok, boolean_field} = + Membership.create_custom_field( + %{ + name: "Subscribe to newsletter", + value_type: :boolean + }, + actor: system_actor + ) + + {:ok, _} = + Membership.update_settings(settings, %{ + join_form_enabled: true, + join_form_field_ids: ["email", boolean_field.id], + join_form_field_required: %{"email" => true, boolean_field.id => false} + }) + + {:ok, view, _html} = live(conn, "/join") + + assert has_element?(view, "#join-form") + assert has_element?(view, "input#join-field-#{boolean_field.id}[name='#{boolean_field.id}']") + assert has_element?(view, "input#join-field-#{boolean_field.id}[type='checkbox']") + refute has_element?(view, "input#join-field-#{boolean_field.id}[type='text']") + end + + @tag role: :unauthenticated + test "renders typed custom fields with matching HTML input types", %{conn: conn} do + system_actor = Mv.Helpers.SystemActor.get_system_actor() + {:ok, settings} = Membership.get_settings() + + {:ok, integer_field} = + Membership.create_custom_field(%{name: "Lucky number", value_type: :integer}, actor: system_actor) + + {:ok, date_field} = + Membership.create_custom_field(%{name: "Birth date", value_type: :date}, actor: system_actor) + + {:ok, email_field} = + Membership.create_custom_field(%{name: "Secondary email", value_type: :email}, actor: system_actor) + + {:ok, _} = + Membership.update_settings(settings, %{ + join_form_enabled: true, + join_form_field_ids: ["email", integer_field.id, date_field.id, email_field.id], + join_form_field_required: %{ + "email" => true, + integer_field.id => false, + date_field.id => false, + email_field.id => false + } + }) + + {:ok, view, _html} = live(conn, "/join") + + assert has_element?(view, "input#join-field-#{integer_field.id}[type='number']") + assert has_element?(view, "input#join-field-#{date_field.id}[type='date']") + assert has_element?(view, "input#join-field-#{email_field.id}[type='email']") + end + end + + describe "submit join form with typed custom fields" do + setup do + reset_rate_limiter() + :ok + end + + @tag role: :unauthenticated + test "persists checked boolean custom field and ignores non-allowlisted field", %{conn: conn} do + system_actor = Mv.Helpers.SystemActor.get_system_actor() + {:ok, settings} = Membership.get_settings() + + {:ok, boolean_field} = + Membership.create_custom_field( + %{ + name: "Receive announcements", + value_type: :boolean + }, + actor: system_actor + ) + + {:ok, _} = + Membership.update_settings(settings, %{ + join_form_enabled: true, + join_form_field_ids: ["email", boolean_field.id], + join_form_field_required: %{"email" => true, boolean_field.id => false} + }) + + count_before = count_join_requests() + {:ok, view, _html} = live(conn, "/join") + + view + |> element("#join-form") + |> render_submit(%{ + "email" => "typed#{System.unique_integer([:positive])}@example.com", + "website" => "", + boolean_field.id => "on", + "not_allowlisted" => "should-not-be-persisted" + }) + + Process.sleep(400) + + assert count_join_requests() == count_before + 1 + assert view |> element("[data-testid='join-success-message']") |> has_element?() + + form_data = latest_join_request_form_data() + assert Map.get(form_data, boolean_field.id) == "on" + refute Map.has_key?(form_data, "not_allowlisted") + end + end + defp enable_join_form(enabled) do {:ok, settings} = Membership.get_settings() {:ok, _} = Membership.update_settings(settings, %{join_form_enabled: enabled}) @@ -189,6 +303,15 @@ defmodule MvWeb.JoinLiveTest do Repo.one(from j in "join_requests", select: count(j.id)) || 0 end + defp latest_join_request_form_data do + Repo.one( + from j in "join_requests", + order_by: [desc: j.inserted_at], + limit: 1, + select: j.form_data + ) || %{} + end + defp reset_rate_limiter do :ets.delete_all_objects(MvWeb.JoinRateLimit) rescue