Phase 2 red: crypto primitive tests and stub modules
Tests for the entire crypto/ public surface, written against the API
shape declared in the README. The accompanying src/crypto/ modules are
stubs that throw 'not implemented' so the test files compile and tests
fail with clear errors rather than module-not-found.
Tests cover:
* init() resolves and is idempotent
* fromBase64 / toBase64 / toBase64URL round-trips, including URL-safe
input with stripped padding (the form Ente uses for auth tokens)
* deriveKEK matches sodium.crypto_pwhash with Argon2id parameters
* deriveLoginSubkey matches sodium.crypto_kdf_derive_from_key with
subkey id 1 and ctx 'loginctx', truncated to 16 bytes
* decryptBox round-trips, rejects tampering, wrong key, wrong nonce
* decryptSealed round-trips, rejects wrong keypair and tampering
* Secretstream pull decrypts multi-chunk streams in order, exposes
per-chunk tags, rejects tampering, wrong key, and out-of-order chunks
* Constants STREAM_CHUNK_SIZE (4 MiB) and STREAM_CHUNK_OVERHEAD (17)
Tests are commented to serve as the canonical API documentation per the
README development workflow policy. Verified: 29 tests fail (red), 3
trivial constant tests pass; lint and fmt-check are green.
eslint.config.mjs is updated to honour the leading-underscore convention
for intentionally unused parameters (the stubs).
This commit is contained in:
38
test/crypto/init.test.ts
Normal file
38
test/crypto/init.test.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Tests for `crypto.init()`.
|
||||
*
|
||||
* libsodium ships as WebAssembly. The bindings (`libsodium-wrappers-sumo`)
|
||||
* load asynchronously: the runtime must `await sodium.ready` once before any
|
||||
* crypto call is safe. quack hides that detail behind a single
|
||||
* `init()` function.
|
||||
*
|
||||
* Every other test in `test/crypto/**` calls `init()` in `beforeAll`. New
|
||||
* code that needs crypto should do the same. Calling it more than once is
|
||||
* cheap and intentional; the second call returns the same already-resolved
|
||||
* promise.
|
||||
*/
|
||||
|
||||
import { beforeAll, describe, expect, it } from "vitest";
|
||||
import { init } from "../../src/crypto/index.js";
|
||||
|
||||
describe("crypto.init", () => {
|
||||
beforeAll(async () => {
|
||||
await init();
|
||||
});
|
||||
|
||||
it("resolves without throwing", async () => {
|
||||
// The success criterion is simply that the promise resolves. If
|
||||
// libsodium's WASM fails to load, `init()` rejects and this test
|
||||
// fails.
|
||||
await expect(init()).resolves.toBeUndefined();
|
||||
});
|
||||
|
||||
it("is idempotent: repeated calls are safe", async () => {
|
||||
// Code paths in this library may call `init()` defensively (e.g. a
|
||||
// `Client` constructor that doesn't know whether the caller already
|
||||
// initialised). Repeated calls must therefore be harmless.
|
||||
await init();
|
||||
await init();
|
||||
await init();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user