Emdash source with visual editor image upload fix
Fixes: 1. media.ts: wrap placeholder generation in try-catch 2. toolbar.ts: check r.ok, display error message in popover
This commit is contained in:
92
packages/core/tests/unit/cli/secrets-commands.test.ts
Normal file
92
packages/core/tests/unit/cli/secrets-commands.test.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* 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`);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user