{"version":3,"file":"messaging-testing.cjs","names":[],"sources":["../src/messaging-testing.ts"],"sourcesContent":["/**\n * Testing utilities for messaging instrumentation\n *\n * Provides mock producers, consumers, and assertion helpers\n * for testing event-driven code with Autotel's messaging module.\n *\n * @example Basic test setup\n * ```typescript\n * import { createMessagingTestHarness } from 'autotel/messaging-testing';\n *\n * describe('Order processing', () => {\n *   const harness = createMessagingTestHarness();\n *\n *   beforeEach(() => harness.reset());\n *   afterAll(() => harness.shutdown());\n *\n *   it('should process order and publish event', async () => {\n *     await processOrder({ id: 'order-123' });\n *\n *     harness.assertProducerCalled('orders', {\n *       messageCount: 1,\n *       hasTraceHeaders: true,\n *     });\n *   });\n * });\n * ```\n *\n * @module\n */\n\nimport type { Link, SpanContext } from '@opentelemetry/api';\nimport type {\n  RebalanceEvent,\n  PartitionAssignment,\n  OutOfOrderInfo,\n} from './messaging';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Recorded producer call\n */\nexport interface RecordedProducerCall {\n  /** Destination (topic/queue) */\n  destination: string;\n\n  /** System (kafka, sqs, etc.) */\n  system: string;\n\n  /** Message payload */\n  payload: unknown;\n\n  /** Headers injected */\n  headers: Record<string, string>;\n\n  /** Timestamp of call */\n  timestamp: number;\n\n  /** Trace ID from headers */\n  traceId?: string;\n\n  /** Span ID from headers */\n  spanId?: string;\n}\n\n/**\n * Recorded consumer call\n */\nexport interface RecordedConsumerCall {\n  /** Destination (topic/queue) */\n  destination: string;\n\n  /** System (kafka, sqs, etc.) */\n  system: string;\n\n  /** Consumer group */\n  consumerGroup?: string;\n\n  /** Message payload */\n  payload: unknown;\n\n  /** Headers extracted */\n  headers?: Record<string, string>;\n\n  /** Timestamp of call */\n  timestamp: number;\n\n  /** Producer links extracted */\n  producerLinks: Link[];\n\n  /** Whether message was duplicate */\n  isDuplicate: boolean;\n\n  /** Out of order info if detected */\n  outOfOrderInfo: OutOfOrderInfo | null;\n\n  /** DLQ reason if routed to DLQ */\n  dlqReason?: string;\n\n  /** Retry attempt number */\n  retryAttempt?: number;\n}\n\n/**\n * Recorded rebalance event\n */\nexport interface RecordedRebalanceEvent extends RebalanceEvent {\n  /** Destination (topic) */\n  destination: string;\n\n  /** Consumer group */\n  consumerGroup: string;\n}\n\n/**\n * Mock message for testing\n */\nexport interface MockMessage<T = unknown> {\n  /** Message payload */\n  payload: T;\n\n  /** Headers */\n  headers?: Record<string, string>;\n\n  /** Offset/sequence number */\n  offset?: number;\n\n  /** Partition */\n  partition?: number;\n\n  /** Key */\n  key?: string;\n\n  /** Message ID */\n  messageId?: string;\n\n  /** Timestamp */\n  timestamp?: number;\n}\n\n/**\n * Producer assertion options\n */\nexport interface ProducerAssertionOptions {\n  /** Expected number of messages */\n  messageCount?: number;\n\n  /** Whether trace headers should be present */\n  hasTraceHeaders?: boolean;\n\n  /** Expected destination */\n  destination?: string;\n\n  /** Custom matcher for payload */\n  payloadMatcher?: (payload: unknown) => boolean;\n\n  /** Expected trace ID */\n  traceId?: string;\n}\n\n/**\n * Consumer assertion options\n */\nexport interface ConsumerAssertionOptions {\n  /** Expected number of messages processed */\n  messageCount?: number;\n\n  /** Whether producer links should be present */\n  hasProducerLinks?: boolean;\n\n  /** Expected destination */\n  destination?: string;\n\n  /** Expected consumer group */\n  consumerGroup?: string;\n\n  /** Whether any messages were duplicates */\n  hasDuplicates?: boolean;\n\n  /** Whether any messages were out of order */\n  hasOutOfOrder?: boolean;\n\n  /** Whether any messages went to DLQ */\n  hasDLQ?: boolean;\n}\n\n/**\n * Messaging test harness\n */\nexport interface MessagingTestHarness {\n  /** All recorded producer calls */\n  producerCalls: RecordedProducerCall[];\n\n  /** All recorded consumer calls */\n  consumerCalls: RecordedConsumerCall[];\n\n  /** All recorded rebalance events */\n  rebalanceEvents: RecordedRebalanceEvent[];\n\n  /**\n   * Record a producer call\n   */\n  recordProducerCall(call: Omit<RecordedProducerCall, 'timestamp'>): void;\n\n  /**\n   * Record a consumer call\n   */\n  recordConsumerCall(call: Omit<RecordedConsumerCall, 'timestamp'>): void;\n\n  /**\n   * Record a rebalance event\n   */\n  recordRebalanceEvent(event: RecordedRebalanceEvent): void;\n\n  /**\n   * Create a mock message with trace headers\n   */\n  createMockMessage<T>(\n    payload: T,\n    options?: Partial<MockMessage<T>>,\n  ): MockMessage<T>;\n\n  /**\n   * Create mock trace headers\n   */\n  createMockTraceHeaders(\n    traceId?: string,\n    spanId?: string,\n  ): Record<string, string>;\n\n  /**\n   * Assert producer was called with expected options\n   */\n  assertProducerCalled(\n    destination: string,\n    options?: ProducerAssertionOptions,\n  ): void;\n\n  /**\n   * Assert producer was not called\n   */\n  assertProducerNotCalled(destination?: string): void;\n\n  /**\n   * Assert consumer processed messages with expected options\n   */\n  assertConsumerProcessed(\n    destination: string,\n    options?: ConsumerAssertionOptions,\n  ): void;\n\n  /**\n   * Assert consumer was not called\n   */\n  assertConsumerNotCalled(destination?: string): void;\n\n  /**\n   * Assert rebalance occurred\n   */\n  assertRebalanceOccurred(\n    destination: string,\n    type: RebalanceEvent['type'],\n    partitionCount?: number,\n  ): void;\n\n  /**\n   * Get producer calls for destination\n   */\n  getProducerCalls(destination?: string): RecordedProducerCall[];\n\n  /**\n   * Get consumer calls for destination\n   */\n  getConsumerCalls(destination?: string): RecordedConsumerCall[];\n\n  /**\n   * Get the last producer call\n   */\n  getLastProducerCall(destination?: string): RecordedProducerCall | undefined;\n\n  /**\n   * Get the last consumer call\n   */\n  getLastConsumerCall(destination?: string): RecordedConsumerCall | undefined;\n\n  /**\n   * Reset all recorded calls\n   */\n  reset(): void;\n\n  /**\n   * Shutdown the harness\n   */\n  shutdown(): void;\n}\n\n// ============================================================================\n// Implementation\n// ============================================================================\n\n/**\n * Generate a random hex string\n */\nfunction randomHex(length: number): string {\n  let result = '';\n  const chars = '0123456789abcdef';\n  for (let i = 0; i < length; i++) {\n    result += chars.charAt(Math.floor(Math.random() * chars.length));\n  }\n  return result;\n}\n\n/**\n * Create a messaging test harness\n *\n * Provides utilities for recording and asserting on producer/consumer calls\n * during testing.\n *\n * @example\n * ```typescript\n * const harness = createMessagingTestHarness();\n *\n * // In your test setup\n * beforeEach(() => harness.reset());\n *\n * // In your tests\n * it('should publish order event', async () => {\n *   await orderService.createOrder({ id: '123' });\n *\n *   harness.assertProducerCalled('orders', {\n *     messageCount: 1,\n *     hasTraceHeaders: true,\n *   });\n *\n *   const lastCall = harness.getLastProducerCall('orders');\n *   expect(lastCall?.payload).toMatchObject({ orderId: '123' });\n * });\n * ```\n */\nexport function createMessagingTestHarness(): MessagingTestHarness {\n  const producerCalls: RecordedProducerCall[] = [];\n  const consumerCalls: RecordedConsumerCall[] = [];\n  const rebalanceEvents: RecordedRebalanceEvent[] = [];\n\n  return {\n    producerCalls,\n    consumerCalls,\n    rebalanceEvents,\n\n    recordProducerCall(call) {\n      producerCalls.push({\n        ...call,\n        timestamp: Date.now(),\n      });\n    },\n\n    recordConsumerCall(call) {\n      consumerCalls.push({\n        ...call,\n        timestamp: Date.now(),\n      });\n    },\n\n    recordRebalanceEvent(event) {\n      rebalanceEvents.push(event);\n    },\n\n    createMockMessage<T>(\n      payload: T,\n      options: Partial<MockMessage<T>> = {},\n    ): MockMessage<T> {\n      return {\n        payload,\n        headers: options.headers ?? this.createMockTraceHeaders(),\n        offset: options.offset ?? Math.floor(Math.random() * 10_000),\n        partition: options.partition ?? 0,\n        key: options.key,\n        messageId: options.messageId ?? `msg-${randomHex(8)}`,\n        timestamp: options.timestamp ?? Date.now(),\n      };\n    },\n\n    createMockTraceHeaders(\n      traceId?: string,\n      spanId?: string,\n    ): Record<string, string> {\n      const tid = traceId ?? randomHex(32);\n      const sid = spanId ?? randomHex(16);\n      return {\n        traceparent: `00-${tid}-${sid}-01`,\n      };\n    },\n\n    assertProducerCalled(\n      destination: string,\n      options: ProducerAssertionOptions = {},\n    ) {\n      const calls = producerCalls.filter((c) => c.destination === destination);\n\n      if (calls.length === 0) {\n        throw new Error(\n          `Expected producer to be called for destination '${destination}', but it was not called`,\n        );\n      }\n\n      if (\n        options.messageCount !== undefined &&\n        calls.length !== options.messageCount\n      ) {\n        throw new Error(\n          `Expected ${options.messageCount} producer calls for '${destination}', got ${calls.length}`,\n        );\n      }\n\n      if (options.hasTraceHeaders) {\n        const withoutHeaders = calls.filter((c) => !c.headers?.traceparent);\n        if (withoutHeaders.length > 0) {\n          throw new Error(\n            `Expected all producer calls for '${destination}' to have trace headers, but ${withoutHeaders.length} did not`,\n          );\n        }\n      }\n\n      if (options.traceId) {\n        const matchingTraceId = calls.filter(\n          (c) => c.traceId === options.traceId,\n        );\n        if (matchingTraceId.length === 0) {\n          throw new Error(\n            `Expected producer call for '${destination}' with traceId '${options.traceId}', but none found`,\n          );\n        }\n      }\n\n      if (options.payloadMatcher) {\n        const matching = calls.filter((c) =>\n          options.payloadMatcher!(c.payload),\n        );\n        if (matching.length === 0) {\n          throw new Error(\n            `Expected producer call for '${destination}' to match payload matcher, but none did`,\n          );\n        }\n      }\n    },\n\n    assertProducerNotCalled(destination?: string) {\n      if (destination) {\n        const calls = producerCalls.filter(\n          (c) => c.destination === destination,\n        );\n        if (calls.length > 0) {\n          throw new Error(\n            `Expected producer not to be called for '${destination}', but it was called ${calls.length} times`,\n          );\n        }\n      } else {\n        if (producerCalls.length > 0) {\n          throw new Error(\n            `Expected no producer calls, but ${producerCalls.length} calls were made`,\n          );\n        }\n      }\n    },\n\n    assertConsumerProcessed(\n      destination: string,\n      options: ConsumerAssertionOptions = {},\n    ) {\n      const calls = consumerCalls.filter((c) => c.destination === destination);\n\n      if (calls.length === 0) {\n        throw new Error(\n          `Expected consumer to process messages for destination '${destination}', but none were processed`,\n        );\n      }\n\n      if (\n        options.messageCount !== undefined &&\n        calls.length !== options.messageCount\n      ) {\n        throw new Error(\n          `Expected ${options.messageCount} consumer calls for '${destination}', got ${calls.length}`,\n        );\n      }\n\n      if (options.consumerGroup) {\n        const wrongGroup = calls.filter(\n          (c) => c.consumerGroup !== options.consumerGroup,\n        );\n        if (wrongGroup.length > 0) {\n          throw new Error(\n            `Expected consumer group '${options.consumerGroup}' for '${destination}', but found different groups`,\n          );\n        }\n      }\n\n      if (options.hasProducerLinks) {\n        const withoutLinks = calls.filter((c) => c.producerLinks.length === 0);\n        if (withoutLinks.length > 0) {\n          throw new Error(\n            `Expected all consumer calls for '${destination}' to have producer links, but ${withoutLinks.length} did not`,\n          );\n        }\n      }\n\n      if (options.hasDuplicates !== undefined) {\n        const duplicates = calls.filter((c) => c.isDuplicate);\n        if (options.hasDuplicates && duplicates.length === 0) {\n          throw new Error(\n            `Expected duplicate messages for '${destination}', but none were detected`,\n          );\n        }\n        if (!options.hasDuplicates && duplicates.length > 0) {\n          throw new Error(\n            `Expected no duplicate messages for '${destination}', but ${duplicates.length} were detected`,\n          );\n        }\n      }\n\n      if (options.hasOutOfOrder !== undefined) {\n        const outOfOrder = calls.filter((c) => c.outOfOrderInfo !== null);\n        if (options.hasOutOfOrder && outOfOrder.length === 0) {\n          throw new Error(\n            `Expected out-of-order messages for '${destination}', but none were detected`,\n          );\n        }\n        if (!options.hasOutOfOrder && outOfOrder.length > 0) {\n          throw new Error(\n            `Expected no out-of-order messages for '${destination}', but ${outOfOrder.length} were detected`,\n          );\n        }\n      }\n\n      if (options.hasDLQ !== undefined) {\n        const dlqCalls = calls.filter((c) => c.dlqReason !== undefined);\n        if (options.hasDLQ && dlqCalls.length === 0) {\n          throw new Error(\n            `Expected DLQ routing for '${destination}', but none occurred`,\n          );\n        }\n        if (!options.hasDLQ && dlqCalls.length > 0) {\n          throw new Error(\n            `Expected no DLQ routing for '${destination}', but ${dlqCalls.length} occurred`,\n          );\n        }\n      }\n    },\n\n    assertConsumerNotCalled(destination?: string) {\n      if (destination) {\n        const calls = consumerCalls.filter(\n          (c) => c.destination === destination,\n        );\n        if (calls.length > 0) {\n          throw new Error(\n            `Expected consumer not to be called for '${destination}', but it processed ${calls.length} messages`,\n          );\n        }\n      } else {\n        if (consumerCalls.length > 0) {\n          throw new Error(\n            `Expected no consumer calls, but ${consumerCalls.length} messages were processed`,\n          );\n        }\n      }\n    },\n\n    assertRebalanceOccurred(\n      destination: string,\n      type: RebalanceEvent['type'],\n      partitionCount?: number,\n    ) {\n      const events = rebalanceEvents.filter(\n        (e) => e.destination === destination && e.type === type,\n      );\n\n      if (events.length === 0) {\n        throw new Error(\n          `Expected rebalance '${type}' for '${destination}', but none occurred`,\n        );\n      }\n\n      if (partitionCount !== undefined) {\n        const matching = events.filter(\n          (e) => e.partitions.length === partitionCount,\n        );\n        if (matching.length === 0) {\n          throw new Error(\n            `Expected rebalance '${type}' for '${destination}' with ${partitionCount} partitions, but none matched`,\n          );\n        }\n      }\n    },\n\n    getProducerCalls(destination?: string) {\n      if (destination) {\n        return producerCalls.filter((c) => c.destination === destination);\n      }\n      return [...producerCalls];\n    },\n\n    getConsumerCalls(destination?: string) {\n      if (destination) {\n        return consumerCalls.filter((c) => c.destination === destination);\n      }\n      return [...consumerCalls];\n    },\n\n    getLastProducerCall(destination?: string) {\n      const calls = this.getProducerCalls(destination);\n      return calls.at(-1);\n    },\n\n    getLastConsumerCall(destination?: string) {\n      const calls = this.getConsumerCalls(destination);\n      return calls.at(-1);\n    },\n\n    reset() {\n      producerCalls.length = 0;\n      consumerCalls.length = 0;\n      rebalanceEvents.length = 0;\n    },\n\n    shutdown() {\n      this.reset();\n    },\n  };\n}\n\n// ============================================================================\n// Mock Broker\n// ============================================================================\n\n/**\n * Mock message broker for testing\n */\nexport interface MockMessageBroker {\n  /** Topics/queues in the broker */\n  topics: Map<string, MockMessage[]>;\n\n  /**\n   * Publish a message to a topic\n   */\n  publish(topic: string, message: MockMessage): void;\n\n  /**\n   * Consume messages from a topic\n   */\n  consume(topic: string, count?: number): MockMessage[];\n\n  /**\n   * Peek at messages without consuming\n   */\n  peek(topic: string, count?: number): MockMessage[];\n\n  /**\n   * Get message count for topic\n   */\n  getMessageCount(topic: string): number;\n\n  /**\n   * Clear all messages\n   */\n  clear(topic?: string): void;\n\n  /**\n   * Create a topic\n   */\n  createTopic(topic: string): void;\n\n  /**\n   * Delete a topic\n   */\n  deleteTopic(topic: string): void;\n\n  /**\n   * List all topics\n   */\n  listTopics(): string[];\n}\n\n/**\n * Create a mock message broker for testing\n *\n * Simulates a message broker (Kafka, SQS, RabbitMQ, etc.) for unit testing.\n *\n * @example\n * ```typescript\n * const broker = createMockMessageBroker();\n *\n * // Producer publishes\n * broker.publish('orders', { payload: { orderId: '123' }, headers: {} });\n *\n * // Consumer receives\n * const messages = broker.consume('orders');\n * expect(messages).toHaveLength(1);\n * expect(messages[0].payload).toEqual({ orderId: '123' });\n * ```\n */\nexport function createMockMessageBroker(): MockMessageBroker {\n  const topics = new Map<string, MockMessage[]>();\n\n  return {\n    topics,\n\n    publish(topic: string, message: MockMessage) {\n      if (!topics.has(topic)) {\n        topics.set(topic, []);\n      }\n      topics.get(topic)!.push({\n        ...message,\n        timestamp: message.timestamp ?? Date.now(),\n        offset: message.offset ?? topics.get(topic)!.length,\n      });\n    },\n\n    consume(topic: string, count?: number) {\n      const messages = topics.get(topic) ?? [];\n      if (count === undefined) {\n        const all = [...messages];\n        messages.length = 0;\n        return all;\n      }\n      return messages.splice(0, count);\n    },\n\n    peek(topic: string, count?: number) {\n      const messages = topics.get(topic) ?? [];\n      if (count === undefined) {\n        return [...messages];\n      }\n      return messages.slice(0, count);\n    },\n\n    getMessageCount(topic: string) {\n      return topics.get(topic)?.length ?? 0;\n    },\n\n    clear(topic?: string) {\n      if (topic) {\n        topics.set(topic, []);\n      } else {\n        topics.clear();\n      }\n    },\n\n    createTopic(topic: string) {\n      if (!topics.has(topic)) {\n        topics.set(topic, []);\n      }\n    },\n\n    deleteTopic(topic: string) {\n      topics.delete(topic);\n    },\n\n    listTopics() {\n      return [...topics.keys()];\n    },\n  };\n}\n\n// ============================================================================\n// Context Propagation Helpers\n// ============================================================================\n\n/**\n * Extract trace ID from traceparent header\n */\nexport function extractTraceIdFromHeader(traceparent: string): string | null {\n  const parts = traceparent.split('-');\n  if (parts.length >= 3 && parts[1] !== undefined) {\n    return parts[1];\n  }\n  return null;\n}\n\n/**\n * Extract span ID from traceparent header\n */\nexport function extractSpanIdFromHeader(traceparent: string): string | null {\n  const parts = traceparent.split('-');\n  if (parts.length >= 4 && parts[2] !== undefined) {\n    return parts[2];\n  }\n  return null;\n}\n\n/**\n * Create a mock span context\n */\nexport function createMockSpanContext(\n  traceId?: string,\n  spanId?: string,\n): SpanContext {\n  return {\n    traceId: traceId ?? randomHex(32),\n    spanId: spanId ?? randomHex(16),\n    traceFlags: 1,\n    isRemote: true,\n  };\n}\n\n/**\n * Create a mock link to a producer span\n */\nexport function createMockProducerLink(\n  traceId?: string,\n  spanId?: string,\n): Link {\n  return {\n    context: createMockSpanContext(traceId, spanId),\n    attributes: {\n      'messaging.link.source': 'producer',\n    },\n  };\n}\n\n// ============================================================================\n// Scenario Builders\n// ============================================================================\n\n/**\n * Create a batch of mock messages\n */\nexport function createMockMessageBatch<T>(\n  payloads: T[],\n  options: {\n    startOffset?: number;\n    partition?: number;\n    addTraceHeaders?: boolean;\n    traceId?: string;\n  } = {},\n): MockMessage<T>[] {\n  const startOffset = options.startOffset ?? 0;\n  const addTraceHeaders = options.addTraceHeaders ?? true;\n  const traceId = options.traceId ?? randomHex(32);\n\n  return payloads.map((payload, index) => ({\n    payload,\n    headers: addTraceHeaders\n      ? { traceparent: `00-${traceId}-${randomHex(16)}-01` }\n      : undefined,\n    offset: startOffset + index,\n    partition: options.partition ?? 0,\n    messageId: `msg-${randomHex(8)}`,\n    timestamp: Date.now() + index,\n  }));\n}\n\n/**\n * Create a rebalance scenario\n */\nexport function createRebalanceScenario(\n  topic: string,\n  consumerGroup: string,\n  partitions: number[],\n): {\n  assignEvent: RecordedRebalanceEvent;\n  revokeEvent: RecordedRebalanceEvent;\n} {\n  const assignments: PartitionAssignment[] = partitions.map((p) => ({\n    topic,\n    partition: p,\n    offset: 0,\n  }));\n\n  return {\n    assignEvent: {\n      type: 'assigned',\n      partitions: assignments,\n      timestamp: Date.now(),\n      generation: 1,\n      destination: topic,\n      consumerGroup,\n    },\n    revokeEvent: {\n      type: 'revoked',\n      partitions: assignments,\n      timestamp: Date.now() + 1000,\n      generation: 2,\n      destination: topic,\n      consumerGroup,\n    },\n  };\n}\n\n/**\n * Create an out-of-order scenario\n */\nexport function createOutOfOrderScenario<T>(\n  payloads: T[],\n  outOfOrderIndices: number[],\n): MockMessage<T>[] {\n  const messages = createMockMessageBatch(payloads, { addTraceHeaders: true });\n\n  // Shuffle specified indices to create out-of-order scenario\n  const shuffled = [...messages];\n  for (const index of outOfOrderIndices) {\n    if (index > 0 && index < shuffled.length) {\n      // Swap with previous to create out-of-order\n      const prev = shuffled[index - 1]!;\n      const curr = shuffled[index]!;\n      shuffled[index - 1] = curr;\n      shuffled[index] = prev;\n    }\n  }\n\n  return shuffled;\n}\n\n/**\n * Create a duplicate message scenario\n */\nexport function createDuplicateScenario<T>(\n  payloads: T[],\n  duplicateIndices: number[],\n): MockMessage<T>[] {\n  const messages = createMockMessageBatch(payloads, { addTraceHeaders: true });\n  const result = [...messages];\n\n  for (const index of duplicateIndices) {\n    const originalMessage = messages[index];\n    if (index >= 0 && index < messages.length && originalMessage) {\n      // Insert duplicate after the original\n      result.splice(index + 1, 0, { ...originalMessage });\n    }\n  }\n\n  return result;\n}\n"],"mappings":"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"}