towerops/test/towerops_web/controllers/user_credential_controller_test.exs
2026-01-09 12:26:32 -06:00

95 lines
3.3 KiB
Elixir

defmodule ToweropsWeb.UserCredentialControllerTest do
use ToweropsWeb.ConnCase, async: true
import Towerops.AccountsFixtures
alias Towerops.Accounts
describe "POST /api/webauthn/registration/challenge" do
setup :register_and_log_in_user
test "returns challenge for authenticated user with confirmed email", %{conn: conn, user: user} do
conn = post(conn, ~p"/api/webauthn/registration/challenge")
assert %{"challenge" => challenge, "user" => user_data} = json_response(conn, 200)
assert is_binary(challenge)
assert user_data["name"] == user.email
end
test "returns error for user without confirmed email" do
# Create unconfirmed user
user = unconfirmed_user_fixture()
conn = log_in_user(build_conn(), user)
conn = post(conn, ~p"/api/webauthn/registration/challenge")
assert %{"error" => error} = json_response(conn, 403)
assert error =~ "Email confirmation required"
end
test "requires authentication" do
conn = build_conn()
conn = post(conn, ~p"/api/webauthn/registration/challenge")
assert redirected_to(conn) == ~p"/users/log-in"
end
end
describe "POST /api/webauthn/authentication/challenge" do
test "returns challenge for user with passkeys", %{conn: conn} do
user = user_fixture()
# Note: In a real test, we'd create a credential here
# For now, we test the error path
conn = post(conn, ~p"/api/webauthn/authentication/challenge", %{"email" => user.email})
assert %{"error" => _} = json_response(conn, 404)
end
test "returns error for non-existent user", %{conn: conn} do
conn =
post(conn, ~p"/api/webauthn/authentication/challenge", %{
"email" => "nonexistent@example.com"
})
assert %{"error" => _} = json_response(conn, 404)
end
test "does not require authentication", %{conn: conn} do
user = user_fixture()
conn = post(conn, ~p"/api/webauthn/authentication/challenge", %{"email" => user.email})
# Should not redirect to login
assert conn.status in [200, 404]
end
end
describe "DELETE /users/credentials/:id" do
setup :register_and_log_in_user
test "deletes credential successfully", %{conn: conn, user: user} do
# Create a test credential
credential = credential_fixture(user, %{name: "Test Key"})
conn = delete(conn, ~p"/users/credentials/#{credential.id}")
assert redirected_to(conn) == ~p"/users/settings"
assert Phoenix.Flash.get(conn.assigns.flash, :info) =~ "deleted successfully"
# Verify credential is deleted
assert Accounts.list_user_credentials(user.id) == []
end
test "cannot delete another user's credential", %{conn: conn} do
other_user = user_fixture()
credential = credential_fixture(other_user, %{name: "Other Key"})
conn = delete(conn, ~p"/users/credentials/#{credential.id}")
assert redirected_to(conn) == ~p"/users/settings"
assert Phoenix.Flash.get(conn.assigns.flash, :error) =~ "not found"
# Verify credential still exists
assert length(Accounts.list_user_credentials(other_user.id)) == 1
end
test "requires authentication" do
conn = build_conn()
conn = delete(conn, ~p"/users/credentials/#{Ecto.UUID.generate()}")
assert redirected_to(conn) == ~p"/users/log-in"
end
end
end