73 lines
2.5 KiB
TypeScript
73 lines
2.5 KiB
TypeScript
|
|
import { describe, it, expect, vi, beforeEach } from "vitest";
|
||
|
|
|
||
|
|
vi.mock("~/database/context", () => ({
|
||
|
|
database: vi.fn(),
|
||
|
|
}));
|
||
|
|
|
||
|
|
import { anonymizeUserAccount } from "../user";
|
||
|
|
import { database } from "~/database/context";
|
||
|
|
import * as schema from "~/database/schema";
|
||
|
|
|
||
|
|
const USER_ID = "a1b2c3d4-e5f6-7890-abcd-ef1234567890";
|
||
|
|
|
||
|
|
function makeTransactionDb() {
|
||
|
|
const whereFn = vi.fn().mockResolvedValue(undefined);
|
||
|
|
const setFn = vi.fn().mockReturnValue({ where: whereFn });
|
||
|
|
const deleteFn = vi.fn().mockReturnValue({ where: vi.fn().mockResolvedValue(undefined) });
|
||
|
|
const updateFn = vi.fn().mockReturnValue({ set: setFn });
|
||
|
|
|
||
|
|
const tx = { delete: deleteFn, update: updateFn };
|
||
|
|
const db = {
|
||
|
|
transaction: vi.fn().mockImplementation((fn: (t: typeof tx) => Promise<void>) => fn(tx)),
|
||
|
|
};
|
||
|
|
|
||
|
|
return { db, tx, deleteFn, updateFn, setFn, whereFn };
|
||
|
|
}
|
||
|
|
|
||
|
|
beforeEach(() => {
|
||
|
|
vi.clearAllMocks();
|
||
|
|
});
|
||
|
|
|
||
|
|
describe("anonymizeUserAccount", () => {
|
||
|
|
it("deletes sessions then accounts inside a transaction", async () => {
|
||
|
|
const { db, tx, deleteFn } = makeTransactionDb();
|
||
|
|
vi.mocked(database).mockReturnValue(db as never);
|
||
|
|
|
||
|
|
await anonymizeUserAccount(USER_ID);
|
||
|
|
|
||
|
|
expect(db.transaction).toHaveBeenCalledTimes(1);
|
||
|
|
expect(deleteFn).toHaveBeenCalledTimes(2);
|
||
|
|
expect(deleteFn).toHaveBeenNthCalledWith(1, schema.sessions);
|
||
|
|
expect(deleteFn).toHaveBeenNthCalledWith(2, schema.accounts);
|
||
|
|
expect(tx.update).toHaveBeenCalledWith(schema.users);
|
||
|
|
});
|
||
|
|
|
||
|
|
it("calls update on the users table with anonymized fields", async () => {
|
||
|
|
const { db, setFn } = makeTransactionDb();
|
||
|
|
vi.mocked(database).mockReturnValue(db as never);
|
||
|
|
|
||
|
|
await anonymizeUserAccount(USER_ID);
|
||
|
|
|
||
|
|
const setCall = setFn.mock.calls[0][0];
|
||
|
|
expect(setCall.email).toMatch(/^deleted-[a-f0-9]{8}@deleted\.brackt\.com$/);
|
||
|
|
expect(setCall.displayName).toBeNull();
|
||
|
|
expect(setCall.username).toBeNull();
|
||
|
|
expect(setCall.imageUrl).toBeNull();
|
||
|
|
expect(setCall.customAvatarUrl).toBeNull();
|
||
|
|
expect(setCall.flagConfig).toBeNull();
|
||
|
|
expect(setCall.avatarType).toBe("flag");
|
||
|
|
expect(setCall.deletedAt).toBeInstanceOf(Date);
|
||
|
|
});
|
||
|
|
|
||
|
|
it("derives the short ID from the UUID", async () => {
|
||
|
|
const { db, setFn } = makeTransactionDb();
|
||
|
|
vi.mocked(database).mockReturnValue(db as never);
|
||
|
|
|
||
|
|
await anonymizeUserAccount(USER_ID);
|
||
|
|
|
||
|
|
const setCall = setFn.mock.calls[0][0];
|
||
|
|
// USER_ID without dashes: "a1b2c3d4e5f67890abcdef1234567890" → first 8 = "a1b2c3d4"
|
||
|
|
expect(setCall.email).toBe("deleted-a1b2c3d4@deleted.brackt.com");
|
||
|
|
});
|
||
|
|
});
|