// Npm Telegram Live tests cover npm telegram live script behavior.
import { execFileSync } from "node:child_process";
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { afterEach, describe, expect, it } from "vitest";
import { testing } from "../../scripts/e2e/npm-telegram-live-runner.ts";
import { privateLocalOnlyPluginSdkEntrypoints } from "../../scripts/lib/plugin-sdk-entries.mts";

const TEST_DIR = path.dirname(fileURLToPath(import.meta.url));
const DOCKER_SCRIPT_PATH = path.resolve(TEST_DIR, "../../scripts/e2e/npm-telegram-live-docker.sh");
const PREPARE_PACKAGE_PATH = path.resolve(
  TEST_DIR,
  "../../scripts/e2e/lib/npm-telegram-live/prepare-package.mts",
);
const tempRoots: string[] = [];

function mkTempRoot() {
  const root = mkdtempSync(path.join(tmpdir(), "openclaw-npm-telegram-live-"));
  tempRoots.push(root);
  return root;
}

afterEach(() => {
  for (const root of tempRoots.splice(0)) {
    rmSync(root, { force: true, recursive: true });
  }
});

describe("package Telegram live Docker E2E", () => {
  it("supports npm-specific Convex credential aliases", () => {
    const script = readFileSync(DOCKER_SCRIPT_PATH, "utf8");

    expect(script).toContain("OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE");
    expect(script).toContain("OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE");
    expect(script).toContain('docker_env+=(-e OPENCLAW_QA_CREDENTIAL_SOURCE="$credential_source")');
    expect(script).toContain('docker_env+=(-e OPENCLAW_QA_CREDENTIAL_ROLE="$credential_role")');
  });

  it("defaults CI runs to Convex when broker credentials are present", () => {
    const script = readFileSync(DOCKER_SCRIPT_PATH, "utf8");

    expect(script).toContain(
      'if [ -n "${CI:-}" ] && [ -n "${OPENCLAW_QA_CONVEX_SITE_URL:-}" ]; then',
    );
    expect(script).toContain("OPENCLAW_QA_CONVEX_SECRET_CI");
    expect(script).toContain("OPENCLAW_QA_CONVEX_SECRET_MAINTAINER");
    expect(script).toContain('printf "convex"');
  });

  it("installs the package candidate before forwarding runtime secrets", () => {
    const script = readFileSync(DOCKER_SCRIPT_PATH, "utf8");
    const installRunStart = script.indexOf('echo "Running package Telegram live Docker E2E');
    const installRunEnd = script.indexOf("# Mount the trusted current-source QA harness");
    const installRun = script.slice(installRunStart, installRunEnd);

    expect(installRunStart).toBeGreaterThanOrEqual(0);
    expect(installRunEnd).toBeGreaterThan(installRunStart);
    expect(installRun).toContain(
      '-e OPENCLAW_E2E_NPM_INSTALL_TIMEOUT="${OPENCLAW_E2E_NPM_INSTALL_TIMEOUT:-600s}"',
    );
    expect(installRun).toContain(
      '"$timeout_bin" --kill-after=30s "$npm_install_timeout" npm install -g "$install_source" --no-fund --no-audit',
    );
    expect(installRun).toContain("elif command -v gtimeout >/dev/null 2>&1; then");
    expect(installRun).toContain('timeout_bin="gtimeout"');
    expect(installRun).toContain(
      'echo "timeout or gtimeout is required for OPENCLAW_E2E_NPM_INSTALL_TIMEOUT=$npm_install_timeout" >&2',
    );
    expect(installRun).toContain('"$timeout_bin" --kill-after=1s 1s true >/dev/null 2>&1');
    expect(installRun).toContain(
      '"$timeout_bin" "$npm_install_timeout" npm install -g "$install_source" --no-fund --no-audit',
    );
    expect(installRun).toContain('npm install -g "$install_source" --no-fund --no-audit');
    expect(installRun).not.toContain(
      "running package install without OPENCLAW_E2E_NPM_INSTALL_TIMEOUT",
    );
    expect(installRun).toContain('"${package_mount_args[@]}"');
    expect(installRun).not.toContain('"${docker_env[@]}"');
    expect(installRun).toContain(
      'run_logged_print_heartbeat "npm-telegram-package-install" 60 docker_e2e_docker_run_cmd run --rm',
    );
    expect(installRun).not.toContain("run_logged_print_heartbeat docker run --rm");
    expect(script).toContain(
      'run_logged_print_heartbeat "npm-telegram-live-suite" 60 docker_e2e_run_with_harness',
    );
    expect(script).not.toContain('cat "$run_log"');
    expect(script).toContain('"${docker_env[@]}"');
    expect(script).toContain(
      'if [ -z "$credential_role" ] && [ "$credential_source" = "convex" ]; then',
    );
    expect(script).toContain('credential_role="ci"');
    expect(script).toContain('credential_role="maintainer"');
  });

  it("bounds installed-package hot path OpenClaw commands", () => {
    const script = readFileSync(DOCKER_SCRIPT_PATH, "utf8");
    const runtimeRunStart = script.indexOf("# Mount the trusted current-source QA harness");
    const runtimeRun = script.slice(runtimeRunStart);

    expect(runtimeRunStart).toBeGreaterThanOrEqual(0);
    expect(script).toContain(
      '-e OPENCLAW_E2E_COMMAND_TIMEOUT="${OPENCLAW_E2E_COMMAND_TIMEOUT:-300s}"',
    );
    expect(runtimeRun).toContain("source scripts/lib/openclaw-e2e-instance.sh");
    expect(runtimeRun).toContain('sut_command="/npm-global/bin/openclaw"');
    expect(runtimeRun).toContain('openclaw_e2e_run_command "$sut_command" --version');
    expect(runtimeRun).toContain('openclaw_e2e_run_command "$sut_command" onboard');
    expect(runtimeRun).toContain(
      'OPENAI_API_KEY="$hotpath_model_value" openclaw_e2e_run_command "$sut_command" onboard',
    );
    expect(runtimeRun).not.toContain("export OPENAI_API_KEY=");
    expect(runtimeRun).toContain('openclaw_e2e_run_command "$sut_command" channels add');
    expect(runtimeRun).toContain('openclaw_e2e_run_command "$sut_command" doctor --fix');
    expect(runtimeRun).toContain(
      'openclaw_e2e_run_command "$sut_command" doctor --non-interactive',
    );
    expect(runtimeRun).toContain('export OPENCLAW_NPM_TELEGRAM_SUT_COMMAND="$sut_command"');
    expect(runtimeRun).toContain('openclaw_e2e_print_log "$file"');
    expect(runtimeRun).not.toContain("sed -n '1,220p'");
    expect(runtimeRun).not.toMatch(/^\s*openclaw (onboard|channels add|doctor )/mu);
  });

  it("isolates onboarding hot-path config from the live suite", () => {
    const script = readFileSync(DOCKER_SCRIPT_PATH, "utf8");

    expect(script).toContain(
      'runtime_home="$(mktemp -d "/tmp/openclaw-npm-telegram-runtime.XXXXXX")"',
    );
    expect(script).toContain(
      'hotpath_home="$(mktemp -d "/tmp/openclaw-npm-telegram-hotpath.XXXXXX")"',
    );
    expect(script).toContain('export HOME="$hotpath_home"');
    expect(script).toContain('export HOME="$runtime_home"');
  });

  it("fails fast after the first package Telegram scenario failure", () => {
    const runner = readFileSync(
      path.resolve(TEST_DIR, "../../scripts/e2e/npm-telegram-live-runner.ts"),
      "utf8",
    );

    expect(runner).toContain("failFast: true");
  });

  it("can install a resolved package tarball instead of a registry spec", () => {
    const script = readFileSync(DOCKER_SCRIPT_PATH, "utf8");

    expect(script).toContain("OPENCLAW_NPM_TELEGRAM_PACKAGE_TGZ");
    expect(script).toContain("OPENCLAW_CURRENT_PACKAGE_TGZ");
    expect(script).toContain('-e OPENCLAW_QA_PACKAGE_SOURCE="$package_install_source"');
    expect(script).toContain('-e OPENCLAW_QA_PACKAGE_SOURCE_KIND="$package_source_kind"');
    expect(script).toContain("OPENCLAW_QA_PACKAGE_SOURCE_SHA");
    expect(script).toContain(
      'package_mount_args=(-v "$resolved_package_tgz:$package_install_source:ro")',
    );
    expect(script).toContain('validate_openclaw_package_spec "$PACKAGE_SPEC"');
    expect(script.indexOf('if [ -n "$resolved_package_tgz" ]; then')).toBeLessThan(
      script.indexOf('validate_openclaw_package_spec "$PACKAGE_SPEC"'),
    );
  });

  it("installs prepared root and companion tarballs through an exact local registry", () => {
    const script = readFileSync(DOCKER_SCRIPT_PATH, "utf8");

    expect(script).toContain("OPENCLAW_NPM_TELEGRAM_PACKAGE_DIR");
    expect(script).toContain('package_source_kind="prepared-package-set"');
    expect(script).toContain('package_install_source="openclaw@$(read_package_version');
    expect(script).toContain('-v "$resolved_package_dir:/package-under-test:ro"');
    expect(script).toContain(
      '-v "$ROOT_DIR/scripts/lib/bounded-response.mjs:/tmp/lib/bounded-response.mjs:ro"',
    );
    expect(script).toContain(
      '-v "$ROOT_DIR/scripts/e2e/lib/plugins/npm-registry-server.mjs:/tmp/openclaw-e2e/lib/plugins/npm-registry-server.mjs:ro"',
    );
    expect(script).toContain("OPENCLAW_NPM_TELEGRAM_PACKAGE_SET");
    expect(script).toContain("node /tmp/openclaw-e2e/lib/plugins/npm-registry-server.mjs");
    expect(script).toContain("OPENCLAW_NPM_REGISTRY_UPSTREAM=https://registry.npmjs.org");
    expect(script).toContain('export NPM_CONFIG_REGISTRY="$registry_url"');
  });

  it("keeps live Docker artifacts isolated by default", () => {
    const script = readFileSync(DOCKER_SCRIPT_PATH, "utf8");

    expect(script).toContain(
      'RUN_ID="${OPENCLAW_NPM_TELEGRAM_RUN_ID:-$(date -u +%Y%m%dT%H%M%SZ)-$$}"',
    );
    expect(script).toContain(
      'OUTPUT_DIR="${OPENCLAW_NPM_TELEGRAM_OUTPUT_DIR:-.artifacts/qa-e2e/npm-telegram-live/$RUN_ID}"',
    );
    expect(script).toContain(
      'OUTPUT_DIR_CONTAINER_RELATIVE=".artifacts/qa-e2e/npm-telegram-live-output"',
    );
    expect(script).toContain('OUTPUT_DIR_CONTAINER="/app/$OUTPUT_DIR_CONTAINER_RELATIVE"');
    expect(script).toContain(
      '-e OPENCLAW_NPM_TELEGRAM_OUTPUT_DIR="$OUTPUT_DIR_CONTAINER_RELATIVE"',
    );
    expect(script).not.toContain(
      'OUTPUT_DIR="${OPENCLAW_NPM_TELEGRAM_OUTPUT_DIR:-.artifacts/qa-e2e/npm-telegram-live}"',
    );
  });

  it("uses unique direct-run output dirs by default", () => {
    const repoRoot = mkTempRoot();
    const firstDir = testing.resolvePackageTelegramOutputDir({}, repoRoot);
    const secondDir = testing.resolvePackageTelegramOutputDir({}, repoRoot);

    expect(path.dirname(firstDir)).toBe(path.join(repoRoot, ".artifacts", "qa-e2e"));
    expect(path.basename(firstDir)).toMatch(/^npm-telegram-live-[a-z0-9]+-[a-f0-9]{8}$/u);
    expect(secondDir).not.toBe(firstDir);
    expect(
      testing.resolvePackageTelegramOutputDir(
        { OPENCLAW_NPM_TELEGRAM_OUTPUT_DIR: ".artifacts/custom" },
        repoRoot,
      ),
    ).toBe(".artifacts/custom");
  });

  it("keeps the installed OpenClaw command as the package SUT", async () => {
    const prefix = mkTempRoot();
    const command = path.join(prefix, "bin", "openclaw");
    const harnessCommand = path.join(mkTempRoot(), "bin", "openclaw");
    mkdirSync(path.dirname(command), { recursive: true });
    mkdirSync(path.dirname(harnessCommand), { recursive: true });
    writeFileSync(command, "#!/bin/sh\n", { mode: 0o755 });
    writeFileSync(harnessCommand, "#!/bin/sh\n", { mode: 0o755 });

    await expect(
      testing.resolveTrustedOpenClawCommand(command, {
        NPM_CONFIG_PREFIX: prefix,
      }),
    ).resolves.toEqual({
      executablePath: command,
      usePackagedPlugins: true,
    });
    await expect(
      testing.resolveTrustedOpenClawCommand(harnessCommand, {
        NPM_CONFIG_PREFIX: prefix,
      }),
    ).rejects.toThrow("OPENCLAW_NPM_TELEGRAM_SUT_COMMAND must resolve inside NPM_CONFIG_PREFIX.");
  });

  it("mounts the QA taxonomy without exposing the repository root", () => {
    const script = readFileSync(DOCKER_SCRIPT_PATH, "utf8");

    expect(script).toContain('-v "$ROOT_DIR/taxonomy.yaml:/app/taxonomy.yaml:ro"');
    expect(script).not.toContain('-v "$ROOT_DIR:/app');
  });

  it("mounts configured output paths before entering the container", () => {
    const script = readFileSync(DOCKER_SCRIPT_PATH, "utf8");
    const dockerEnvStart = script.indexOf("docker_env=(");
    const dockerEnvEnd = script.indexOf(")\n\nforward_env_if_set", dockerEnvStart);
    const dockerEnv = script.slice(dockerEnvStart, dockerEnvEnd);

    expect(script).toContain('*) OUTPUT_DIR_HOST="$ROOT_DIR/$OUTPUT_DIR" ;;');
    expect(script).toContain('mkdir -p "$OUTPUT_DIR_HOST"');
    expect(script).toContain(
      'printf \'schema=1\\nexit_code=%s\\nlive_output=job_log\\n\' "$rc" > "$OUTPUT_DIR_HOST/run-metadata.txt"',
    );
    expect(script).toContain("trap cleanup EXIT");
    expect(dockerEnv).toContain(
      '-e OPENCLAW_NPM_TELEGRAM_OUTPUT_DIR="$OUTPUT_DIR_CONTAINER_RELATIVE"',
    );
    expect(dockerEnv).not.toContain('-e OPENCLAW_NPM_TELEGRAM_OUTPUT_DIR="$OUTPUT_DIR_CONTAINER"');
    expect(dockerEnv).not.toContain('-e OPENCLAW_NPM_TELEGRAM_OUTPUT_DIR="$OUTPUT_DIR"');
    expect(script).toContain('-v "$OUTPUT_DIR_HOST:$OUTPUT_DIR_CONTAINER"');
  });

  it("uses the container temp root for OpenClaw runtime scratch files", () => {
    const script = readFileSync(DOCKER_SCRIPT_PATH, "utf8");
    const dockerEnvStart = script.indexOf("docker_env=(");
    const dockerEnvEnd = script.indexOf(")\n\nforward_env_if_set", dockerEnvStart);
    const dockerEnv = script.slice(dockerEnvStart, dockerEnvEnd);

    expect(dockerEnvStart).toBeGreaterThanOrEqual(0);
    expect(dockerEnvEnd).toBeGreaterThan(dockerEnvStart);
    expect(dockerEnv).toContain("-e TMPDIR=/tmp");
  });

  it("forwards repeated RTT controls to the package Telegram live lane", () => {
    const script = readFileSync(DOCKER_SCRIPT_PATH, "utf8");

    expect(script).toContain("OPENCLAW_NPM_TELEGRAM_RTT_SAMPLES");
    expect(script).toContain("OPENCLAW_NPM_TELEGRAM_RTT_TIMEOUT_MS");
    expect(script).toContain("OPENCLAW_NPM_TELEGRAM_RTT_MAX_FAILURES");
    expect(script).toContain("OPENCLAW_NPM_TELEGRAM_RTT_CHECKS");
  });

  it("isolates the trusted private QA harness from the installed package candidate", () => {
    const script = readFileSync(DOCKER_SCRIPT_PATH, "utf8");
    expect(script).toContain('cp "$ROOT_DIR/package.json" "$harness_package_json"');
    expect(script).toContain(
      'node --import tsx "$ROOT_DIR/scripts/e2e/lib/npm-telegram-live/prepare-package.mts" "$harness_package_json"',
    );
    expect(script).toContain('-v "$harness_package_json:/app/package.json:ro"');
    expect(script).toContain('-v "$ROOT_DIR/dist:/app/dist:ro"');
    expect(script).toContain('-v "$ROOT_DIR/node_modules:/trusted-harness/node_modules:ro"');
    expect(script).toContain('-v "$ROOT_DIR/packages:/app/packages:ro"');
    expect(script).toContain('-v "$ROOT_DIR/extensions:/app/extensions:ro"');
    expect(script).toContain('-v "$ROOT_DIR/taxonomy.yaml:/app/taxonomy.yaml:ro"');
    expect(script).toContain('-v "$ROOT_DIR/qa/scenarios:/app/qa/scenarios:ro"');
    expect(script).toContain("for dependency_dir in /trusted-harness/node_modules/*");
    expect(script).toContain("for workspace_dir in /app/packages/* /app/extensions/*");
    expect(script).toContain('link_harness_dependency "$workspace_dir" "$workspace_name"');
    expect(script).toContain("link_harness_dependency /app openclaw");
    expect(script).not.toContain('openclaw_package_dir="/npm-global/lib/node_modules/openclaw"');
    expect(script).not.toContain('cp "$openclaw_package_dir/package.json" /app/package.json');
    expect(script).not.toContain("/app/node_modules/openclaw/package.json");
    expect(script).not.toContain("link_installed_package_dependency");
  });

  it("adds private SDK exports only to the trusted harness manifest", () => {
    const root = mkTempRoot();
    const harnessManifestPath = path.join(root, "harness-package.json");
    const candidateManifestPath = path.join(root, "candidate-package.json");
    const existingGatewayExport = {
      types: "./existing/gateway-runtime.d.ts",
      default: "./existing/gateway-runtime.js",
    };
    writeFileSync(
      harnessManifestPath,
      `${JSON.stringify({
        name: "openclaw",
        exports: {
          "./kept": "./dist/kept.js",
          "./plugin-sdk/gateway-runtime": existingGatewayExport,
        },
      })}\n`,
    );
    writeFileSync(candidateManifestPath, '{"name":"candidate","exports":{}}\n');
    const candidateBefore = readFileSync(candidateManifestPath, "utf8");

    execFileSync(process.execPath, [PREPARE_PACKAGE_PATH, harnessManifestPath]);

    const prepared = JSON.parse(readFileSync(harnessManifestPath, "utf8")) as {
      exports: Record<string, unknown>;
    };
    expect(prepared.exports["./kept"]).toBe("./dist/kept.js");
    expect(prepared.exports["./plugin-sdk/gateway-runtime"]).toEqual(existingGatewayExport);
    expect(prepared.exports["./plugin-sdk/qa-runtime"]).toEqual({
      default: "./dist/plugin-sdk/qa-runtime.js",
    });
    expect(prepared.exports["./plugin-sdk/qa-lab"]).toEqual({
      default: "./dist/plugin-sdk/qa-lab.js",
    });
    for (const subpath of privateLocalOnlyPluginSdkEntrypoints) {
      expect(prepared.exports[`./plugin-sdk/${subpath}`]).toEqual({
        default: `./dist/plugin-sdk/${subpath}.js`,
      });
    }
    expect(readFileSync(candidateManifestPath, "utf8")).toBe(candidateBefore);
  });

  it("lets npm-specific credential aliases override shared QA env", () => {
    expect(
      testing.resolveCredentialSource({
        OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE: "convex",
        OPENCLAW_QA_CREDENTIAL_SOURCE: "env",
      }),
    ).toBe("convex");
    expect(
      testing.resolveCredentialRole({
        OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE: "ci",
        OPENCLAW_QA_CREDENTIAL_ROLE: "maintainer",
      }),
    ).toBe("ci");
  });

  it("defaults package Telegram RTT for the normal package live lane", () => {
    expect(testing.resolveRttOptions({})).toEqual({
      scenarioId: "channel-canary",
      count: 20,
      timeoutMs: 30_000,
      maxFailures: 20,
    });
  });

  it("does not force default RTT onto focused non-RTT scenario runs", () => {
    expect(testing.resolveRttOptions({}, ["telegram-status-command"])).toBeUndefined();
  });

  it("maps repeated RTT env onto package Telegram live options", () => {
    expect(
      testing.resolveRttOptions({
        OPENCLAW_NPM_TELEGRAM_RTT_SAMPLES: "7",
        OPENCLAW_NPM_TELEGRAM_RTT_TIMEOUT_MS: "45000",
        OPENCLAW_NPM_TELEGRAM_RTT_MAX_FAILURES: "2",
        OPENCLAW_NPM_TELEGRAM_RTT_CHECKS: "channel-canary",
      }),
    ).toEqual({
      scenarioId: "channel-canary",
      count: 7,
      timeoutMs: 45_000,
      maxFailures: 2,
    });
  });

  it("builds a generic suite probe for the Telegram RTT lane", () => {
    const probe = testing.createRoundTripProbe(testing.resolveRttOptions({}));

    expect(probe).toMatchObject({
      scenarioId: "channel-canary",
      count: 20,
      timeoutMs: 30_000,
      markerPrefix: "QA-TELEGRAM-RTT",
      textPrefix: "@openclaw Telegram RTT check. Reply exactly: ",
      chainReplies: true,
      input: {
        conversation: { id: "telegram-rtt-room", kind: "group" },
      },
    });
  });

  it.each([
    {
      name: "promotes the default canary before taxonomy-backed release selection",
      env: {},
      requested: [],
      resolved: ["telegram-status-command"],
      expected: ["channel-canary", "telegram-status-command"],
    },
    {
      name: "keeps focused non-RTT selections unchanged",
      env: {},
      requested: ["telegram-status-command"],
      resolved: ["telegram-status-command"],
      expected: ["telegram-status-command"],
    },
    {
      name: "promotes an explicitly requested RTT canary",
      env: { OPENCLAW_NPM_TELEGRAM_RTT_CHECKS: "channel-canary" },
      requested: ["telegram-status-command"],
      resolved: ["telegram-status-command"],
      expected: ["channel-canary", "telegram-status-command"],
    },
    {
      name: "does not duplicate an already selected RTT canary",
      env: {},
      requested: ["telegram-status-command", "channel-canary"],
      resolved: ["telegram-status-command", "channel-canary"],
      expected: ["channel-canary", "telegram-status-command"],
    },
  ])("$name", ({ env, requested, resolved, expected }) => {
    const options = testing.resolveRttOptions(env, requested);

    expect(testing.prioritizeRoundTripProbeScenario(resolved, options)).toEqual(expected);
  });

  it("rejects retired RTT scenario ids", () => {
    expect(() =>
      testing.resolveRttOptions({
        OPENCLAW_NPM_TELEGRAM_RTT_CHECKS: "telegram-mentioned-message-reply",
      }),
    ).toThrow("unknown Telegram QA RTT check: telegram-mentioned-message-reply");
  });

  it("rejects invalid repeated RTT env", () => {
    expect(() =>
      testing.resolveRttOptions({
        OPENCLAW_NPM_TELEGRAM_RTT_SAMPLES: "7samples",
      }),
    ).toThrow("invalid OPENCLAW_NPM_TELEGRAM_RTT_SAMPLES: 7samples");
  });

  it.each(["fail", "skip", "skipped", "timeout"])(
    "fails package Telegram QA when a scenario has %s status",
    async (status) => {
      const summaryPath = path.join(mkTempRoot(), "qa-evidence.json");
      writeFileSync(
        summaryPath,
        JSON.stringify({
          kind: "openclaw.qa.evidence-summary",
          schemaVersion: 2,
          generatedAt: "2026-05-01T00:00:00.000Z",
          entries: [{ result: { status } }],
        }),
        "utf8",
      );

      await expect(
        testing.shouldFailPackageTelegramRun(
          { summaryPath },
          { OPENCLAW_NPM_TELEGRAM_ALLOW_FAILURES: "" },
        ),
      ).resolves.toBe(true);
    },
  );

  it("passes package Telegram QA when every scenario passes", async () => {
    const summaryPath = path.join(mkTempRoot(), "qa-evidence.json");
    writeFileSync(
      summaryPath,
      JSON.stringify({
        kind: "openclaw.qa.evidence-summary",
        schemaVersion: 2,
        generatedAt: "2026-05-01T00:00:00.000Z",
        entries: [{ result: { status: "pass" } }],
      }),
      "utf8",
    );

    await expect(
      testing.shouldFailPackageTelegramRun(
        { summaryPath },
        { OPENCLAW_NPM_TELEGRAM_ALLOW_FAILURES: "" },
      ),
    ).resolves.toBe(false);
  });

  it("does not read package Telegram summaries when failures are allowed", async () => {
    await expect(
      testing.shouldFailPackageTelegramRun(
        { summaryPath: path.join(mkTempRoot(), "missing-summary.json") },
        { OPENCLAW_NPM_TELEGRAM_ALLOW_FAILURES: "1" },
      ),
    ).resolves.toBe(false);
  });
});
