Files
i-want-to-heal-mmo/src/frontend/accountRepository.test.ts
T
2026-07-10 23:47:37 -04:00

54 lines
2.6 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type { StorageAdapter } from "./saveRepository";
import { AccountRepository } from "./accountRepository";
function memoryStorage(): StorageAdapter {
const data = new Map<string, string>();
return {
getItem: (key) => data.get(key) ?? null,
setItem: (key, value) => { data.set(key, value); },
};
}
const testHasher = async (password: string, salt: string) => {
const checksum = [...password].reduce((total, character) => total + character.charCodeAt(0), 0);
return `derived:${salt}:${checksum}`;
};
describe("AccountRepository", () => {
it("requires both a username and password", async () => {
const repository = new AccountRepository(memoryStorage(), testHasher, () => "salt");
await expect(repository.create("", "secret")).resolves.toEqual({ ok: false, reason: "missing-credentials" });
await expect(repository.create("healer", "")).resolves.toEqual({ ok: false, reason: "missing-credentials" });
await expect(repository.authenticate("healer", "")).resolves.toEqual({ ok: false, reason: "missing-credentials" });
});
it("requires account creation before sign-in", async () => {
const repository = new AccountRepository(memoryStorage(), testHasher, () => "salt");
await expect(repository.authenticate("new-healer", "secret")).resolves.toEqual({ ok: false, reason: "account-not-found" });
await expect(repository.create("new-healer", "secret")).resolves.toEqual({ ok: true, username: "new-healer" });
await expect(repository.authenticate("new-healer", "secret")).resolves.toEqual({ ok: true, username: "new-healer" });
});
it("rejects an incorrect password and duplicate account names", async () => {
const repository = new AccountRepository(memoryStorage(), testHasher, () => "salt");
await repository.create("Wayfinder", "correct");
await expect(repository.authenticate("wayfinder", "wrong")).resolves.toEqual({ ok: false, reason: "invalid-password" });
await expect(repository.create(" wayfinder ", "another")).resolves.toEqual({ ok: false, reason: "account-exists" });
});
it("persists only a derived password verifier", async () => {
const storage = memoryStorage();
const repository = new AccountRepository(storage, testHasher, () => "unique-salt");
await repository.create("healer", "plaintext-secret");
const persisted = storage.getItem("i-want-to-heal:accounts:v1") ?? "";
expect(persisted).toContain("derived:unique-salt:");
expect(persisted).not.toContain("plaintext-secret");
expect(JSON.parse(persisted).healer).not.toHaveProperty("password");
});
});