/* Unit tests for service deploy helpers covering extractWorkersDevUrl; parseEnvFile; flagString. Not a contract source of truth — the module under test owns the authoritative behavior; fixtures are minimal scaffolding only. RFC-1311: Compass header sweep — declares the service suite's contract for test-file scaffold coverage. */ import { describe, it, expect } from "vitest"; import { mkdtempSync, writeFileSync, rmSync } from "node:fs"; import { join } from "node:path"; import { tmpdir } from "node:os"; import { extractWorkersDevUrl, parseEnvFile, flagString, flagBoolean, runBuildCheck, } from "./service-deploy-helpers.ts"; describe("extractWorkersDevUrl", () => { it("extracts workers.dev URL from wrangler output", () => { const stdout = "Uploaded matomo-proxy-dev (1.2 sec)\n https://matomo-proxy-dev.syrokomskyi.workers.dev\n"; expect(extractWorkersDevUrl(stdout)).toBe("https://matomo-proxy-dev.syrokomskyi.workers.dev"); }); it("returns undefined when no workers.dev URL found", () => { expect(extractWorkersDevUrl("no url here")).toBeUndefined(); }); it("extracts URL with trailing path", () => { const stdout = "Deployed to https://rate-fetcher-dev.syrokomskyi.workers.dev/health"; expect(extractWorkersDevUrl(stdout)).toBe( "https://rate-fetcher-dev.syrokomskyi.workers.dev/health", ); }); }); describe("parseEnvFile", () => { let tmpDir: string; it("parses key=value pairs", async () => { tmpDir = mkdtempSync(join(tmpdir(), "tmp-env-parse-")); const envPath = join(tmpDir, ".env"); writeFileSync(envPath, "FOO=bar\nBAZ=qux\n# comment\n\nSKIP=\n"); const env = await parseEnvFile(envPath); expect(env).toEqual({ FOO: "bar", BAZ: "qux" }); rmSync(tmpDir, { recursive: true }); }); it("returns empty object for missing file", async () => { const env = await parseEnvFile("/nonexistent/.env"); expect(env).toEqual({}); }); it("strips quotes from values", async () => { tmpDir = mkdtempSync(join(tmpdir(), "tmp-env-quotes-")); const envPath = join(tmpDir, ".env"); writeFileSync(envPath, "KEY1=\"double quoted\"\nKEY2='single quoted'\n"); const env = await parseEnvFile(envPath); expect(env).toEqual({ KEY1: "double quoted", KEY2: "single quoted" }); rmSync(tmpDir, { recursive: true }); }); }); describe("flagString", () => { it("returns string value", () => { expect(flagString({ flags: { service: "matomo-proxy" } } as never, "service")).toBe( "matomo-proxy", ); }); it("returns undefined for missing flag", () => { expect(flagString({ flags: {} } as never, "service")).toBeUndefined(); }); it("returns undefined for non-string flag", () => { expect(flagString({ flags: { service: true } } as never, "service")).toBeUndefined(); }); }); describe("flagBoolean", () => { it("returns true for boolean true", () => { expect(flagBoolean({ flags: { dev: true } } as never, "dev")).toBe(true); }); it("returns true for string 'true'", () => { expect(flagBoolean({ flags: { dev: "true" } } as never, "dev")).toBe(true); }); it("returns false for missing flag", () => { expect(flagBoolean({ flags: {} } as never, "dev")).toBe(false); }); }); describe("runBuildCheck", () => { it("passes when build:check exits 0", async () => { const tmpDir = mkdtempSync(join(tmpdir(), "tmp-buildcheck-pass-")); writeFileSync( join(tmpDir, "package.json"), JSON.stringify({ name: "test-svc", scripts: { "build:check": 'node -e "process.exit(0)"' }, }) + "\n", ); const result = await runBuildCheck(tmpDir, { info: () => {} }); expect(result.passed).toBe(true); expect(result.command).toBe("build:check"); rmSync(tmpDir, { recursive: true }); }); it("fails when build:check exits non-zero", async () => { const tmpDir = mkdtempSync(join(tmpdir(), "tmp-buildcheck-fail-")); writeFileSync( join(tmpDir, "package.json"), JSON.stringify({ name: "test-svc", scripts: { "build:check": 'node -e "process.exit(1)"' }, }) + "\n", ); const result = await runBuildCheck(tmpDir, { info: () => {} }); expect(result.passed).toBe(false); rmSync(tmpDir, { recursive: true }); }); });