wbxcallprov/test/helpers.test.js
jmcqueen 6de5392e90
Some checks are pending
CI / verify (push) Waiting to run
Add node:test suite and Gitea Actions CI
- 30-test suite (node --test, no framework) covering the exact functions
  that have regressed in previous rounds:
    * parseStoreArg / parseStoreNumber / storeEmail (helpers)
    * greetingForBrand (brand fallback)
    * formatE911Address / formatSuite (google response reducer)
    * parseNextLink (RFC-5988 pagination — now exported)
    * runStep success / non-critical / critical / no-bot paths
- test/setup.js stubs required env vars so any src/ module can be
  imported cleanly; loaded via --import once per test process
- npm run test wired up; directory form works on Node 20 + 22
- .gitea/workflows/ci.yml runs lint + format:check + test on push/PR
  to main, on Node 22 to match the runtime image
- Exclude test/ and .gitea/ from the Docker build context
- Exclude docker/ from bot Prettier scope (remote-agent is its own
  sub-project with its own tooling)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 16:07:02 -04:00

74 lines
2.9 KiB
JavaScript

import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
import { parseStoreArg, parseStoreNumber, storeEmail } from '../src/commands/helpers.js';
// parseStoreArg regressed once already: the framework's trigger.prompt is
// everything AFTER the matched command (e.g. " 792" for "/storeInfo 792"),
// but the old implementation split and took index [1], which returned
// undefined. These tests lock that behavior down.
describe('parseStoreArg', () => {
it('reads first token from trigger.prompt (DM path)', () => {
assert.equal(parseStoreArg({ prompt: ' 792' }), '792');
});
it('handles a prompt with trailing junk', () => {
assert.equal(parseStoreArg({ prompt: ' 499 extra text' }), '499');
});
it('falls back to trigger.args when prompt is empty (DM)', () => {
// In DMs the framework populates args as [command, ...positional].
assert.equal(parseStoreArg({ prompt: '', args: ['/storeInfo', '792'] }), '792');
});
it('falls back to trigger.args in mentioned group rooms', () => {
// In group rooms args[0] is the bot name; we look for the first
// token starting with '/' and take the one after it.
assert.equal(
parseStoreArg({ prompt: '', args: ['aeoCallProvisioning', '/storeInfo', '792'] }),
'792',
);
});
it('returns undefined when nothing usable is present', () => {
assert.equal(parseStoreArg({}), undefined);
assert.equal(parseStoreArg({ prompt: ' ', args: [] }), undefined);
assert.equal(parseStoreArg(null), undefined);
assert.equal(parseStoreArg(undefined), undefined);
});
});
describe('parseStoreNumber', () => {
it('accepts 1-5 digit numeric strings', () => {
assert.equal(parseStoreNumber({ prompt: ' 1' }), '1');
assert.equal(parseStoreNumber({ prompt: ' 499' }), '499');
assert.equal(parseStoreNumber({ prompt: ' 12345' }), '12345');
});
it('rejects non-numeric input', () => {
assert.equal(parseStoreNumber({ prompt: ' abc' }), null);
assert.equal(parseStoreNumber({ prompt: ' 49a' }), null);
assert.equal(parseStoreNumber({ prompt: ' 4-9' }), null);
});
it('rejects overly long numbers', () => {
assert.equal(parseStoreNumber({ prompt: ' 123456' }), null);
});
it('returns null when the arg is missing', () => {
assert.equal(parseStoreNumber({}), null);
assert.equal(parseStoreNumber({ prompt: '' }), null);
});
});
describe('storeEmail', () => {
it('zero-pads to 5 digits and appends @ae.com', () => {
assert.equal(storeEmail(499), 'ae00499@ae.com');
assert.equal(storeEmail(1), 'ae00001@ae.com');
assert.equal(storeEmail(12345), 'ae12345@ae.com');
});
it('accepts numeric-string input', () => {
assert.equal(storeEmail('42'), 'ae00042@ae.com');
});
});