This commit is contained in:
parent
eadf90b5fc
commit
f1d0526209
19 changed files with 547 additions and 15 deletions
|
|
@ -5,6 +5,9 @@ defmodule MvWeb.JoinLiveTest do
|
|||
Covers: public path /join (unauthenticated 200), 404 when join disabled,
|
||||
submit creates JoinRequest and shows success copy, honeypot prevents create,
|
||||
rate limiting rejects excess submits. Uses unauthenticated conn; no User/Member.
|
||||
|
||||
Honeypot: form param `"website"` (legit-sounding name per best practice; not "honeypot").
|
||||
Field is hidden via CSS class in app.css (off-screen, no inline styles), type="text".
|
||||
"""
|
||||
use MvWeb.ConnCase, async: true
|
||||
import Phoenix.LiveViewTest
|
||||
|
|
@ -44,7 +47,7 @@ defmodule MvWeb.JoinLiveTest do
|
|||
"email" => "newuser#{System.unique_integer([:positive])}@example.com",
|
||||
"first_name" => "Jane",
|
||||
"last_name" => "Doe",
|
||||
"honeypot" => ""
|
||||
"website" => ""
|
||||
})
|
||||
|> render_submit()
|
||||
|
||||
|
|
@ -66,7 +69,7 @@ defmodule MvWeb.JoinLiveTest do
|
|||
"email" => "bot#{System.unique_integer([:positive])}@example.com",
|
||||
"first_name" => "Bot",
|
||||
"last_name" => "User",
|
||||
"honeypot" => "filled-by-bot"
|
||||
"website" => "filled-by-bot"
|
||||
})
|
||||
|> render_submit()
|
||||
|
||||
|
|
@ -79,38 +82,66 @@ defmodule MvWeb.JoinLiveTest do
|
|||
test "after rate limit exceeded submit returns 429 or error and no new JoinRequest", %{
|
||||
conn: conn
|
||||
} do
|
||||
# Reset rate limit state so this test is independent of others (same key in test)
|
||||
try do
|
||||
:ets.delete_all_objects(MvWeb.JoinRateLimit)
|
||||
rescue
|
||||
ArgumentError -> :ok
|
||||
end
|
||||
|
||||
enable_join_form(true)
|
||||
# Set allowlist so form has email, first_name, last_name
|
||||
{:ok, settings} = Membership.get_settings()
|
||||
|
||||
Membership.update_settings(settings, %{
|
||||
join_form_field_ids: ["email", "first_name", "last_name"],
|
||||
join_form_field_required: %{"email" => true, "first_name" => false, "last_name" => false}
|
||||
})
|
||||
|
||||
# Rely on test config: join rate limit low (e.g. 2 per window)
|
||||
base_email = "ratelimit#{System.unique_integer([:positive])}@example.com"
|
||||
count_before = count_join_requests()
|
||||
sandbox = conn.private[:ecto_sandbox]
|
||||
|
||||
{:ok, view, _html} = live(conn, "/join")
|
||||
|
||||
# Exhaust limit with valid submits
|
||||
# Exhaust limit with 2 valid submits (each needs a fresh session because form disappears after submit)
|
||||
for i <- 0..1 do
|
||||
c =
|
||||
build_conn()
|
||||
|> Phoenix.ConnTest.init_test_session(%{})
|
||||
|> Plug.Conn.put_private(:ecto_sandbox, sandbox)
|
||||
|
||||
{:ok, view, _} = live(c, "/join")
|
||||
|
||||
view
|
||||
|> form("#join-form", %{
|
||||
"email" => "#{i}-#{base_email}",
|
||||
"first_name" => "User",
|
||||
"last_name" => "Test",
|
||||
"honeypot" => ""
|
||||
"website" => ""
|
||||
})
|
||||
|> render_submit()
|
||||
end
|
||||
|
||||
# Next submit should be rate limited
|
||||
# Next submit (new session) should be rate limited
|
||||
c =
|
||||
build_conn()
|
||||
|> Phoenix.ConnTest.init_test_session(%{})
|
||||
|> Plug.Conn.put_private(:ecto_sandbox, sandbox)
|
||||
|
||||
{:ok, view, _} = live(c, "/join")
|
||||
|
||||
result =
|
||||
view
|
||||
|> form("#join-form", %{
|
||||
"email" => "third-#{base_email}",
|
||||
"first_name" => "Third",
|
||||
"last_name" => "User",
|
||||
"honeypot" => ""
|
||||
"website" => ""
|
||||
})
|
||||
|> render_submit()
|
||||
|
||||
assert count_join_requests() == count_before + 2
|
||||
assert result =~ "rate limit" or result =~ "too many" or result =~ "429"
|
||||
assert result =~ "rate limit" or String.downcase(result) =~ "too many" or result =~ "429"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -120,7 +151,15 @@ defmodule MvWeb.JoinLiveTest do
|
|||
end
|
||||
|
||||
defp enable_join_form_for_test(_context) do
|
||||
enable_join_form(true)
|
||||
{:ok, settings} = Membership.get_settings()
|
||||
|
||||
{:ok, _} =
|
||||
Membership.update_settings(settings, %{
|
||||
join_form_enabled: true,
|
||||
join_form_field_ids: ["email", "first_name", "last_name"],
|
||||
join_form_field_required: %{"email" => true, "first_name" => false, "last_name" => false}
|
||||
})
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue