fix(nav): show the player game-data groups to staff
All checks were successful
PR Checks / android-build (pull_request) Successful in 6m8s
All checks were successful
PR Checks / android-build (pull_request) Successful in 6m8s
Staff are a superset of players (all player abilities plus their staff tools), and the backend's player self-service surface is role-agnostic, but MenuAccess.PLAYER gated "My characters/vendors/houses" on role == player — so a signed-in admin/editor/moderator saw neither the menu items nor, via the greyed personal streams, their own notification options, even with linked characters. Gate MenuAccess.PLAYER on isPlayer OR isStaff. The notifications screen needs no change: once the backend returns the caller's linked accounts (paired with RunicGateway/website), hasLinkedAccount resolves and the personal streams enable themselves. Tests: MenuAccessTest now asserts every staff role sees the player game-data groups and a PLAYER entry, and an unrecognized role / anon still cannot. Full unit suite passes. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -37,12 +37,16 @@ class MenuAccessTest {
|
||||
assertTrue(visible.contains(Routes.HOME))
|
||||
}
|
||||
|
||||
@Test fun staffSeeAccountButNoPlayerOnlyGroups() {
|
||||
val visible = routes(signedIn(Role.EDITOR))
|
||||
assertTrue(visible.contains(Routes.ACCOUNT))
|
||||
// No PLAYER-access entry (the M4 game-data groups) leaks to staff.
|
||||
val playerOnly = APP_MENU.filter { it.access == MenuAccess.PLAYER }.map { it.route }
|
||||
assertTrue(playerOnly.none { visible.contains(it) })
|
||||
@Test fun staffSeeThePlayerGameDataGroups() {
|
||||
// Staff are a superset of players: every staff role sees the PLAYER-access
|
||||
// game-data groups too (their own linked characters, via the role-agnostic
|
||||
// /player self-service surface), on top of their staff entries.
|
||||
val playerGroups = APP_MENU.filter { it.access == MenuAccess.PLAYER }.map { it.route }
|
||||
for (role in listOf(Role.ADMIN, Role.EDITOR, Role.MODERATOR)) {
|
||||
val visible = routes(signedIn(role))
|
||||
assertTrue("$role should see Account", visible.contains(Routes.ACCOUNT))
|
||||
assertTrue("$role should see the player game-data groups", playerGroups.all { visible.contains(it) })
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun publicEntryCountIsStableAcrossSessions() {
|
||||
@@ -58,10 +62,13 @@ class MenuAccessTest {
|
||||
}
|
||||
|
||||
@Test fun playerAccessGatedFunction() {
|
||||
// A synthetic PLAYER-gated entry is visible to a player, hidden from staff/anon.
|
||||
// A PLAYER-gated entry is visible to a player AND to every staff role
|
||||
// (staff superset), hidden only from an unrecognized role and anon.
|
||||
val entries = listOf(MenuEntry("game", 0, MenuAccess.PLAYER))
|
||||
assertTrue(visibleEntries(entries, signedIn(Role.PLAYER)).isNotEmpty())
|
||||
assertTrue(visibleEntries(entries, signedIn(Role.ADMIN)).isEmpty())
|
||||
for (role in listOf(Role.PLAYER, Role.ADMIN, Role.EDITOR, Role.MODERATOR)) {
|
||||
assertTrue("$role should see a PLAYER entry", visibleEntries(entries, signedIn(role)).isNotEmpty())
|
||||
}
|
||||
assertTrue(visibleEntries(entries, signedIn(Role.UNKNOWN)).isEmpty())
|
||||
assertTrue(visibleEntries(entries, Session.SignedOut).isEmpty())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user