Files
Epicure/apps/web/lib/__tests__/encrypt.test.ts
T
2026-07-01 11:10:37 +02:00

54 lines
1.7 KiB
TypeScript

import { describe, it, expect } from "vitest";
import { encrypt, decrypt } from "../encrypt";
describe("encrypt / decrypt", () => {
it("round-trips a short string", () => {
const plain = "hello world";
expect(decrypt(encrypt(plain))).toBe(plain);
});
it("round-trips an empty string", () => {
expect(decrypt(encrypt(""))).toBe("");
});
it("round-trips a unicode string", () => {
const plain = "café ☕ résumé";
expect(decrypt(encrypt(plain))).toBe(plain);
});
it("round-trips a long string (API key-sized)", () => {
const plain = "sk-proj-" + "a".repeat(128);
expect(decrypt(encrypt(plain))).toBe(plain);
});
it("produces different ciphertexts for same input (random IV)", () => {
const plain = "same input";
const c1 = encrypt(plain);
const c2 = encrypt(plain);
expect(c1).not.toBe(c2);
// but both decrypt to same value
expect(decrypt(c1)).toBe(plain);
expect(decrypt(c2)).toBe(plain);
});
it("ciphertext format is iv:authTag:encrypted (3 hex segments)", () => {
const ct = encrypt("test");
const parts = ct.split(":");
expect(parts).toHaveLength(3);
parts.forEach((p) => expect(p).toMatch(/^[0-9a-f]+$/));
});
it("throws on malformed ciphertext (wrong segments)", () => {
expect(() => decrypt("notvalid")).toThrow("Invalid ciphertext format");
expect(() => decrypt("a:b")).toThrow("Invalid ciphertext format");
});
it("throws on tampered ciphertext (auth tag mismatch)", () => {
const ct = encrypt("sensitive");
const parts = ct.split(":");
// flip a byte in the encrypted payload
const tampered = parts[0] + ":" + parts[1] + ":" + "00" + parts[2]!.slice(2);
expect(() => decrypt(tampered)).toThrow();
});
});