'use strict'; const { test } = require('node:test'); const assert = require('node:assert'); const reg = require('../../static/capabilities/library-card-actions.js'); function freshIds() { reg.snapshot().actions.forEach((a) => reg.unregister(a.id)); } test('register + list returns applicable actions sorted by order', () => { freshIds(); reg.register({ id: 'b', label: 'B', order: 20, run() {} }); reg.register({ id: 'a', label: 'A', order: 10, run() {} }); const ids = reg.list({ filename: 'x.archive' }).map((a) => a.id); assert.deepStrictEqual(ids, ['a', 'b']); }); test('applies() filters out non-applicable actions', () => { freshIds(); reg.register({ id: 'bassonly', label: 'Bass', applies: (s) => s.format === 'sloppak', run() {} }); assert.strictEqual(reg.list({ filename: 'x.archive', format: 'archive' }).length, 0); assert.strictEqual(reg.list({ filename: 'y.sloppak', format: 'sloppak' }).length, 1); }); test('enabled() reflected in the summary but action still listed', () => { freshIds(); reg.register({ id: 'maybe', label: 'Maybe', enabled: (s) => !!s.allow, run() {} }); const off = reg.list({ filename: 'x' })[0]; assert.strictEqual(off.enabled, false); const on = reg.list({ filename: 'x', allow: true })[0]; assert.strictEqual(on.enabled, true); }); test('run() invokes the handler and reports handled', async () => { freshIds(); let got = null; reg.register({ id: 'go', label: 'Go', run: (song) => { got = song.filename; return 'done'; } }); const r = await reg.run('go', { filename: 'song.archive' }, {}); assert.strictEqual(r.ok, true); assert.strictEqual(r.outcome, 'handled'); assert.strictEqual(got, 'song.archive'); }); test('run() of a disabled / non-applicable / unknown action does not throw', async () => { freshIds(); reg.register({ id: 'dis', label: 'Dis', enabled: () => false, run() { throw new Error('should not run'); } }); assert.strictEqual((await reg.run('dis', {})).outcome, 'disabled'); assert.strictEqual((await reg.run('nope', {})).outcome, 'no-action'); }); test('run() surfaces handler errors as failed (no throw)', async () => { freshIds(); reg.register({ id: 'boom', label: 'Boom', run() { throw new Error('kaboom'); } }); const r = await reg.run('boom', {}); assert.strictEqual(r.ok, false); assert.strictEqual(r.outcome, 'failed'); }); test('unregister removes the action', () => { freshIds(); const off = reg.register({ id: 'temp', label: 'T', run() {} }); assert.strictEqual(reg.list({}).length, 1); off(); assert.strictEqual(reg.list({}).length, 0); }); test('bad specs are rejected (no id / no run)', () => { freshIds(); reg.register({ label: 'no id', run() {} }); reg.register({ id: 'no-run' }); assert.strictEqual(reg.list({}).length, 0); });