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": {
|
||||
"@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-dom": "^19.2.3",
|
||||
"@vitejs/plugin-react": "^4.7.0",
|
||||
"@vitest/ui": "^4.0.15",
|
||||
"jsdom": "^27.3.0",
|
||||
"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({
|
||||
plugins: [tailwindcss(), react(), svgr()],
|
||||
test: {
|
||||
globals: true,
|
||||
environment: "jsdom",
|
||||
setupFiles: "./src/test/setup.ts",
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": path.resolve(__dirname, "./src"),
|
||||
|
|
|
|||
Loading…
Reference in a new issue