Add Super Viewer read-only administrator role
CI / checks (push) Successful in 5m40s

This commit is contained in:
2026-10-11 23:30:40 -04:00
parent 253d47300c
commit 4ea291d305
48 changed files with 1684 additions and 933 deletions
+34
View File
@@ -1,6 +1,7 @@
import { describe, expect, it, vi } from 'vitest';
import { render } from 'svelte/server';
import { writable } from 'svelte/store';
import type { AuthUser } from '../../src/lib/auth.js';
import type { ProvisioningDetail, RecoveryObservation } from '../../src/lib/provisioning-detail.js';
import { provisioningNeedsRefresh } from '../../src/lib/ui/provisioning-presentation.js';
import ProvisioningPage from '../../src/routes/provisioning/[id]/+page.svelte';
@@ -79,6 +80,39 @@ function pageBody(detail: ProvisioningDetail) {
props: { data: { detail, user: null, setupRequired: false } }
}).body;
}
it('lets Super Viewers inspect actionable operations without mutation controls', () => {
const detail = fixture('failed');
Object.assign(detail, {
canResumeVerification: true,
canResumeCleanup: true,
canResumeRebuild: true,
canRetryWithRebuild: true,
canCancel: true,
canCancelCreation: true,
canOverrideSafety: true
});
const bodyFor = (role: AuthUser['role']) =>
render(ProvisioningPage, {
props: { data: { detail, user: { role } as AuthUser, setupRequired: false } }
}).body;
const readOnly = bodyFor('super_viewer');
const admin = bodyFor('admin');
expect(readOnly).toContain('View server');
expect(readOnly).toContain('operation-a');
for (const action of [
'Resume health verification',
'Resume rebuild cleanup',
'Resume cleanup',
'Retry with rebuild',
'Cancel operation',
'Cancel creation and remove server',
'Admin override…'
]) {
expect(readOnly).not.toContain(action);
expect(admin).toContain(action);
}
});
function recovery(state: RecoveryObservation['state']): RecoveryObservation {
return {
state,