UNPKG

autotel

Version:
1 lines 6.08 kB
{"version":3,"file":"event-testing.cjs","names":[],"sources":["../src/event-testing.ts"],"sourcesContent":["/**\n * Testing utilities for Events\n *\n * Provides in-memory collection of events for testing purposes.\n */\n\nimport type {\n EventAttributes,\n FunnelStatus,\n OutcomeStatus,\n} from './event-subscriber';\n\nexport interface EventData {\n event: string;\n attributes?: EventAttributes;\n service: string;\n timestamp: number;\n}\n\nexport interface EventsFunnelStep {\n funnel: string;\n status: FunnelStatus;\n attributes?: EventAttributes;\n service: string;\n timestamp: number;\n}\n\nexport interface EventsOutcome {\n operation: string;\n status: OutcomeStatus;\n attributes?: EventAttributes;\n service: string;\n timestamp: number;\n}\n\nexport interface EventsValue {\n metric: string;\n value: number;\n attributes?: EventAttributes;\n service: string;\n timestamp: number;\n}\n\n/**\n * In-memory events collector for testing\n */\nexport interface EventCollector {\n /** Get all collected events */\n getEvents(): EventData[];\n /** Get all collected funnel steps */\n getFunnelSteps(): EventsFunnelStep[];\n /** Get all collected outcomes */\n getOutcomes(): EventsOutcome[];\n /** Get all collected values */\n getValues(): EventsValue[];\n /** Clear all collected events */\n clear(): void;\n /** Record an event (internal use) */\n recordEvent(event: EventData): void;\n /** Record a funnel step (internal use) */\n recordFunnelStep(step: EventsFunnelStep): void;\n /** Record an outcome (internal use) */\n recordOutcome(outcome: EventsOutcome): void;\n /** Record a value (internal use) */\n recordValue(value: EventsValue): void;\n}\n\n/**\n * Create an in-memory events collector for testing\n *\n * @example\n * ```typescript\n * const collector = createEventCollector()\n *\n * const events = new Event('test-service', { collector })\n * events.trackEvent('application.submitted', { jobId: '123' })\n *\n * const event =collector.getEvents()\n * expect(events).toHaveLength(1)\n * expect(events[0].event).toBe('application.submitted')\n * ```\n */\nexport function createEventCollector(): EventCollector {\n const events: EventData[] = [];\n const funnelSteps: EventsFunnelStep[] = [];\n const outcomes: EventsOutcome[] = [];\n const values: EventsValue[] = [];\n\n return {\n getEvents(): EventData[] {\n return [...events];\n },\n\n getFunnelSteps(): EventsFunnelStep[] {\n return [...funnelSteps];\n },\n\n getOutcomes(): EventsOutcome[] {\n return [...outcomes];\n },\n\n getValues(): EventsValue[] {\n return [...values];\n },\n\n clear(): void {\n events.length = 0;\n funnelSteps.length = 0;\n outcomes.length = 0;\n values.length = 0;\n },\n\n recordEvent(event: EventData): void {\n events.push(event);\n },\n\n recordFunnelStep(step: EventsFunnelStep): void {\n funnelSteps.push(step);\n },\n\n recordOutcome(outcome: EventsOutcome): void {\n outcomes.push(outcome);\n },\n\n recordValue(value: EventsValue): void {\n values.push(value);\n },\n };\n}\n\n/**\n * Assert that an events event was tracked\n *\n * @example\n * ```typescript\n * assertEventTracked({\n * collector,\n * eventName: 'application.submitted',\n * attributes: { jobId: '123' }\n * })\n * ```\n */\nexport function assertEventTracked(options: {\n collector: EventCollector;\n eventName: string;\n attributes?: Record<string, unknown>;\n}): void {\n const events = options.collector.getEvents();\n const matching = events.filter((e) => e.event === options.eventName);\n\n if (matching.length === 0) {\n throw new Error(`No events found with name: ${options.eventName}`);\n }\n\n if (options.attributes) {\n const matchingWithAttrs = matching.filter((e) =>\n Object.entries(options.attributes!).every(\n ([key, value]) => e.attributes && e.attributes[key] === value,\n ),\n );\n\n if (matchingWithAttrs.length === 0) {\n throw new Error(\n `Event ${options.eventName} found but attributes don't match: ${JSON.stringify(options.attributes)}`,\n );\n }\n }\n}\n\n/**\n * Assert that an outcome was tracked\n *\n * @example\n * ```typescript\n * assertOutcomeTracked({\n * collector,\n * operation: 'email.delivery',\n * status: 'success'\n * })\n * ```\n */\nexport function assertOutcomeTracked(options: {\n collector: EventCollector;\n operation: string;\n status: 'success' | 'failure' | 'partial';\n}): void {\n const outcomes = options.collector.getOutcomes();\n const matching = outcomes.filter(\n (o) => o.operation === options.operation && o.status === options.status,\n );\n\n if (matching.length === 0) {\n throw new Error(\n `No outcomes found with operation: ${options.operation} and status: ${options.status}`,\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAkFA,SAAgB,uBAAuC;CACrD,MAAM,SAAsB,CAAC;CAC7B,MAAM,cAAkC,CAAC;CACzC,MAAM,WAA4B,CAAC;CACnC,MAAM,SAAwB,CAAC;CAE/B,OAAO;EACL,YAAyB;GACvB,OAAO,CAAC,GAAG,MAAM;EACnB;EAEA,iBAAqC;GACnC,OAAO,CAAC,GAAG,WAAW;EACxB;EAEA,cAA+B;GAC7B,OAAO,CAAC,GAAG,QAAQ;EACrB;EAEA,YAA2B;GACzB,OAAO,CAAC,GAAG,MAAM;EACnB;EAEA,QAAc;GACZ,OAAO,SAAS;GAChB,YAAY,SAAS;GACrB,SAAS,SAAS;GAClB,OAAO,SAAS;EAClB;EAEA,YAAY,OAAwB;GAClC,OAAO,KAAK,KAAK;EACnB;EAEA,iBAAiB,MAA8B;GAC7C,YAAY,KAAK,IAAI;EACvB;EAEA,cAAc,SAA8B;GAC1C,SAAS,KAAK,OAAO;EACvB;EAEA,YAAY,OAA0B;GACpC,OAAO,KAAK,KAAK;EACnB;CACF;AACF;;;;;;;;;;;;;AAcA,SAAgB,mBAAmB,SAI1B;CAEP,MAAM,WADS,QAAQ,UAAU,UACX,CAAC,CAAC,QAAQ,MAAM,EAAE,UAAU,QAAQ,SAAS;CAEnE,IAAI,SAAS,WAAW,GACtB,MAAM,IAAI,MAAM,8BAA8B,QAAQ,WAAW;CAGnE,IAAI,QAAQ,YAOV;MAN0B,SAAS,QAAQ,MACzC,OAAO,QAAQ,QAAQ,UAAW,CAAC,CAAC,OACjC,CAAC,KAAK,WAAW,EAAE,cAAc,EAAE,WAAW,SAAS,KAC1D,CAGkB,CAAC,CAAC,WAAW,GAC/B,MAAM,IAAI,MACR,SAAS,QAAQ,UAAU,qCAAqC,KAAK,UAAU,QAAQ,UAAU,GACnG;CACF;AAEJ;;;;;;;;;;;;;AAcA,SAAgB,qBAAqB,SAI5B;CAMP,IALiB,QAAQ,UAAU,YACX,CAAC,CAAC,QACvB,MAAM,EAAE,cAAc,QAAQ,aAAa,EAAE,WAAW,QAAQ,MAGxD,CAAC,CAAC,WAAW,GACtB,MAAM,IAAI,MACR,qCAAqC,QAAQ,UAAU,eAAe,QAAQ,QAChF;AAEJ"}