This commit is contained in:
parent
d40bc0bb82
commit
d10fcc3da1
7 changed files with 68 additions and 46 deletions
|
|
@ -31,9 +31,10 @@ defmodule MvWeb.Layouts do
|
||||||
attr :flash, :map, required: true, doc: "the map of flash messages"
|
attr :flash, :map, required: true, doc: "the map of flash messages"
|
||||||
|
|
||||||
attr :current_user, :map, default: nil, doc: "the current user, if authenticated"
|
attr :current_user, :map, default: nil, doc: "the current user, if authenticated"
|
||||||
|
|
||||||
attr :current_scope, :map,
|
attr :current_scope, :map,
|
||||||
default: nil,
|
default: nil,
|
||||||
doc: "the current [scope](https://hexdocs.pm/phoenix/scopes.html)"
|
doc: "the current [scope](https://hexdocs.pm/phoenix/scopes.html)"
|
||||||
|
|
||||||
slot :inner_block, required: true
|
slot :inner_block, required: true
|
||||||
|
|
||||||
|
|
@ -52,7 +53,6 @@ defmodule MvWeb.Layouts do
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Shows the flash group with standard titles and content.
|
Shows the flash group with standard titles and content.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,9 @@ defmodule MvWeb.Layouts.Navbar do
|
||||||
use Gettext, backend: MvWeb.Gettext
|
use Gettext, backend: MvWeb.Gettext
|
||||||
use MvWeb, :verified_routes
|
use MvWeb, :verified_routes
|
||||||
|
|
||||||
attr :current_user, :map, required: true, doc: "The current user - navbar is only shown when user is present"
|
attr :current_user, :map,
|
||||||
|
required: true,
|
||||||
|
doc: "The current user - navbar is only shown when user is present"
|
||||||
|
|
||||||
def navbar(assigns) do
|
def navbar(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,10 @@ defmodule MvWeb.LiveUserAuth do
|
||||||
case socket.assigns do
|
case socket.assigns do
|
||||||
%{current_user: %{} = user} ->
|
%{current_user: %{} = user} ->
|
||||||
{:cont, assign(socket, :current_user, user)}
|
{:cont, assign(socket, :current_user, user)}
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
{:halt, Phoenix.LiveView.redirect(socket, to: ~p"/sign-in")}
|
socket = Phoenix.LiveView.redirect(socket, to: ~p"/sign-in")
|
||||||
|
{:halt, socket}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,10 @@ defmodule MvWeb.Layouts.NavbarTest do
|
||||||
# Setup: Create a user
|
# Setup: Create a user
|
||||||
user = create_test_user(%{email: "test@example.com"})
|
user = create_test_user(%{email: "test@example.com"})
|
||||||
|
|
||||||
html = render_component(&MvWeb.Layouts.Navbar.navbar/1, %{
|
html =
|
||||||
current_user: user
|
render_component(&MvWeb.Layouts.Navbar.navbar/1, %{
|
||||||
})
|
current_user: user
|
||||||
|
})
|
||||||
|
|
||||||
# Test dropdown structure
|
# Test dropdown structure
|
||||||
assert html =~ "dropdown-content"
|
assert html =~ "dropdown-content"
|
||||||
|
|
@ -27,11 +28,13 @@ defmodule MvWeb.Layouts.NavbarTest do
|
||||||
# Setup: Create a user with specific email for testing initials
|
# Setup: Create a user with specific email for testing initials
|
||||||
user = create_test_user(%{email: "test.user@example.com"})
|
user = create_test_user(%{email: "test.user@example.com"})
|
||||||
|
|
||||||
html = render_component(&MvWeb.Layouts.Navbar.navbar/1, %{
|
html =
|
||||||
current_user: user
|
render_component(&MvWeb.Layouts.Navbar.navbar/1, %{
|
||||||
})
|
current_user: user
|
||||||
|
})
|
||||||
|
|
||||||
assert html =~ "<span>TU</span>" # Initials from test.user@example.com
|
# Initials from test.user@example.com
|
||||||
|
assert html =~ "<span>TU</span>"
|
||||||
end
|
end
|
||||||
|
|
||||||
@tag :skip
|
@tag :skip
|
||||||
|
|
@ -42,31 +45,36 @@ defmodule MvWeb.Layouts.NavbarTest do
|
||||||
"sub" => "oidc_123",
|
"sub" => "oidc_123",
|
||||||
"preferred_username" => "oidc.user@example.com"
|
"preferred_username" => "oidc.user@example.com"
|
||||||
}
|
}
|
||||||
|
|
||||||
oauth_tokens = %{
|
oauth_tokens = %{
|
||||||
"access_token" => "test_token",
|
"access_token" => "test_token",
|
||||||
"id_token" => "test_id_token"
|
"id_token" => "test_id_token"
|
||||||
}
|
}
|
||||||
|
|
||||||
user = Mv.Accounts.User
|
user =
|
||||||
|> Ash.Changeset.for_create(:register_with_rauthy, %{
|
Mv.Accounts.User
|
||||||
user_info: user_info,
|
|> Ash.Changeset.for_create(:register_with_rauthy, %{
|
||||||
oauth_tokens: oauth_tokens
|
user_info: user_info,
|
||||||
})
|
oauth_tokens: oauth_tokens
|
||||||
|> Ash.create!(domain: Mv.Accounts)
|
})
|
||||||
|
|> Ash.create!(domain: Mv.Accounts)
|
||||||
|
|
||||||
html = render_component(&MvWeb.Layouts.Navbar.navbar/1, %{
|
html =
|
||||||
current_user: user
|
render_component(&MvWeb.Layouts.Navbar.navbar/1, %{
|
||||||
})
|
current_user: user
|
||||||
|
})
|
||||||
|
|
||||||
assert html =~ "<span>OU</span>" # Initials from oidc.user@example.com
|
# Initials from oidc.user@example.com
|
||||||
|
assert html =~ "<span>OU</span>"
|
||||||
end
|
end
|
||||||
|
|
||||||
test "includes all required navigation items", %{conn: _conn} do
|
test "includes all required navigation items", %{conn: _conn} do
|
||||||
user = create_test_user(%{email: "test@example.com"})
|
user = create_test_user(%{email: "test@example.com"})
|
||||||
|
|
||||||
html = render_component(&MvWeb.Layouts.Navbar.navbar/1, %{
|
html =
|
||||||
current_user: user
|
render_component(&MvWeb.Layouts.Navbar.navbar/1, %{
|
||||||
})
|
current_user: user
|
||||||
|
})
|
||||||
|
|
||||||
# Check for all required menu items
|
# Check for all required menu items
|
||||||
assert html =~ "Profil"
|
assert html =~ "Profil"
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,8 @@ defmodule MvWeb.ProfileNavigationTest do
|
||||||
conn = conn_with_password_user(conn, user)
|
conn = conn_with_password_user(conn, user)
|
||||||
{:ok, _view, html} = live(conn, "/")
|
{:ok, _view, html} = live(conn, "/")
|
||||||
|
|
||||||
assert html =~ "<span>TU</span>" # Initials from test.user@example.com
|
# Initials from test.user@example.com
|
||||||
|
assert html =~ "<span>TU</span>"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -77,17 +78,19 @@ defmodule MvWeb.ProfileNavigationTest do
|
||||||
"sub" => "oidc_123",
|
"sub" => "oidc_123",
|
||||||
"preferred_username" => "oidc.user@example.com"
|
"preferred_username" => "oidc.user@example.com"
|
||||||
}
|
}
|
||||||
|
|
||||||
oauth_tokens = %{
|
oauth_tokens = %{
|
||||||
"access_token" => "test_token",
|
"access_token" => "test_token",
|
||||||
"id_token" => "test_id_token"
|
"id_token" => "test_id_token"
|
||||||
}
|
}
|
||||||
|
|
||||||
user = Mv.Accounts.User
|
user =
|
||||||
|> Ash.Changeset.for_create(:register_with_rauthy, %{
|
Mv.Accounts.User
|
||||||
user_info: user_info,
|
|> Ash.Changeset.for_create(:register_with_rauthy, %{
|
||||||
oauth_tokens: oauth_tokens
|
user_info: user_info,
|
||||||
})
|
oauth_tokens: oauth_tokens
|
||||||
|> Ash.create!(domain: Mv.Accounts)
|
})
|
||||||
|
|> Ash.create!(domain: Mv.Accounts)
|
||||||
|
|
||||||
# Login user via OIDC
|
# Login user via OIDC
|
||||||
conn = sign_in_user_via_oidc(conn, user)
|
conn = sign_in_user_via_oidc(conn, user)
|
||||||
|
|
@ -99,32 +102,38 @@ defmodule MvWeb.ProfileNavigationTest do
|
||||||
# Verify we're on the correct profile page with OIDC specific information
|
# Verify we're on the correct profile page with OIDC specific information
|
||||||
{:ok, _profile_view, html} = live(conn, "/users/#{user.id}")
|
{:ok, _profile_view, html} = live(conn, "/users/#{user.id}")
|
||||||
assert html =~ to_string(user.email)
|
assert html =~ to_string(user.email)
|
||||||
assert html =~ "oidc_123" # OIDC ID should be visible
|
# OIDC ID should be visible
|
||||||
assert html =~ "Not enabled" # Password auth should be disabled for OIDC users
|
assert html =~ "oidc_123"
|
||||||
|
# Password auth should be disabled for OIDC users
|
||||||
|
assert html =~ "Not enabled"
|
||||||
end
|
end
|
||||||
|
|
||||||
test "profile navigation works across different authentication methods", %{conn: conn} do
|
test "profile navigation works across different authentication methods", %{conn: conn} do
|
||||||
# Create password user
|
# Create password user
|
||||||
password_user = create_test_user(%{
|
password_user =
|
||||||
email: "password2@example.com",
|
create_test_user(%{
|
||||||
password: "test_password123"
|
email: "password2@example.com",
|
||||||
})
|
password: "test_password123"
|
||||||
|
})
|
||||||
|
|
||||||
# Create OIDC user
|
# Create OIDC user
|
||||||
user_info = %{
|
user_info = %{
|
||||||
"sub" => "oidc_789",
|
"sub" => "oidc_789",
|
||||||
"preferred_username" => "oidc@example.com"
|
"preferred_username" => "oidc@example.com"
|
||||||
}
|
}
|
||||||
|
|
||||||
oauth_tokens = %{
|
oauth_tokens = %{
|
||||||
"access_token" => "test_token",
|
"access_token" => "test_token",
|
||||||
"id_token" => "test_id_token"
|
"id_token" => "test_id_token"
|
||||||
}
|
}
|
||||||
oidc_user = Mv.Accounts.User
|
|
||||||
|> Ash.Changeset.for_create(:register_with_rauthy, %{
|
oidc_user =
|
||||||
user_info: user_info,
|
Mv.Accounts.User
|
||||||
oauth_tokens: oauth_tokens
|
|> Ash.Changeset.for_create(:register_with_rauthy, %{
|
||||||
})
|
user_info: user_info,
|
||||||
|> Ash.create!(domain: Mv.Accounts)
|
oauth_tokens: oauth_tokens
|
||||||
|
})
|
||||||
|
|> Ash.create!(domain: Mv.Accounts)
|
||||||
|
|
||||||
# Test with password user
|
# Test with password user
|
||||||
conn_password = conn_with_password_user(conn, password_user)
|
conn_password = conn_with_password_user(conn, password_user)
|
||||||
|
|
@ -139,5 +148,4 @@ defmodule MvWeb.ProfileNavigationTest do
|
||||||
assert_redirected(view_oidc, "/users/#{oidc_user.id}")
|
assert_redirected(view_oidc, "/users/#{oidc_user.id}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -388,7 +388,8 @@ defmodule MvWeb.UserLive.IndexTest do
|
||||||
assert html =~ "Email"
|
assert html =~ "Email"
|
||||||
assert html =~ "OIDC ID"
|
assert html =~ "OIDC ID"
|
||||||
# Should show the authenticated user at minimum
|
# Should show the authenticated user at minimum
|
||||||
assert html =~ "oidc.user" # Matches the generated email pattern oidc.user{unique_id}@example.com
|
# Matches the generated email pattern oidc.user{unique_id}@example.com
|
||||||
|
assert html =~ "oidc.user"
|
||||||
end
|
end
|
||||||
|
|
||||||
test "handles users with missing OIDC ID", %{conn: conn} do
|
test "handles users with missing OIDC ID", %{conn: conn} do
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,7 @@ defmodule MvWeb.ConnCase do
|
||||||
def conn_with_oidc_user(conn, user_attrs \\ %{}) do
|
def conn_with_oidc_user(conn, user_attrs \\ %{}) do
|
||||||
# Ensure unique email for OIDC users
|
# Ensure unique email for OIDC users
|
||||||
unique_id = System.unique_integer([:positive])
|
unique_id = System.unique_integer([:positive])
|
||||||
|
|
||||||
default_attrs = %{
|
default_attrs = %{
|
||||||
email: "oidc.user#{unique_id}@example.com",
|
email: "oidc.user#{unique_id}@example.com",
|
||||||
oidc_id: "oidc_#{unique_id}"
|
oidc_id: "oidc_#{unique_id}"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue