109 lines
2.8 KiB
TypeScript
109 lines
2.8 KiB
TypeScript
import { TRPCError } from "@trpc/server";
|
|
import { describe, expect, it, vi } from "vitest";
|
|
import {
|
|
getNotificationErrorCandidates,
|
|
rethrowNotificationReferenceError,
|
|
resolveUserId,
|
|
} from "../router/notification-procedure-support.js";
|
|
|
|
describe("notification procedure support", () => {
|
|
it("resolves the current user id from the session email", async () => {
|
|
const findUnique = vi.fn().mockResolvedValue({ id: "user_1" });
|
|
|
|
await expect(resolveUserId({
|
|
db: {
|
|
user: {
|
|
findUnique,
|
|
},
|
|
},
|
|
session: {
|
|
user: { email: "person@example.com" },
|
|
},
|
|
})).resolves.toBe("user_1");
|
|
|
|
expect(findUnique).toHaveBeenCalledWith({
|
|
where: { email: "person@example.com" },
|
|
select: { id: true },
|
|
});
|
|
});
|
|
|
|
it("rejects when no session email is available", async () => {
|
|
await expect(resolveUserId({
|
|
db: {
|
|
user: {
|
|
findUnique: vi.fn(),
|
|
},
|
|
},
|
|
session: {
|
|
user: null,
|
|
},
|
|
})).rejects.toEqual(expect.objectContaining<Partial<TRPCError>>({
|
|
code: "UNAUTHORIZED",
|
|
}));
|
|
});
|
|
|
|
it("collects nested notification error candidates from causes", () => {
|
|
const nested = {
|
|
code: "P2003",
|
|
meta: { field_name: "senderId" },
|
|
};
|
|
|
|
const candidates = getNotificationErrorCandidates({
|
|
cause: {
|
|
shape: {
|
|
data: {
|
|
cause: nested,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
expect(candidates).toContainEqual(expect.objectContaining({
|
|
code: "P2003",
|
|
meta: expect.objectContaining({ field_name: "senderId" }),
|
|
}));
|
|
});
|
|
|
|
it("rewrites sender foreign-key errors to a not found TRPC error", () => {
|
|
const error = {
|
|
code: "P2003",
|
|
meta: { field_name: "senderId" },
|
|
};
|
|
|
|
try {
|
|
rethrowNotificationReferenceError(error);
|
|
throw new Error("expected notification reference error");
|
|
} catch (caught) {
|
|
expect(caught).toBeInstanceOf(TRPCError);
|
|
expect(caught).toMatchObject<Partial<TRPCError>>({
|
|
code: "NOT_FOUND",
|
|
message: "Sender user not found",
|
|
});
|
|
}
|
|
});
|
|
|
|
it("rewrites broadcast source foreign-key errors to a not found TRPC error", () => {
|
|
const error = {
|
|
code: "P2003",
|
|
meta: { field_name: "Notification_sourceId_fkey" },
|
|
};
|
|
|
|
try {
|
|
rethrowNotificationReferenceError(error);
|
|
throw new Error("expected notification reference error");
|
|
} catch (caught) {
|
|
expect(caught).toBeInstanceOf(TRPCError);
|
|
expect(caught).toMatchObject<Partial<TRPCError>>({
|
|
code: "NOT_FOUND",
|
|
message: "Notification broadcast not found",
|
|
});
|
|
}
|
|
});
|
|
|
|
it("rethrows unrelated errors unchanged", () => {
|
|
const error = new Error("boom");
|
|
|
|
expect(() => rethrowNotificationReferenceError(error)).toThrow(error);
|
|
});
|
|
});
|