towerops/test/towerops_web/controllers/user_registration_controller_test.exs

186 lines
5.3 KiB
Elixir

defmodule ToweropsWeb.UserRegistrationControllerTest do
@moduledoc """
Tests for UserRegistrationController.
Note: This controller is not currently routed (registration uses UserRegistrationLive),
but we test the controller module directly to ensure code coverage and correctness.
We dispatch through the endpoint to get proper plug pipeline setup.
"""
use ToweropsWeb.ConnCase, async: true
import Towerops.AccountsFixtures
import Towerops.OrganizationsFixtures
alias Towerops.Accounts
alias ToweropsWeb.UserRegistrationController
# Helper to prepare conn for direct controller invocation
# (controller is unrouted, so we set up params/flash manually)
defp prepare_conn(conn) do
conn
|> Phoenix.ConnTest.init_test_session(%{})
|> Plug.Conn.fetch_query_params()
|> Phoenix.Controller.fetch_flash()
|> Plug.Conn.put_private(:phoenix_endpoint, ToweropsWeb.Endpoint)
|> Plug.Conn.put_private(:phoenix_router, ToweropsWeb.Router)
|> Plug.Conn.put_private(:phoenix_format, "html")
|> Map.put(:params, %{})
end
describe "new/2" do
test "renders registration form", %{conn: conn} do
conn =
conn
|> prepare_conn()
|> UserRegistrationController.new(%{})
assert conn.status == 200
end
test "renders registration form with invitation token", %{conn: conn} do
user = user_fixture()
org = organization_fixture(user.id)
{:ok, invitation} =
Towerops.Organizations.create_invitation(%{
organization_id: org.id,
invited_by_id: user.id,
email: "invited@example.com",
role: "member"
})
conn =
conn
|> prepare_conn()
|> UserRegistrationController.new(%{"invitation_token" => invitation.token})
assert conn.status == 200
end
test "handles non-existent invitation token gracefully", %{conn: conn} do
conn =
conn
|> prepare_conn()
|> UserRegistrationController.new(%{"invitation_token" => "bogus-token"})
assert conn.status == 200
end
end
describe "create/2" do
test "creates user with organization on normal registration", %{conn: conn} do
email = unique_user_email()
conn =
conn
|> prepare_conn()
|> Map.put(:params, %{})
|> UserRegistrationController.create(%{
"user" => %{
"email" => email,
"password" => valid_user_password(),
"privacy_policy_consent" => "true",
"terms_of_service_consent" => "true"
}
})
# Should redirect (log in user)
assert conn.status in [301, 302]
# User should exist
assert Accounts.get_user_by_email(email)
end
test "returns errors for invalid registration data", %{conn: conn} do
conn =
conn
|> prepare_conn()
|> Map.put(:params, %{})
|> UserRegistrationController.create(%{
"user" => %{
"email" => "bad",
"password" => "x"
}
})
# Should re-render the form with errors
assert conn.status == 200
end
test "creates user via invitation and adds to organization", %{conn: conn} do
inviter = user_fixture()
org = organization_fixture(inviter.id)
{:ok, invitation} =
Towerops.Organizations.create_invitation(%{
organization_id: org.id,
invited_by_id: inviter.id,
email: "newuser@example.com",
role: "member"
})
email = unique_user_email()
conn =
conn
|> prepare_conn()
|> Map.put(:params, %{"invitation_token" => invitation.token})
|> UserRegistrationController.create(%{
"user" => %{
"email" => email,
"password" => valid_user_password(),
"invitation_token" => invitation.token,
"privacy_policy_consent" => "true",
"terms_of_service_consent" => "true"
}
})
# Should redirect (log in user)
assert conn.status in [301, 302]
# User should exist
assert Accounts.get_user_by_email(email)
end
test "handles invalid invitation token on create", %{conn: conn} do
email = unique_user_email()
conn =
conn
|> prepare_conn()
|> Map.put(:params, %{"invitation_token" => "expired-or-bad-token"})
|> UserRegistrationController.create(%{
"user" => %{
"email" => email,
"password" => valid_user_password(),
"invitation_token" => "expired-or-bad-token",
"privacy_policy_consent" => "true",
"terms_of_service_consent" => "true"
}
})
# Should re-render with error flash
assert conn.status == 200
end
test "prevents duplicate email registration", %{conn: conn} do
existing_user = user_fixture()
conn =
conn
|> prepare_conn()
|> Map.put(:params, %{})
|> UserRegistrationController.create(%{
"user" => %{
"email" => existing_user.email,
"password" => valid_user_password(),
"privacy_policy_consent" => "true",
"terms_of_service_consent" => "true"
}
})
# Should re-render with validation errors
assert conn.status == 200
end
end
end