From 459d9fdfa311bdbff1b589cc9f512bb311714c4c Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sat, 4 Apr 2026 10:04:55 +0000 Subject: [PATCH 1/2] test: cover dotenv parse, remove, and append validation --- src/lib/dotenv-parse.test.ts | 92 ++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 src/lib/dotenv-parse.test.ts diff --git a/src/lib/dotenv-parse.test.ts b/src/lib/dotenv-parse.test.ts new file mode 100644 index 0000000..a8b1944 --- /dev/null +++ b/src/lib/dotenv-parse.test.ts @@ -0,0 +1,92 @@ +import { describe, expect, it } from "vitest"; +import { appendDotenvKey, parseDotenv, removeDotenvKey } from "./dotenv-parse"; + +describe("parseDotenv", () => { + it("parses unquoted, single-quoted, and double-quoted values", () => { + expect(parseDotenv("A=1\nB=two\nC=\"x\"\nD='y z'\n")).toEqual([ + { key: "A", value: "1" }, + { key: "B", value: "two" }, + { key: "C", value: "x" }, + { key: "D", value: "y z" }, + ]); + }); + + it("ignores blanks, comments, and lines without =", () => { + expect(parseDotenv("\n # x\nFOO=bar\nnot-a-pair\n")).toEqual([ + { key: "FOO", value: "bar" }, + ]); + }); + + it("handles CRLF line endings", () => { + expect(parseDotenv("X=a\r\nY=b")).toEqual([ + { key: "X", value: "a" }, + { key: "Y", value: "b" }, + ]); + }); + + it("rejects keys when = is first character", () => { + expect(parseDotenv("=nokey")).toEqual([]); + }); +}); + +describe("removeDotenvKey", () => { + it("removes every assignment line for the key and keeps comments", () => { + const before = "A=1\n# keep\nB=2\nA=3\n\n"; + expect(removeDotenvKey(before, "A")).toBe("# keep\nB=2\n\n"); + }); + + it("does not strip malformed lines that parseDotenv would skip", () => { + const body = "KEEP_ME\nFOO=1\n"; + expect(removeDotenvKey(body, "FOO")).toBe("KEEP_ME\n"); + }); +}); + +describe("appendDotenvKey", () => { + it("appends a line and trims trailing whitespace on existing content", () => { + const r = appendDotenvKey("X=1\n \n", "Y", "2"); + expect(r).toEqual({ ok: true, content: "X=1\nY=2" }); + }); + + it("uses first file when empty", () => { + const r = appendDotenvKey("", "A", "b"); + expect(r).toEqual({ ok: true, content: "A=b" }); + }); + + it("quotes values that need escaping", () => { + const r = appendDotenvKey("", "K", 'say "hi"'); + expect(r).toEqual({ ok: true, content: 'K="say \\"hi\\""' }); + }); + + it("rejects empty key", () => { + const r = appendDotenvKey("X=1", " ", "v"); + expect(r).toEqual({ ok: false, error: "Enter a variable name" }); + }); + + it("rejects keys containing =, starting with #, or spanning lines", () => { + expect(appendDotenvKey("", "a=b", "1")).toMatchObject({ + ok: false, + error: 'Key cannot contain "="', + }); + expect(appendDotenvKey("", "#x", "1")).toMatchObject({ + ok: false, + error: "Key cannot start with #", + }); + expect(appendDotenvKey("", "a\nb", "1")).toMatchObject({ + ok: false, + error: "Key cannot span lines", + }); + }); + + it("rejects values with line breaks", () => { + const r = appendDotenvKey("", "K", "a\nb"); + expect(r).toEqual({ + ok: false, + error: "Value cannot contain line breaks", + }); + }); + + it("rejects duplicate keys visible to parseDotenv", () => { + const r = appendDotenvKey("FOO=1", "FOO", "2"); + expect(r).toEqual({ ok: false, error: '"FOO" is already defined' }); + }); +}); From ab18e8113a00c02c7b5136367f8b3bae24277ac7 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sat, 4 Apr 2026 10:05:02 +0000 Subject: [PATCH 2/2] test: cover URL-safe S3 object key token round-trip --- src/lib/key-token.test.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/lib/key-token.test.ts diff --git a/src/lib/key-token.test.ts b/src/lib/key-token.test.ts new file mode 100644 index 0000000..786c382 --- /dev/null +++ b/src/lib/key-token.test.ts @@ -0,0 +1,22 @@ +import { describe, expect, it } from "vitest"; +import { decodeObjectKeyToken, encodeObjectKeyToken } from "./key-token"; + +describe("encodeObjectKeyToken / decodeObjectKeyToken", () => { + it("round-trips utf-8 object keys", () => { + const key = "team/prod/secrets/.env"; + const token = encodeObjectKeyToken(key); + expect(decodeObjectKeyToken(token)).toBe(key); + }); + + it("uses URL-safe alphabet (no +, /, or trailing =)", () => { + const token = encodeObjectKeyToken("???"); + expect(token).not.toMatch(/[+/=]/); + }); + + it("round-trips keys that produce padding in standard base64", () => { + const key = "ab"; // often encodes to base64 ending with == + const token = encodeObjectKeyToken(key); + expect(token.endsWith("=")).toBe(false); + expect(decodeObjectKeyToken(token)).toBe(key); + }); +});