Add statistics route, permissions, and sidebar entry
- /statistics route and PagePaths.statistics - Permission sets: viewer and admin can access /statistics - Sidebar link with can_access_page check - Plug and sidebar tests updated Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
7b83011dcb
commit
cf79bbd1c4
7 changed files with 61 additions and 6 deletions
|
|
@ -26,6 +26,7 @@ This document lists all protected routes, which permission set may access them,
|
||||||
| `/groups/new` | ✗ | ✗ | ✗ | ✓ |
|
| `/groups/new` | ✗ | ✗ | ✗ | ✓ |
|
||||||
| `/groups/:slug` | ✗ | ✓ | ✓ | ✓ |
|
| `/groups/:slug` | ✗ | ✓ | ✓ | ✓ |
|
||||||
| `/groups/:slug/edit` | ✗ | ✗ | ✗ | ✓ |
|
| `/groups/:slug/edit` | ✗ | ✗ | ✗ | ✓ |
|
||||||
|
| `/statistics` | ✗ | ✓ | ✓ | ✓ |
|
||||||
| `/admin/roles` | ✗ | ✗ | ✗ | ✓ |
|
| `/admin/roles` | ✗ | ✗ | ✗ | ✓ |
|
||||||
| `/admin/roles/new` | ✗ | ✗ | ✗ | ✓ |
|
| `/admin/roles/new` | ✗ | ✗ | ✗ | ✓ |
|
||||||
| `/admin/roles/:id` | ✗ | ✗ | ✗ | ✓ |
|
| `/admin/roles/:id` | ✗ | ✗ | ✗ | ✓ |
|
||||||
|
|
|
||||||
|
|
@ -178,7 +178,9 @@ defmodule Mv.Authorization.PermissionSets do
|
||||||
# Groups overview
|
# Groups overview
|
||||||
"/groups",
|
"/groups",
|
||||||
# Group detail
|
# Group detail
|
||||||
"/groups/:slug"
|
"/groups/:slug",
|
||||||
|
# Statistics
|
||||||
|
"/statistics"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
@ -243,7 +245,9 @@ defmodule Mv.Authorization.PermissionSets do
|
||||||
# Group detail
|
# Group detail
|
||||||
"/groups/:slug",
|
"/groups/:slug",
|
||||||
# Edit group
|
# Edit group
|
||||||
"/groups/:slug/edit"
|
"/groups/:slug/edit",
|
||||||
|
# Statistics
|
||||||
|
"/statistics"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,14 @@ defmodule MvWeb.Layouts.Sidebar do
|
||||||
/>
|
/>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
<%= if can_access_page?(@current_user, PagePaths.statistics()) do %>
|
||||||
|
<.menu_item
|
||||||
|
href={~p"/statistics"}
|
||||||
|
icon="hero-chart-bar"
|
||||||
|
label={gettext("Statistics")}
|
||||||
|
/>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
<%= if admin_menu_visible?(@current_user) do %>
|
<%= if admin_menu_visible?(@current_user) do %>
|
||||||
<.menu_group
|
<.menu_group
|
||||||
icon="hero-cog-6-tooth"
|
icon="hero-cog-6-tooth"
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ defmodule MvWeb.PagePaths do
|
||||||
# Sidebar top-level menu paths
|
# Sidebar top-level menu paths
|
||||||
@members "/members"
|
@members "/members"
|
||||||
@membership_fee_types "/membership_fee_types"
|
@membership_fee_types "/membership_fee_types"
|
||||||
|
@statistics "/statistics"
|
||||||
|
|
||||||
# Administration submenu paths (all must match router)
|
# Administration submenu paths (all must match router)
|
||||||
@users "/users"
|
@users "/users"
|
||||||
|
|
@ -31,6 +32,9 @@ defmodule MvWeb.PagePaths do
|
||||||
@doc "Path for Membership Fee Types index (sidebar and page permission check)."
|
@doc "Path for Membership Fee Types index (sidebar and page permission check)."
|
||||||
def membership_fee_types, do: @membership_fee_types
|
def membership_fee_types, do: @membership_fee_types
|
||||||
|
|
||||||
|
@doc "Path for Statistics page (sidebar and page permission check)."
|
||||||
|
def statistics, do: @statistics
|
||||||
|
|
||||||
@doc "Paths for Administration menu; show group if user can access any of these."
|
@doc "Paths for Administration menu; show group if user can access any of these."
|
||||||
def admin_menu_paths, do: @admin_page_paths
|
def admin_menu_paths, do: @admin_page_paths
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,9 @@ defmodule MvWeb.Router do
|
||||||
|
|
||||||
# Membership Fee Types Management
|
# Membership Fee Types Management
|
||||||
live "/membership_fee_types", MembershipFeeTypeLive.Index, :index
|
live "/membership_fee_types", MembershipFeeTypeLive.Index, :index
|
||||||
|
|
||||||
|
# Statistics
|
||||||
|
live "/statistics", StatisticsLive, :index
|
||||||
live "/membership_fee_types/new", MembershipFeeTypeLive.Form, :new
|
live "/membership_fee_types/new", MembershipFeeTypeLive.Form, :new
|
||||||
live "/membership_fee_types/:id/edit", MembershipFeeTypeLive.Form, :edit
|
live "/membership_fee_types/:id/edit", MembershipFeeTypeLive.Form, :edit
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,12 +25,13 @@ defmodule MvWeb.SidebarAuthorizationTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "sidebar menu with admin user" do
|
describe "sidebar menu with admin user" do
|
||||||
test "shows Members, Fee Types and Administration with all subitems" do
|
test "shows Members, Fee Types, Statistics and Administration with all subitems" do
|
||||||
user = Fixtures.user_with_role_fixture("admin")
|
user = Fixtures.user_with_role_fixture("admin")
|
||||||
html = render_sidebar(sidebar_assigns(user))
|
html = render_sidebar(sidebar_assigns(user))
|
||||||
|
|
||||||
assert html =~ ~s(href="/members")
|
assert html =~ ~s(href="/members")
|
||||||
assert html =~ ~s(href="/membership_fee_types")
|
assert html =~ ~s(href="/membership_fee_types")
|
||||||
|
assert html =~ ~s(href="/statistics")
|
||||||
assert html =~ ~s(data-testid="sidebar-administration")
|
assert html =~ ~s(data-testid="sidebar-administration")
|
||||||
assert html =~ ~s(href="/users")
|
assert html =~ ~s(href="/users")
|
||||||
assert html =~ ~s(href="/groups")
|
assert html =~ ~s(href="/groups")
|
||||||
|
|
@ -41,11 +42,12 @@ defmodule MvWeb.SidebarAuthorizationTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "sidebar menu with read_only user (Vorstand/Buchhaltung)" do
|
describe "sidebar menu with read_only user (Vorstand/Buchhaltung)" do
|
||||||
test "shows Members and Groups (from Administration)" do
|
test "shows Members, Statistics and Groups (from Administration)" do
|
||||||
user = Fixtures.user_with_role_fixture("read_only")
|
user = Fixtures.user_with_role_fixture("read_only")
|
||||||
html = render_sidebar(sidebar_assigns(user))
|
html = render_sidebar(sidebar_assigns(user))
|
||||||
|
|
||||||
assert html =~ ~s(href="/members")
|
assert html =~ ~s(href="/members")
|
||||||
|
assert html =~ ~s(href="/statistics")
|
||||||
assert html =~ ~s(href="/groups")
|
assert html =~ ~s(href="/groups")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -61,11 +63,12 @@ defmodule MvWeb.SidebarAuthorizationTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "sidebar menu with normal_user (Kassenwart)" do
|
describe "sidebar menu with normal_user (Kassenwart)" do
|
||||||
test "shows Members and Groups" do
|
test "shows Members, Statistics and Groups" do
|
||||||
user = Fixtures.user_with_role_fixture("normal_user")
|
user = Fixtures.user_with_role_fixture("normal_user")
|
||||||
html = render_sidebar(sidebar_assigns(user))
|
html = render_sidebar(sidebar_assigns(user))
|
||||||
|
|
||||||
assert html =~ ~s(href="/members")
|
assert html =~ ~s(href="/members")
|
||||||
|
assert html =~ ~s(href="/statistics")
|
||||||
assert html =~ ~s(href="/groups")
|
assert html =~ ~s(href="/groups")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -88,10 +91,11 @@ defmodule MvWeb.SidebarAuthorizationTest do
|
||||||
refute html =~ ~s(href="/members")
|
refute html =~ ~s(href="/members")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "does not show Fee Types or Administration" do
|
test "does not show Statistics, Fee Types or Administration" do
|
||||||
user = Fixtures.user_with_role_fixture("own_data")
|
user = Fixtures.user_with_role_fixture("own_data")
|
||||||
html = render_sidebar(sidebar_assigns(user))
|
html = render_sidebar(sidebar_assigns(user))
|
||||||
|
|
||||||
|
refute html =~ ~s(href="/statistics")
|
||||||
refute html =~ ~s(href="/membership_fee_types")
|
refute html =~ ~s(href="/membership_fee_types")
|
||||||
refute html =~ ~s(href="/users")
|
refute html =~ ~s(href="/users")
|
||||||
refute html =~ ~s(data-testid="sidebar-administration")
|
refute html =~ ~s(data-testid="sidebar-administration")
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,37 @@ defmodule MvWeb.Plugs.CheckPagePermissionTest do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "statistics route /statistics" do
|
||||||
|
test "read_only can access /statistics" do
|
||||||
|
user = Fixtures.user_with_role_fixture("read_only")
|
||||||
|
conn = conn_with_user("/statistics", user) |> CheckPagePermission.call([])
|
||||||
|
|
||||||
|
refute conn.halted
|
||||||
|
end
|
||||||
|
|
||||||
|
test "normal_user can access /statistics" do
|
||||||
|
user = Fixtures.user_with_role_fixture("normal_user")
|
||||||
|
conn = conn_with_user("/statistics", user) |> CheckPagePermission.call([])
|
||||||
|
|
||||||
|
refute conn.halted
|
||||||
|
end
|
||||||
|
|
||||||
|
test "admin can access /statistics" do
|
||||||
|
user = Fixtures.user_with_role_fixture("admin")
|
||||||
|
conn = conn_with_user("/statistics", user) |> CheckPagePermission.call([])
|
||||||
|
|
||||||
|
refute conn.halted
|
||||||
|
end
|
||||||
|
|
||||||
|
test "own_data cannot access /statistics" do
|
||||||
|
user = Fixtures.user_with_role_fixture("own_data")
|
||||||
|
conn = conn_with_user("/statistics", user) |> CheckPagePermission.call([])
|
||||||
|
|
||||||
|
assert conn.halted
|
||||||
|
assert redirected_to(conn) == "/users/#{user.id}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "read_only and normal_user denied on admin routes" do
|
describe "read_only and normal_user denied on admin routes" do
|
||||||
test "read_only cannot access /admin/roles" do
|
test "read_only cannot access /admin/roles" do
|
||||||
user = Fixtures.user_with_role_fixture("read_only")
|
user = Fixtures.user_with_role_fixture("read_only")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue