{"version":3,"sources":["../src/testing.ts"],"names":[],"mappings":"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","file":"testing.cjs","sourcesContent":["/**\n * `@ar-agents/whatsapp/testing` — fixtures + mock client for tests.\n *\n * What you get:\n *\n *   - **Factories**: `mockIncomingTextEnvelope`, `mockIncomingButtonReply`,\n *     `mockIncomingListReply`, `mockMessageStatusEnvelope`. They produce the\n *     raw Meta-shaped JSON envelope (the body Meta posts to your webhook),\n *     ready to feed into `parseWebhookEvents`.\n *\n *   - **`mockSendTextResult`** / **`mockTemplateResult`** — the response\n *     shape Meta returns from `POST /messages`.\n *\n *   - **`mockSignedWebhook`** — produces a `{ rawBody, headers }` pair whose\n *     `x-hub-signature-256` header passes `verifyWebhookSignature` against\n *     the same `appSecret`. Drops directly into your webhook-handler test.\n *\n *   - **`MockWhatsAppClient`** — stand-in for `WhatsAppClient`. Records\n *     every method call so tests assert on what was sent without hitting\n *     the live Meta Graph.\n */\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Raw incoming envelope shape — what Meta posts to your webhook\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type RawWebhookEnvelope = {\n  object: \"whatsapp_business_account\";\n  entry: Array<{\n    id: string;\n    changes: Array<{\n      field: \"messages\";\n      value: Record<string, unknown>;\n    }>;\n  }>;\n};\n\nlet counter = 0;\nconst nextId = () => `wamid.HBgN${(++counter).toString().padStart(8, \"0\")}`;\n\nconst DEFAULT_PHONE = \"5491155555555\";\nconst DEFAULT_PHONE_NUMBER_ID = \"1234567890123456\";\nconst DEFAULT_DISPLAY_PHONE = \"+54 9 11 5555-5555\";\n\nfunction envelope(value: Record<string, unknown>): RawWebhookEnvelope {\n  return {\n    object: \"whatsapp_business_account\",\n    entry: [{ id: \"100000000000000\", changes: [{ field: \"messages\", value }] }],\n  };\n}\n\nexport function mockIncomingTextEnvelope(\n  overrides: { from?: string; body?: string; messageId?: string; ts?: number } = {},\n): RawWebhookEnvelope {\n  const ts = String(overrides.ts ?? Math.floor(Date.now() / 1000));\n  return envelope({\n    messaging_product: \"whatsapp\",\n    metadata: {\n      display_phone_number: DEFAULT_DISPLAY_PHONE,\n      phone_number_id: DEFAULT_PHONE_NUMBER_ID,\n    },\n    contacts: [\n      {\n        profile: { name: \"Test Contact\" },\n        wa_id: overrides.from ?? DEFAULT_PHONE,\n      },\n    ],\n    messages: [\n      {\n        from: overrides.from ?? DEFAULT_PHONE,\n        id: overrides.messageId ?? nextId(),\n        timestamp: ts,\n        type: \"text\",\n        text: { body: overrides.body ?? \"Hola\" },\n      },\n    ],\n  });\n}\n\nexport function mockIncomingButtonReply(\n  overrides: { from?: string; buttonId?: string; buttonTitle?: string } = {},\n): RawWebhookEnvelope {\n  return envelope({\n    messaging_product: \"whatsapp\",\n    metadata: {\n      display_phone_number: DEFAULT_DISPLAY_PHONE,\n      phone_number_id: DEFAULT_PHONE_NUMBER_ID,\n    },\n    contacts: [{ profile: { name: \"Test\" }, wa_id: overrides.from ?? DEFAULT_PHONE }],\n    messages: [\n      {\n        from: overrides.from ?? DEFAULT_PHONE,\n        id: nextId(),\n        timestamp: String(Math.floor(Date.now() / 1000)),\n        type: \"interactive\",\n        interactive: {\n          type: \"button_reply\",\n          button_reply: {\n            id: overrides.buttonId ?? \"btn_yes\",\n            title: overrides.buttonTitle ?? \"Sí\",\n          },\n        },\n      },\n    ],\n  });\n}\n\nexport function mockIncomingListReply(\n  overrides: { from?: string; rowId?: string; rowTitle?: string } = {},\n): RawWebhookEnvelope {\n  return envelope({\n    messaging_product: \"whatsapp\",\n    metadata: {\n      display_phone_number: DEFAULT_DISPLAY_PHONE,\n      phone_number_id: DEFAULT_PHONE_NUMBER_ID,\n    },\n    contacts: [{ profile: { name: \"Test\" }, wa_id: overrides.from ?? DEFAULT_PHONE }],\n    messages: [\n      {\n        from: overrides.from ?? DEFAULT_PHONE,\n        id: nextId(),\n        timestamp: String(Math.floor(Date.now() / 1000)),\n        type: \"interactive\",\n        interactive: {\n          type: \"list_reply\",\n          list_reply: {\n            id: overrides.rowId ?? \"row_1\",\n            title: overrides.rowTitle ?? \"Plan Pro\",\n          },\n        },\n      },\n    ],\n  });\n}\n\nexport function mockMessageStatusEnvelope(\n  args: {\n    messageId?: string;\n    status?: \"sent\" | \"delivered\" | \"read\" | \"failed\";\n    to?: string;\n  } = {},\n): RawWebhookEnvelope {\n  return envelope({\n    messaging_product: \"whatsapp\",\n    metadata: {\n      display_phone_number: DEFAULT_DISPLAY_PHONE,\n      phone_number_id: DEFAULT_PHONE_NUMBER_ID,\n    },\n    statuses: [\n      {\n        id: args.messageId ?? nextId(),\n        status: args.status ?? \"delivered\",\n        timestamp: String(Math.floor(Date.now() / 1000)),\n        recipient_id: args.to ?? DEFAULT_PHONE,\n      },\n    ],\n  });\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Outgoing send results\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport function mockSendTextResult(overrides: { wamid?: string; to?: string } = {}) {\n  return {\n    messaging_product: \"whatsapp\" as const,\n    contacts: [\n      { wa_id: overrides.to ?? DEFAULT_PHONE, input: overrides.to ?? DEFAULT_PHONE },\n    ],\n    messages: [{ id: overrides.wamid ?? nextId(), message_status: \"accepted\" as const }],\n  };\n}\n\nexport function mockTemplateResult(overrides: { wamid?: string; to?: string } = {}) {\n  return mockSendTextResult(overrides);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Signed webhook\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Produce a `{ rawBody, headers }` pair whose `x-hub-signature-256` is a\n * real HMAC-SHA256 against `appSecret`. Pass to `verifyWebhookSignature`\n * (from `@ar-agents/whatsapp`) and it'll accept it.\n */\nexport async function mockSignedWebhook(args: {\n  appSecret: string;\n  envelope?: RawWebhookEnvelope;\n}): Promise<{ rawBody: string; headers: Headers; envelope: RawWebhookEnvelope }> {\n  const env = args.envelope ?? mockIncomingTextEnvelope();\n  const rawBody = JSON.stringify(env);\n\n  const enc = new TextEncoder();\n  const key = await crypto.subtle.importKey(\n    \"raw\",\n    enc.encode(args.appSecret),\n    { name: \"HMAC\", hash: \"SHA-256\" },\n    false,\n    [\"sign\"],\n  );\n  const sigBytes = await crypto.subtle.sign(\"HMAC\", key, enc.encode(rawBody));\n  const hex = Array.from(new Uint8Array(sigBytes))\n    .map((b) => b.toString(16).padStart(2, \"0\"))\n    .join(\"\");\n\n  const headers = new Headers({\n    \"content-type\": \"application/json\",\n    \"x-hub-signature-256\": `sha256=${hex}`,\n  });\n  return { rawBody, headers, envelope: env };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// MockWhatsAppClient\n// ─────────────────────────────────────────────────────────────────────────────\n\ntype Recorded =\n  | { method: \"sendText\"; args: { to: string; body: string } }\n  | { method: \"sendTemplate\"; args: { to: string; templateName: string; languageCode: string } }\n  | { method: \"sendMedia\"; args: { to: string; mediaType: string; url: string } }\n  | { method: \"sendButtons\"; args: { to: string; body: string; buttons: unknown } }\n  | { method: \"sendList\"; args: { to: string; body: string; sections: unknown } }\n  | { method: \"markRead\"; args: { messageId: string } };\n\nexport class MockWhatsAppClient {\n  /** Append-only log of every method call. Inspect in your test assertions. */\n  readonly calls: Recorded[] = [];\n\n  async sendText(to: string, body: string) {\n    this.calls.push({ method: \"sendText\", args: { to, body } });\n    return mockSendTextResult({ to });\n  }\n\n  async sendTemplate(to: string, templateName: string, languageCode = \"es_AR\") {\n    this.calls.push({ method: \"sendTemplate\", args: { to, templateName, languageCode } });\n    return mockSendTextResult({ to });\n  }\n\n  async sendMedia(to: string, mediaType: string, url: string) {\n    this.calls.push({ method: \"sendMedia\", args: { to, mediaType, url } });\n    return mockSendTextResult({ to });\n  }\n\n  async sendButtons(to: string, body: string, buttons: unknown) {\n    this.calls.push({ method: \"sendButtons\", args: { to, body, buttons } });\n    return mockSendTextResult({ to });\n  }\n\n  async sendList(to: string, body: string, sections: unknown) {\n    this.calls.push({ method: \"sendList\", args: { to, body, sections } });\n    return mockSendTextResult({ to });\n  }\n\n  async markRead(messageId: string) {\n    this.calls.push({ method: \"markRead\", args: { messageId } });\n    return { success: true };\n  }\n\n  /** Reset the recorded calls between tests. */\n  reset() {\n    this.calls.length = 0;\n  }\n}\n"]}