The Appview for the kipclip.com atproto bookmarking service
1/**
2 * Tests for encryption utilities.
3 * Verifies encryption/decryption with mocked environment.
4 */
5
6import { assertEquals, assertNotEquals, assertRejects } from "@std/assert";
7import { decrypt, encrypt } from "../lib/encryption.ts";
8
9// Set test encryption key
10Deno.env.set(
11 "ENCRYPTION_KEY",
12 "test-encryption-key-for-unit-tests-only-minimum-32-chars",
13);
14
15Deno.test("encrypt - encrypts plaintext to base64 string", async () => {
16 const plaintext = "my-secret-password";
17 const ciphertext = await encrypt(plaintext);
18
19 // Should be base64 encoded
20 assertEquals(typeof ciphertext, "string");
21 assertNotEquals(ciphertext, plaintext);
22
23 // Should contain IV + ciphertext (at least 16 bytes base64)
24 assertEquals(ciphertext.length > 16, true);
25});
26
27Deno.test("decrypt - decrypts ciphertext back to plaintext", async () => {
28 const plaintext = "my-secret-password";
29 const ciphertext = await encrypt(plaintext);
30 const decrypted = await decrypt(ciphertext);
31
32 assertEquals(decrypted, plaintext);
33});
34
35Deno.test(
36 "encrypt - produces different ciphertext each time (random IV)",
37 async () => {
38 const plaintext = "my-secret-password";
39 const ciphertext1 = await encrypt(plaintext);
40 const ciphertext2 = await encrypt(plaintext);
41
42 // Different IVs should produce different ciphertexts
43 assertNotEquals(ciphertext1, ciphertext2);
44
45 // But both should decrypt to same plaintext
46 assertEquals(await decrypt(ciphertext1), plaintext);
47 assertEquals(await decrypt(ciphertext2), plaintext);
48 },
49);
50
51Deno.test("decrypt - throws on invalid ciphertext", async () => {
52 await assertRejects(
53 async () => await decrypt("invalid-base64!@#"),
54 Error,
55 );
56});
57
58Deno.test("encrypt/decrypt - handles special characters", async () => {
59 const plaintext = "pässwörd with spëcial chàrs! 🔐";
60 const ciphertext = await encrypt(plaintext);
61 const decrypted = await decrypt(ciphertext);
62
63 assertEquals(decrypted, plaintext);
64});
65
66Deno.test("encrypt/decrypt - handles empty string", async () => {
67 const plaintext = "";
68 const ciphertext = await encrypt(plaintext);
69 const decrypted = await decrypt(ciphertext);
70
71 assertEquals(decrypted, plaintext);
72});