test: add tests for join request page
This commit is contained in:
parent
21812542ad
commit
eadf90b5fc
5 changed files with 173 additions and 4 deletions
|
|
@ -60,13 +60,18 @@ defmodule MvWeb.JoinConfirmControllerTest do
|
|||
end
|
||||
|
||||
@tag role: :unauthenticated
|
||||
test "expired token returns 200 with expired message", %{conn: conn} do
|
||||
test "expired token returns 200 with expired message and instructs to submit form again", %{
|
||||
conn: conn
|
||||
} do
|
||||
Application.put_env(:mv, :join_confirm_callback, JoinConfirmExpiredStub)
|
||||
|
||||
conn = get(conn, "/confirm_join/expired-token")
|
||||
body = response(conn, 200)
|
||||
|
||||
assert response(conn, 200) =~ "expired"
|
||||
assert response(conn, 200) =~ "submit"
|
||||
assert body =~ "expired"
|
||||
assert body =~ "submit"
|
||||
# Concept §2.5: clear message + "submit form again"
|
||||
assert body =~ "form" or body =~ "again"
|
||||
end
|
||||
|
||||
@tag role: :unauthenticated
|
||||
|
|
|
|||
130
test/mv_web/live/join_live_test.exs
Normal file
130
test/mv_web/live/join_live_test.exs
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
defmodule MvWeb.JoinLiveTest do
|
||||
@moduledoc """
|
||||
Tests for the public join page (Subtask 4: Public join page and anti-abuse).
|
||||
|
||||
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.
|
||||
"""
|
||||
use MvWeb.ConnCase, async: true
|
||||
import Phoenix.LiveViewTest
|
||||
import Ecto.Query
|
||||
|
||||
alias Mv.Membership
|
||||
alias Mv.Repo
|
||||
|
||||
describe "GET /join" do
|
||||
@tag role: :unauthenticated
|
||||
test "unauthenticated GET /join returns 200 when join form is enabled", %{conn: conn} do
|
||||
enable_join_form(true)
|
||||
conn = get(conn, "/join")
|
||||
assert conn.status == 200
|
||||
end
|
||||
|
||||
@tag role: :unauthenticated
|
||||
test "unauthenticated GET /join returns 404 when join form is disabled", %{conn: conn} do
|
||||
enable_join_form(false)
|
||||
conn = get(conn, "/join")
|
||||
assert conn.status == 404
|
||||
end
|
||||
end
|
||||
|
||||
describe "submit join form" do
|
||||
setup :enable_join_form_for_test
|
||||
|
||||
@tag role: :unauthenticated
|
||||
test "submit with valid allowlist data creates one JoinRequest and shows success copy", %{
|
||||
conn: conn
|
||||
} do
|
||||
count_before = count_join_requests()
|
||||
{:ok, view, _html} = live(conn, "/join")
|
||||
|
||||
view
|
||||
|> form("#join-form", %{
|
||||
"email" => "newuser#{System.unique_integer([:positive])}@example.com",
|
||||
"first_name" => "Jane",
|
||||
"last_name" => "Doe",
|
||||
"honeypot" => ""
|
||||
})
|
||||
|> render_submit()
|
||||
|
||||
assert count_join_requests() == count_before + 1
|
||||
assert view |> element("[data-testid='join-success-message']") |> has_element?()
|
||||
assert render(view) =~ "saved your details"
|
||||
assert render(view) =~ "click the link"
|
||||
end
|
||||
|
||||
@tag role: :unauthenticated
|
||||
test "submit with honeypot filled does not create JoinRequest but shows same success copy", %{
|
||||
conn: conn
|
||||
} do
|
||||
count_before = count_join_requests()
|
||||
{:ok, view, _html} = live(conn, "/join")
|
||||
|
||||
view
|
||||
|> form("#join-form", %{
|
||||
"email" => "bot#{System.unique_integer([:positive])}@example.com",
|
||||
"first_name" => "Bot",
|
||||
"last_name" => "User",
|
||||
"honeypot" => "filled-by-bot"
|
||||
})
|
||||
|> render_submit()
|
||||
|
||||
assert count_join_requests() == count_before
|
||||
assert view |> element("[data-testid='join-success-message']") |> has_element?()
|
||||
end
|
||||
|
||||
@tag role: :unauthenticated
|
||||
@tag :slow
|
||||
test "after rate limit exceeded submit returns 429 or error and no new JoinRequest", %{
|
||||
conn: conn
|
||||
} do
|
||||
enable_join_form(true)
|
||||
# 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()
|
||||
|
||||
{:ok, view, _html} = live(conn, "/join")
|
||||
|
||||
# Exhaust limit with valid submits
|
||||
for i <- 0..1 do
|
||||
view
|
||||
|> form("#join-form", %{
|
||||
"email" => "#{i}-#{base_email}",
|
||||
"first_name" => "User",
|
||||
"last_name" => "Test",
|
||||
"honeypot" => ""
|
||||
})
|
||||
|> render_submit()
|
||||
end
|
||||
|
||||
# Next submit should be rate limited
|
||||
result =
|
||||
view
|
||||
|> form("#join-form", %{
|
||||
"email" => "third-#{base_email}",
|
||||
"first_name" => "Third",
|
||||
"last_name" => "User",
|
||||
"honeypot" => ""
|
||||
})
|
||||
|> render_submit()
|
||||
|
||||
assert count_join_requests() == count_before + 2
|
||||
assert result =~ "rate limit" or result =~ "too many" or result =~ "429"
|
||||
end
|
||||
end
|
||||
|
||||
defp enable_join_form(enabled) do
|
||||
{:ok, settings} = Membership.get_settings()
|
||||
{:ok, _} = Membership.update_settings(settings, %{join_form_enabled: enabled})
|
||||
end
|
||||
|
||||
defp enable_join_form_for_test(_context) do
|
||||
enable_join_form(true)
|
||||
:ok
|
||||
end
|
||||
|
||||
defp count_join_requests do
|
||||
Repo.one(from j in "join_requests", select: count(j.id)) || 0
|
||||
end
|
||||
end
|
||||
|
|
@ -204,6 +204,12 @@ defmodule MvWeb.Plugs.CheckPagePermissionTest do
|
|||
|
||||
refute conn.halted
|
||||
end
|
||||
|
||||
test "unauthenticated user can access /join (public join page, no redirect)" do
|
||||
conn = conn_without_user("/join") |> CheckPagePermission.call([])
|
||||
|
||||
refute conn.halted
|
||||
end
|
||||
end
|
||||
|
||||
describe "error handling" do
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue