// A definition's trigger starts in the editor, and a run's origin on the // console (Rust PLAN_REDESIGNS §14.3.12, D370). The server decides; these prove // the form carries what it is given and the sentences read right. import { test } from 'node:test' import assert from 'node:assert/strict' import { formFromDefinition, payloadFromForm, blankStart, startsFormFrom, startsPayload, isStartableTrigger, describeOrigin, describeTriggerStarts, describeLogLine, } from '../src/lib/eventAuthoring.js' const TRIGGER = { id: 'rust.world.bradley_destroyed', label: 'Bradley destroyed', variables: [ { name: 'server', type: 'string' }, { name: 'kills', type: 'int' }, ], } const triggersById = new Map([[TRIGGER.id, TRIGGER]]) const definition = (starts) => ({ title: 'Launch Site Lockdown', spec: { schedule: { kind: 'manual' }, ...(starts ? { starts } : {}), phases: [{ key: 'main', label: 'Main', steps: [] }], }, }) test('a stored start round-trips through the form unchanged', () => { const starts = [{ on: TRIGGER.id, where: { variable: 'server', cmp: 'eq', value: 'main' }, cooldown: '2h' }] const form = formFromDefinition(definition(starts)) assert.equal(form.starts.length, 1) assert.equal(form.starts[0].whereRows.length, 1) const built = payloadFromForm(form, { triggersById }) assert.equal(built.ok, true) assert.deepEqual(built.payload.spec.starts, starts) }) test('no starts is no key, as the server stores it', () => { const built = payloadFromForm(formFromDefinition(definition()), { triggersById }) assert.equal('starts' in built.payload.spec, false) assert.deepEqual(formFromDefinition(definition()).starts, []) }) test('a half-added row is dropped, a blank cooldown is the default, a literal takes the declared type', () => { const rows = [ blankStart(), { ...blankStart(), on: TRIGGER.id, cooldown: ' ', whereRows: [{ variable: 'kills', cmp: 'gte', value: '2' }] }, ] const errors = [] const out = startsPayload(rows, errors, triggersById) assert.deepEqual(errors, []) assert.deepEqual(out, [{ on: TRIGGER.id, cooldown: '30m', where: { variable: 'kills', cmp: 'gte', value: 2 } }]) }) test('a nested condition the builder cannot draw is posted back verbatim', () => { const where = { op: 'and', nodes: [{ variable: 'server', cmp: 'eq', value: 'main' }, { op: 'or', nodes: [{ variable: 'kills', cmp: 'gt', value: 1 }, { variable: 'kills', cmp: 'lt', value: 0 }] }] } const [row] = startsFormFrom([{ on: TRIGGER.id, where, cooldown: '0m' }]) assert.equal(row.whereEditable, false) assert.deepEqual(startsPayload([row], [], triggersById), [{ on: TRIGGER.id, cooldown: '0m', where }]) }) test('core\'s own lifecycle triggers are not offered', () => { assert.equal(isStartableTrigger({ id: 'event.run.started' }), false) assert.equal(isStartableTrigger(TRIGGER), true) }) test('the origin sentence', () => { assert.equal(describeOrigin(null), null) assert.equal( describeOrigin({ kind: 'trigger', triggerId: TRIGGER.id, label: 'Bradley destroyed', matched: 'server is "main"', variables: { server: 'main', grid: 'G8', _truncated: true }, }), 'Started because “Bradley destroyed” fired (matching server is "main"): server main · grid G8', ) assert.equal(describeOrigin({ kind: 'trigger', triggerId: 'x.y', variables: {} }), 'Started because “x.y” fired') }) test('the editor\'s ignored-firings line', () => { assert.equal(describeTriggerStarts(null), null) assert.equal( describeTriggerStarts({ lastRunId: 12, ignoredRunning: 2, ignoredCooldown: 1, ignoredUnverified: 0 }), 'Last started run #12; since then 2 firings ignored while a run was going, 1 firing ignored in the cooldown.', ) assert.equal( describeTriggerStarts({ lastRunId: null, ignoredRunning: 0, ignoredCooldown: 0, ignoredUnverified: 1 }), 'No run started by a trigger yet; since then 1 firing ignored because the published version is not verified.', ) assert.equal(describeTriggerStarts({ lastRunId: 3 }), 'Last started run #3.') }) test('the audit line names a trigger start', () => { const line = describeLogLine({ kind: 'run.created', detail: { version: 2, source: 'trigger', origin: { kind: 'trigger', label: 'Bradley destroyed', variables: { grid: 'G8' } } }, }) assert.equal(line, 'Occurrence created from version 2 — Started because “Bradley destroyed” fired: grid G8') })