master-zapier-plan-draft/packages/verae-zapier-middleware/test/integration/wait-nats.test.js
George Lambert 51ae79b75f Milestone 3: NATS wait (gate 9), hash lookup, zappier timestamp, NS1 tunnel
Wait-via-NATS returns completed or pending+jobId (GATE 9). Mock SHA256
idempotent register + GET /hashes/{sha256}. Zappier commercial edge has
POST /v1/timestamp and hash-lookup. GATE 12 smoke (signup + wait) passes.

NS1 NATS is 127.0.0.1:4222 on 70.88.205.138; SSH tunnel :14222. Local
nats-server -js used for isolated tests. Activate app adds Echo Text.

Learned: JetStream on NS1 is loopback-only; do not bind 4222 public.
2026-09-09 02:54:02 -04:00

67 lines
2.3 KiB
JavaScript

/**
* GATE 9 — /timestamp/wait via NATS events (timeout returns pending + jobId)
*/
import { describe, it, before, after } from 'node:test';
import assert from 'node:assert/strict';
import { config } from '../../src/config.js';
import { useTempStore, seedProTenant } from '../helpers.js';
import { connectNats, ensureStreams, closeNats } from '../../src/nats/connection.js';
import { startJobPollerWorker, stopJobPollerWorker } from '../../src/workers/jobPollerWorker.js';
import { createTimestampAndWait } from '../../src/services/timestampService.js';
import { resolveAuthContext } from '../../src/services/authService.js';
import { clearMockJobs } from '../../src/clients/veraeClient.js';
describe('GATE 9 wait via NATS', () => {
/** @type {ReturnType<typeof useTempStore>} */
let ctx;
let authCtx;
before(async () => {
assert.equal(config.mockVerae, true);
config.natsEnabled = true;
process.env.NATS_FORCE_CONNECT = '1';
config.natsUrl = process.env.NATS_URL || 'nats://127.0.0.1:4222';
config.jobPollIntervalMs = 40;
config.jobPollMaxAttempts = 40;
config.waitTimeoutMs = 8000;
config.mockJobCompleteMs = 80;
clearMockJobs();
ctx = useTempStore();
const seeded = seedProTenant();
authCtx = await resolveAuthContext(seeded.apiKey);
await connectNats(config.natsUrl);
await ensureStreams();
await startJobPollerWorker();
});
after(async () => {
await stopJobPollerWorker();
await closeNats();
ctx.cleanup();
process.env.NATS_FORCE_CONNECT = '';
});
it('wait returns completed when worker finishes before timeout', async () => {
const status = await createTimestampAndWait(authCtx, { data: 'wait-fast' });
assert.equal(status.status, 'completed');
assert.ok(status.id || status.jobId);
});
it('wait returns pending + jobId on timeout', async () => {
const prevWait = config.waitTimeoutMs;
const prevDelay = config.mockJobCompleteMs;
config.waitTimeoutMs = 60;
config.mockJobCompleteMs = 30_000;
try {
const status = await createTimestampAndWait(authCtx, { data: 'wait-slow' });
assert.equal(status.status, 'pending');
assert.ok(status.jobId || status.id);
} finally {
config.waitTimeoutMs = prevWait;
config.mockJobCompleteMs = prevDelay;
}
});
});