Tests: accept single user or list from read_sign_in_with_rauthy (get? true)
Some checks reported errors
continuous-integration/drone/push Build was killed

Handle {:ok, user}, {:ok, nil} in addition to {:ok, [user]}, {:ok, []}.
This commit is contained in:
Moritz 2026-02-04 18:03:18 +01:00
parent b215282609
commit f59ed30d48
4 changed files with 80 additions and 8 deletions

View file

@ -130,6 +130,10 @@ defmodule Mv.Accounts.UserAuthenticationTest do
)
case result do
{:ok, found_user} when is_struct(found_user) ->
assert found_user.id == user.id
assert found_user.oidc_id == "oidc_identifier_12345"
{:ok, [found_user]} ->
assert found_user.id == user.id
assert found_user.oidc_id == "oidc_identifier_12345"
@ -137,6 +141,9 @@ defmodule Mv.Accounts.UserAuthenticationTest do
{:ok, []} ->
flunk("User should be found by oidc_id")
{:ok, nil} ->
flunk("User should be found by oidc_id")
{:error, error} ->
flunk("Unexpected error: #{inspect(error)}")
end
@ -231,11 +238,14 @@ defmodule Mv.Accounts.UserAuthenticationTest do
actor: system_actor
)
# Either returns empty list OR authentication error - both mean "user not found"
# Either returns empty/nil OR authentication error - both mean "user not found"
case result do
{:ok, []} ->
:ok
{:ok, nil} ->
:ok
{:error, %Ash.Error.Forbidden{errors: [%AshAuthentication.Errors.AuthenticationFailed{}]}} ->
:ok
@ -272,11 +282,14 @@ defmodule Mv.Accounts.UserAuthenticationTest do
actor: system_actor
)
# Either returns empty list OR authentication error - both mean "user not found"
# Either returns empty/nil OR authentication error - both mean "user not found"
case result do
{:ok, []} ->
:ok
{:ok, nil} ->
:ok
{:error, %Ash.Error.Forbidden{errors: [%AshAuthentication.Errors.AuthenticationFailed{}]}} ->
:ok

View file

@ -83,6 +83,25 @@ defmodule Mv.OidcRoleSyncTest do
{:ok, after_user} = get_user(user1.id)
assert after_user.role_id == mitglied_role_id()
end
test "when user_info has no groups, groups are read from access_token JWT (e.g. Rauthy)" do
email = "sync-from-token-#{System.unique_integer([:positive])}@test.example.com"
{:ok, user} = create_user_with_mitglied(email)
user_info = %{"sub" => "oidc-123"}
# Minimal JWT: header.payload.signature with "groups" in payload (Rauthy puts groups in access_token)
payload = Jason.encode!(%{"groups" => ["mila-admin"], "sub" => "oidc-123"})
payload_b64 = Base.url_encode64(payload, padding: false)
header_b64 = Base.url_encode64("{\"alg\":\"HS256\",\"typ\":\"JWT\"}", padding: false)
sig_b64 = Base.url_encode64("sig", padding: false)
access_token = "#{header_b64}.#{payload_b64}.#{sig_b64}"
oauth_tokens = %{"access_token" => access_token}
assert :ok = OidcRoleSync.apply_admin_role_from_user_info(user, user_info, oauth_tokens)
{:ok, after_user} = get_user(user.id)
assert after_user.role_id == admin_role_id()
end
end
# B3: Role sync after registration is implemented via after_action in register_with_rauthy.

View file

@ -37,7 +37,7 @@ defmodule MvWeb.OidcE2EFlowTest do
assert is_nil(new_user.hashed_password)
# Verify user can be found by oidc_id
{:ok, [found_user]} =
result =
Mv.Accounts.read_sign_in_with_rauthy(
%{
user_info: user_info,
@ -46,6 +46,13 @@ defmodule MvWeb.OidcE2EFlowTest do
actor: actor
)
found_user =
case result do
{:ok, u} when is_struct(u) -> u
{:ok, [u]} -> u
_ -> flunk("Expected user, got: #{inspect(result)}")
end
assert found_user.id == new_user.id
end
end
@ -177,7 +184,7 @@ defmodule MvWeb.OidcE2EFlowTest do
assert linked_user.hashed_password == password_user.hashed_password
# Step 5: User can now sign in via OIDC
{:ok, [signed_in_user]} =
result =
Mv.Accounts.read_sign_in_with_rauthy(
%{
user_info: user_info,
@ -186,6 +193,13 @@ defmodule MvWeb.OidcE2EFlowTest do
actor: actor
)
signed_in_user =
case result do
{:ok, u} when is_struct(u) -> u
{:ok, [u]} -> u
_ -> flunk("Expected user, got: #{inspect(result)}")
end
assert signed_in_user.id == password_user.id
assert signed_in_user.oidc_id == "oidc_link_888"
end
@ -331,6 +345,9 @@ defmodule MvWeb.OidcE2EFlowTest do
{:ok, []} ->
:ok
{:ok, nil} ->
:ok
{:error, %Ash.Error.Forbidden{}} ->
:ok

View file

@ -27,7 +27,7 @@ defmodule MvWeb.OidcIntegrationTest do
# Test sign_in_with_rauthy action directly
system_actor = Mv.Helpers.SystemActor.get_system_actor()
{:ok, [found_user]} =
result =
Mv.Accounts.read_sign_in_with_rauthy(
%{
user_info: user_info,
@ -36,6 +36,13 @@ defmodule MvWeb.OidcIntegrationTest do
actor: system_actor
)
found_user =
case result do
{:ok, u} when is_struct(u) -> u
{:ok, [u]} -> u
_ -> flunk("Expected user, got: #{inspect(result)}")
end
assert found_user.id == user.id
assert to_string(found_user.email) == "existing@example.com"
assert found_user.oidc_id == "existing_oidc_123"
@ -104,6 +111,9 @@ defmodule MvWeb.OidcIntegrationTest do
{:ok, []} ->
:ok
{:ok, nil} ->
:ok
{:error, %Ash.Error.Forbidden{errors: [%AshAuthentication.Errors.AuthenticationFailed{}]}} ->
:ok
@ -129,7 +139,7 @@ defmodule MvWeb.OidcIntegrationTest do
system_actor = Mv.Helpers.SystemActor.get_system_actor()
{:ok, [found_user]} =
result =
Mv.Accounts.read_sign_in_with_rauthy(
%{
user_info: correct_user_info,
@ -138,6 +148,13 @@ defmodule MvWeb.OidcIntegrationTest do
actor: system_actor
)
found_user =
case result do
{:ok, u} when is_struct(u) -> u
{:ok, [u]} -> u
_ -> flunk("Expected user, got: #{inspect(result)}")
end
assert found_user.id == user.id
# Try with wrong oidc_id but correct email
@ -155,11 +172,14 @@ defmodule MvWeb.OidcIntegrationTest do
actor: system_actor
)
# Either returns empty list OR authentication error - both mean "user not found"
# Either returns empty/nil OR authentication error - both mean "user not found"
case result do
{:ok, []} ->
:ok
{:ok, nil} ->
:ok
{:error, %Ash.Error.Forbidden{errors: [%AshAuthentication.Errors.AuthenticationFailed{}]}} ->
:ok
@ -193,11 +213,14 @@ defmodule MvWeb.OidcIntegrationTest do
actor: system_actor
)
# Either returns empty list OR authentication error - both mean "user not found"
# Either returns empty/nil OR authentication error - both mean "user not found"
case result do
{:ok, []} ->
:ok
{:ok, nil} ->
:ok
{:error, %Ash.Error.Forbidden{errors: [%AshAuthentication.Errors.AuthenticationFailed{}]}} ->
:ok