Files
windmill/frontend/src/lib/roleCapabilities.test.ts
T
8dbdfa1949 feat: workspace roles settings UI and capability-based gating (#11824)
* feat: configurable workspace roles with per-workspace overrides

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: close role review gaps in pickers, declarative sync and removal

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: keep resolve_role_name doc on its function

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: validate overrides on instance role changes and bill admins fully

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: allow pipeline drafts and keep role checks on one connection

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: list data pipelines in operator_can_draft

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test: expect a 403 role refusal when an operator resolves jobs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat: require a valid license for custom workspace roles

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: freeze workspace roles when the license lapses

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore: pin the ee companion for workspace roles

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* refactor: broadcast role override changes from the write path, not a trigger

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore: update ee-repo-ref to b5294d38db082bdd104d5358a47695390694c05d

This commit updates the EE repository reference after PR #891 was merged in windmill-ee-private.

Previous ee-repo-ref: 688e00c5982865b14098f530d54280e2311994c0

New ee-repo-ref: b5294d38db082bdd104d5358a47695390694c05d

Automated by sync-ee-ref workflow.

* feat: add workspace roles settings UI and role pickers

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: show the server's reason when a settings save fails

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: default role pickers to a defined role and confirm resets of unknown capabilities

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: treat null role capabilities as unset and key role drafts by map

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat: gate the frontend on workspace role capabilities

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: gate deploys, bulk actions and chat composition per role kind

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: treat a superadmin as full in deploy permission checks

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: leave page visibility out of isRestricted, as the server does

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: let a member discard their own draft without the authoring right

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: show custom roles as inactive without a valid license

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: keep the user store import on the agent page

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: show custom roles as frozen without a valid license

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: reorder instance roles with a drag handle

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: let an admin row that kept the operator flag hold full rights everywhere

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: treat superadmin members as admins and return role names from get user

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: move the instance role label into the expanded panel

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
2026-10-21 16:31:04 +02:00

47 lines
1.9 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import type { RoleCapabilities } from '$lib/gen'
import { capabilitiesIn, FULL_CAPABILITIES, hidesPages, isRestricted } from './roleCapabilities'
const scripter: RoleCapabilities = {
...FULL_CAPABILITIES,
apps: 'none',
visibility: { ...FULL_CAPABILITIES.visibility, workers: false }
}
describe('capabilitiesIn', () => {
it("takes the server's capabilities, whatever the legacy operator flag says", () => {
const caps = capabilitiesIn({ operator: false }, { capabilities: scripter })
expect(caps).toEqual(scripter)
expect(isRestricted(caps)).toBe(true)
})
it('gives an admin everything', () => {
expect(capabilitiesIn({ is_admin: true }, { capabilities: scripter })).toBe(FULL_CAPABILITIES)
})
// A server that predates roles sends `operator` and `operator_settings` only.
it('derives an operator from operator_settings on an older server', () => {
const caps = capabilitiesIn(
{ operator: true },
{ operator_settings: { runs: true, builder_flows: true, manage_triggers: false } as any }
)
expect(caps.code).toBe(false)
expect(caps.flows).toBe('compose')
expect(caps.apps).toBe('none')
expect(caps.manage_schedules).toBe(true)
expect(caps.manage_triggers).toBe(false)
expect(caps.visibility.runs).toBe(true)
// `=== true`: a flag the settings never mention, or settings never written, hide the page.
expect(caps.visibility.workers).toBe(false)
expect(capabilitiesIn({ operator: true }, undefined).visibility.runs).toBe(false)
expect(capabilitiesIn({ operator: false }, undefined)).toBe(FULL_CAPABILITIES)
})
// `RoleCapabilities::is_restricted` leaves visibility out, so a full author keeps forking.
it('does not restrict a full role that only hides pages', () => {
const hidden = { ...FULL_CAPABILITIES, visibility: { ...FULL_CAPABILITIES.visibility, workers: false } }
expect(isRestricted(hidden)).toBe(false)
expect(hidesPages(hidden)).toBe(true)
})
})