commit ec8b30c68cb2fd243bd1b9e33037555a438bb921
parent fa8048840c6c88f07c68b1eef9278f66f133f907
Author: finwo <finwo@pm.me>
Date: Sun, 20 Sep 2026 03:26:11 +0200
Finish the rename in constants and role fixtures the pass missed
Diffstat:
5 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/src/conductor/ui/layout.js b/src/conductor/ui/layout.js
@@ -104,5 +104,5 @@ export function duration(from, to) {
return `${Math.floor(seconds / 60)}m ${seconds % 60}s`;
}
-export const ACTIVE_RUN_STATES = ['pending', 'running'];
-export const ACTIVE_JOB_STATES = ['queued', 'running'];
+export const ACTIVE_JOB_STATES = ['pending', 'running'];
+export const ACTIVE_TASK_STATES = ['queued', 'running'];
diff --git a/src/conductor/ui/pages.js b/src/conductor/ui/pages.js
@@ -6,7 +6,7 @@
// polling stops by itself rather than needing to be cancelled.
import { html, raw } from './html.js';
-import { badge, notice, oneTimeSecret, shortSha, ago, duration, ACTIVE_RUN_STATES, ACTIVE_JOB_STATES } from './layout.js';
+import { badge, notice, oneTimeSecret, shortSha, ago, duration, ACTIVE_JOB_STATES, ACTIVE_TASK_STATES } from './layout.js';
const poll = (url, seconds = 3) => raw(`hx-get="${url}" hx-trigger="every ${seconds}s" hx-swap="outerHTML"`);
@@ -21,7 +21,7 @@ export function jobsPage({ jobs, user, anonymous }) {
}
export function jobsTable(jobs) {
- const live = jobs.some((r) => ACTIVE_RUN_STATES.includes(r.state));
+ const live = jobs.some((r) => ACTIVE_JOB_STATES.includes(r.state));
return html`<div id="jobs" ${live ? poll('/partials/jobs', 4) : ''}>
<table>
<thead><tr>
@@ -68,7 +68,7 @@ export function jobPage({ job, tasks, canManage }) {
}
export function tasksTable(job, tasks) {
- const live = ACTIVE_RUN_STATES.includes(job.state);
+ const live = ACTIVE_JOB_STATES.includes(job.state);
// Grouped by graph depth, which is how the pipeline reads.
const byId = new Map(tasks.map((j) => [j.id, j]));
@@ -138,7 +138,7 @@ export function taskPage({ task, artifacts, log }) {
}
export function taskLog(task, log) {
- const live = ACTIVE_JOB_STATES.includes(task.state);
+ const live = ACTIVE_TASK_STATES.includes(task.state);
return html`<pre id="log" class="log" ${live ? poll(`/partials/tasks/${task.id}/log`, 2) : ''}>${
log || (live ? 'Waiting for output.' : 'No output.')
}</pre>`;
diff --git a/test/auth.test.js b/test/auth.test.js
@@ -62,7 +62,7 @@ test('a token signed with another secret is refused', () => {
});
test('a tampered payload is refused', () => {
- const token = issueToken('secret', { sub: 'u1', name: 'a', role: 'viewer' });
+ const token = issueToken('secret', { sub: 'u1', name: 'a', role: 'user' });
const [header, payload, signature] = token.split('.');
const forged = Buffer.from(JSON.stringify({
...JSON.parse(Buffer.from(payload, 'base64url').toString('utf8')),
diff --git a/test/oidc.test.js b/test/oidc.test.js
@@ -120,13 +120,13 @@ test('a token carrying the admin role authenticates as an administrator', apiGon
});
});
-test('a token without the admin role is a viewer', apiGone, async () => {
+test('a token without the admin role is an ordinary user', apiGone, async () => {
await withOidcConductor({}, async (h) => {
const headers = await oidc.headers('persona-viewer');
const me = await h.app.inject({ method: 'GET', url: '/api/auth/me', headers });
assert.equal(me.json().user.username, 'bob');
- assert.equal(me.json().user.role, 'viewer');
+ assert.equal(me.json().user.role, 'user');
assert.equal((await h.app.inject({ method: 'GET', url: '/api/admin/users', headers })).statusCode, 403);
});
@@ -211,10 +211,10 @@ test('a role revoked at the provider is lost on the next request', apiGone, asyn
// The provider stops asserting the role for that subject.
const account = await h.services.users.byExternalId(`${oidc.issuer}|alice-sub`);
await h.services.users.upsertExternal({
- externalId: `${oidc.issuer}|alice-sub`, username: 'alice', role: 'viewer',
+ externalId: `${oidc.issuer}|alice-sub`, username: 'alice', role: 'user',
});
const refreshed = await h.services.users.get(account.id);
- assert.equal(refreshed.role, 'viewer');
+ assert.equal(refreshed.role, 'user');
});
});
diff --git a/test/ui.test.js b/test/ui.test.js
@@ -195,7 +195,7 @@ test('a user cannot open or delete a project they do not own', async () => {
await withUi({}, async (h) => {
const admin = await signIn(h);
await h.app.inject({
- method: 'POST', url: '/users', ...form(admin, { username: 'mallory', password: 'mallory-password', role: 'viewer' }),
+ method: 'POST', url: '/users', ...form(admin, { username: 'mallory', password: 'mallory-password', role: 'user' }),
});
const other = await signIn(h, 'mallory', 'mallory-password');
@@ -234,7 +234,7 @@ test('an ordinary user cannot create shared capacity from the form', async () =>
await withUi({}, async (h) => {
const admin = await signIn(h);
await h.app.inject({
- method: 'POST', url: '/users', ...form(admin, { username: 'carol', password: 'carol-password', role: 'viewer' }),
+ method: 'POST', url: '/users', ...form(admin, { username: 'carol', password: 'carol-password', role: 'user' }),
});
const carol = await signIn(h, 'carol', 'carol-password');
@@ -252,7 +252,7 @@ test('the users page is administrator only and warns about what deletion destroy
await withUi({}, async (h) => {
const admin = await signIn(h);
await h.app.inject({
- method: 'POST', url: '/users', ...form(admin, { username: 'dave', password: 'dave-password', role: 'viewer' }),
+ method: 'POST', url: '/users', ...form(admin, { username: 'dave', password: 'dave-password', role: 'user' }),
});
const dave = await h.services.users.byUsername('dave');
await h.services.projects.setOwner('demo', dave.id);