Add Vitest setup and tests for encryption
- Set up Vitest with testing-library and jsdom for frontend tests - Add encryption.test.ts to verify deriveKey, wrapMasterKey, unwrapMasterKey - Add test/setup.ts to extend jest-dom matchers and cleanup after tests - Enable Vitest in Vite config and add test scripts in frontend/package.json
This commit is contained in:
parent
b596c9f34d
commit
2eb924dc9c
5 changed files with 1932 additions and 2 deletions
1839
frontend/package-lock.json
generated
1839
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -29,10 +29,21 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@catppuccin/tailwindcss": "^1.0.0",
|
"@catppuccin/tailwindcss": "^1.0.0",
|
||||||
|
"@testing-library/jest-dom": "^6.9.1",
|
||||||
|
"@testing-library/react": "^16.3.0",
|
||||||
|
"@testing-library/user-event": "^14.6.1",
|
||||||
"@types/react": "^19.2.6",
|
"@types/react": "^19.2.6",
|
||||||
"@types/react-dom": "^19.2.3",
|
"@types/react-dom": "^19.2.3",
|
||||||
"@vitejs/plugin-react": "^4.7.0",
|
"@vitejs/plugin-react": "^4.7.0",
|
||||||
|
"@vitest/ui": "^4.0.15",
|
||||||
|
"jsdom": "^27.3.0",
|
||||||
"vite": "^5.4.21",
|
"vite": "^5.4.21",
|
||||||
"vite-plugin-svgr": "^4.5.0"
|
"vite-plugin-svgr": "^4.5.0",
|
||||||
|
"vitest": "^4.0.15"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"test": "vitest",
|
||||||
|
"test:ui": "vitest --ui",
|
||||||
|
"test:coverage": "vitest --coverage"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
66
frontend/src/api/encryption.test.ts
Normal file
66
frontend/src/api/encryption.test.ts
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
// src/api/encryption.test.ts
|
||||||
|
import { describe, it, expect } from "vitest";
|
||||||
|
import {
|
||||||
|
deriveKey,
|
||||||
|
wrapMasterKey,
|
||||||
|
unwrapMasterKey,
|
||||||
|
generateMasterKey,
|
||||||
|
} from "./encryption";
|
||||||
|
|
||||||
|
describe("Encryption", () => {
|
||||||
|
it("should derive consistent keys from same password and salt", async () => {
|
||||||
|
const password = "testPassword123";
|
||||||
|
const salt = "test-salt";
|
||||||
|
|
||||||
|
const key1 = await deriveKey(password, salt);
|
||||||
|
const key2 = await deriveKey(password, salt);
|
||||||
|
|
||||||
|
const testMessage = "test data";
|
||||||
|
const testData = new TextEncoder().encode(testMessage);
|
||||||
|
const iv = crypto.getRandomValues(new Uint8Array(12));
|
||||||
|
|
||||||
|
const encrypted = await crypto.subtle.encrypt(
|
||||||
|
{ name: "AES-GCM", iv },
|
||||||
|
key1,
|
||||||
|
testData,
|
||||||
|
);
|
||||||
|
|
||||||
|
const decrypted = await crypto.subtle.decrypt(
|
||||||
|
{ name: "AES-GCM", iv },
|
||||||
|
key2,
|
||||||
|
encrypted,
|
||||||
|
);
|
||||||
|
|
||||||
|
const decryptedMessage = new TextDecoder().decode(decrypted);
|
||||||
|
expect(decryptedMessage).toBe(testMessage);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should wrap and unwrap master key correctly", async () => {
|
||||||
|
const masterKey = await generateMasterKey();
|
||||||
|
const password = "testPassword123";
|
||||||
|
const salt = "test-salt";
|
||||||
|
const kek = await deriveKey(password, salt);
|
||||||
|
|
||||||
|
const wrapped = await wrapMasterKey(masterKey, kek);
|
||||||
|
const unwrapped = await unwrapMasterKey(wrapped, kek);
|
||||||
|
|
||||||
|
const testMessage = "test message";
|
||||||
|
const testData = new TextEncoder().encode(testMessage);
|
||||||
|
const iv = crypto.getRandomValues(new Uint8Array(12));
|
||||||
|
|
||||||
|
const encrypted = await crypto.subtle.encrypt(
|
||||||
|
{ name: "AES-GCM", iv },
|
||||||
|
masterKey,
|
||||||
|
testData,
|
||||||
|
);
|
||||||
|
|
||||||
|
const decrypted = await crypto.subtle.decrypt(
|
||||||
|
{ name: "AES-GCM", iv },
|
||||||
|
unwrapped,
|
||||||
|
encrypted,
|
||||||
|
);
|
||||||
|
|
||||||
|
const decryptedMessage = new TextDecoder().decode(decrypted);
|
||||||
|
expect(decryptedMessage).toBe(testMessage);
|
||||||
|
});
|
||||||
|
});
|
||||||
11
frontend/src/test/setup.ts
Normal file
11
frontend/src/test/setup.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
// src/test/setup.ts
|
||||||
|
import { expect, afterEach } from "vitest";
|
||||||
|
import { cleanup } from "@testing-library/react";
|
||||||
|
import * as matchers from "@testing-library/jest-dom/matchers";
|
||||||
|
|
||||||
|
expect.extend(matchers);
|
||||||
|
|
||||||
|
// Cleanup after each test
|
||||||
|
afterEach(() => {
|
||||||
|
cleanup();
|
||||||
|
});
|
||||||
|
|
@ -6,6 +6,11 @@ import path from "path";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [tailwindcss(), react(), svgr()],
|
plugins: [tailwindcss(), react(), svgr()],
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
environment: "jsdom",
|
||||||
|
setupFiles: "./src/test/setup.ts",
|
||||||
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
"@": path.resolve(__dirname, "./src"),
|
"@": path.resolve(__dirname, "./src"),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue