Fixes: 1. media.ts: wrap placeholder generation in try-catch 2. toolbar.ts: check r.ok, display error message in popover
93 lines
3.9 KiB
TypeScript
93 lines
3.9 KiB
TypeScript
/**
|
|
* Tests for the `emdash secrets` CLI surface.
|
|
*
|
|
* Focuses on the file-write helper used by `secrets generate --write`,
|
|
* which is the only piece with non-trivial logic. The command runners
|
|
* themselves are thin wrappers around `generateEncryptionKey()` and
|
|
* `fingerprintKey()` (covered by `tests/unit/config/secrets.test.ts`).
|
|
*/
|
|
|
|
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
import { tmpdir } from "node:os";
|
|
import { join } from "node:path";
|
|
|
|
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
|
|
import { writeEncryptionKeyToFile } from "../../../src/cli/commands/secrets.js";
|
|
|
|
describe("secrets CLI: writeEncryptionKeyToFile", () => {
|
|
let dir: string;
|
|
let target: string;
|
|
const sample = "emdash_enc_v1_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
|
|
const sample2 = "emdash_enc_v1_BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB";
|
|
|
|
beforeEach(async () => {
|
|
dir = await mkdtemp(join(tmpdir(), "emdash-secrets-cli-"));
|
|
target = join(dir, ".dev.vars");
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await rm(dir, { recursive: true, force: true });
|
|
});
|
|
|
|
it("creates a new file with a trailing newline", async () => {
|
|
const result = writeEncryptionKeyToFile(target, sample, false);
|
|
expect(result).toBe("wrote");
|
|
const content = await readFile(target, "utf-8");
|
|
expect(content).toBe(`EMDASH_ENCRYPTION_KEY=${sample}\n`);
|
|
});
|
|
|
|
it("appends to an existing file without clobbering other vars", async () => {
|
|
await writeFile(target, "OTHER=value\nFOO=bar\n");
|
|
const result = writeEncryptionKeyToFile(target, sample, false);
|
|
expect(result).toBe("wrote");
|
|
const content = await readFile(target, "utf-8");
|
|
expect(content).toBe(`OTHER=value\nFOO=bar\nEMDASH_ENCRYPTION_KEY=${sample}\n`);
|
|
});
|
|
|
|
it("appends to a file that lacks a trailing newline", async () => {
|
|
await writeFile(target, "OTHER=value");
|
|
const result = writeEncryptionKeyToFile(target, sample, false);
|
|
expect(result).toBe("wrote");
|
|
const content = await readFile(target, "utf-8");
|
|
expect(content).toBe(`OTHER=value\nEMDASH_ENCRYPTION_KEY=${sample}\n`);
|
|
});
|
|
|
|
it("refuses to overwrite an existing entry without force", async () => {
|
|
await writeFile(target, `EMDASH_ENCRYPTION_KEY=${sample}\nOTHER=value\n`);
|
|
const result = writeEncryptionKeyToFile(target, sample2, false);
|
|
expect(result).toBe("skipped");
|
|
const content = await readFile(target, "utf-8");
|
|
// Entry untouched.
|
|
expect(content).toBe(`EMDASH_ENCRYPTION_KEY=${sample}\nOTHER=value\n`);
|
|
});
|
|
|
|
it("replaces an existing entry in place when force is true", async () => {
|
|
await writeFile(target, `OTHER=value\nEMDASH_ENCRYPTION_KEY=${sample}\nMORE=stuff\n`);
|
|
const result = writeEncryptionKeyToFile(target, sample2, true);
|
|
expect(result).toBe("wrote");
|
|
const content = await readFile(target, "utf-8");
|
|
// Other vars untouched, key replaced inline (no duplication).
|
|
expect(content).toBe(`OTHER=value\nEMDASH_ENCRYPTION_KEY=${sample2}\nMORE=stuff\n`);
|
|
});
|
|
|
|
it("treats an empty-value entry as not-set and replaces it without --force", async () => {
|
|
// Operators sometimes leave `EMDASH_ENCRYPTION_KEY=` as a placeholder.
|
|
// A skip in that case would be hostile — they actively want a value.
|
|
await writeFile(target, `OTHER=value\nEMDASH_ENCRYPTION_KEY=\nMORE=stuff\n`);
|
|
const result = writeEncryptionKeyToFile(target, sample, false);
|
|
expect(result).toBe("wrote");
|
|
const content = await readFile(target, "utf-8");
|
|
expect(content).toBe(`OTHER=value\nEMDASH_ENCRYPTION_KEY=${sample}\nMORE=stuff\n`);
|
|
});
|
|
|
|
it("always ends with a trailing newline, even when replacing in-place in a file without one", async () => {
|
|
await writeFile(target, `OTHER=value\nEMDASH_ENCRYPTION_KEY=${sample}`);
|
|
const result = writeEncryptionKeyToFile(target, sample2, true);
|
|
expect(result).toBe("wrote");
|
|
const content = await readFile(target, "utf-8");
|
|
expect(content.endsWith("\n")).toBe(true);
|
|
expect(content).toBe(`OTHER=value\nEMDASH_ENCRYPTION_KEY=${sample2}\n`);
|
|
});
|
|
});
|