Files
abode/test/tools/hash.test.ts
T
codingetandClaude da4e597f73 feat(tests): add unit and integration test suite (node:test)
Adds 215 tests across three tiers using node:test + node:assert/strict
(no new test framework dependencies):

- test/tools/ — middleware and utility tests (token, hash, authenticate,
  jsonBody, convertError, validators)
- test/shared/ — DbInterface/BackendDbInterface contract suites reusable
  across backends (users, abodes, residents, apikeys, sessions, auth)
- test/backends/sqlite/ — SQLite-private tests (sql builder, WrappedDb,
  migrator) + shared suites via SqliteInterface
- test/backends/api/ — ApiInterface unit tests + shared suites via a
  live Koa server backed by SQLite

Also fixes four bugs uncovered by the tests:
- ApiInterface: path params leaked into query string (slice(1) fix)
- ApiInterface: calling res.json() on 204 No Content responses
- SqliteInterface.updateResident: missing comma in SET clause
- WrappedBetterSqlite3Db: readonly:undefined rejected by better-sqlite3

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 11:33:32 +00:00

40 lines
1.4 KiB
TypeScript

import { describe, it } from "node:test";
import assert from "node:assert/strict";
import { hashPassword, validatePassword } from "../../src/util/hash.js";
describe("hashPassword", () => {
it("returns a string in PHC/argon2 format", async () => {
const hash = await hashPassword("secret");
assert.ok(hash.startsWith("$argon2"), `expected argon2 hash, got: ${hash}`);
assert.ok(hash.includes("$"), "has delimiter");
});
it("two hashes of the same password differ (random salt)", async () => {
const [h1, h2] = await Promise.all([
hashPassword("same-password"),
hashPassword("same-password"),
]);
assert.notEqual(h1, h2, "hashes should differ due to random salt");
});
});
describe("validatePassword", () => {
it("returns true for matching password and hash", async () => {
const hash = await hashPassword("correct-password");
const result = await validatePassword("correct-password", hash);
assert.equal(result, true);
});
it("returns false for wrong password", async () => {
const hash = await hashPassword("correct-password");
const result = await validatePassword("wrong-password", hash);
assert.equal(result, false);
});
it("returns false for a completely different password", async () => {
const hash = await hashPassword("original-password");
const result = await validatePassword("different-password", hash);
assert.equal(result, false);
});
});