auth.logout.test.ts 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import { describe, expect, it } from "vitest";
  2. import { appRouter } from "./routers";
  3. import { COOKIE_NAME } from "../shared/const";
  4. import type { TrpcContext } from "./_core/context";
  5. type CookieCall = {
  6. name: string;
  7. options: Record<string, unknown>;
  8. };
  9. type AuthenticatedUser = NonNullable<TrpcContext["user"]>;
  10. function createAuthContext(): { ctx: TrpcContext; clearedCookies: CookieCall[] } {
  11. const clearedCookies: CookieCall[] = [];
  12. const user: AuthenticatedUser = {
  13. id: 1,
  14. openId: "sample-user",
  15. email: "sample@example.com",
  16. name: "Sample User",
  17. loginMethod: "manus",
  18. role: "user",
  19. createdAt: new Date(),
  20. updatedAt: new Date(),
  21. lastSignedIn: new Date(),
  22. };
  23. const ctx: TrpcContext = {
  24. user,
  25. req: {
  26. protocol: "https",
  27. headers: {},
  28. } as TrpcContext["req"],
  29. res: {
  30. clearCookie: (name: string, options: Record<string, unknown>) => {
  31. clearedCookies.push({ name, options });
  32. },
  33. } as TrpcContext["res"],
  34. };
  35. return { ctx, clearedCookies };
  36. }
  37. describe("auth.logout", () => {
  38. it("clears the session cookie and reports success", async () => {
  39. const { ctx, clearedCookies } = createAuthContext();
  40. const caller = appRouter.createCaller(ctx);
  41. const result = await caller.auth.logout();
  42. expect(result).toEqual({ success: true });
  43. expect(clearedCookies).toHaveLength(1);
  44. expect(clearedCookies[0]?.name).toBe(COOKIE_NAME);
  45. expect(clearedCookies[0]?.options).toMatchObject({
  46. maxAge: -1,
  47. secure: true,
  48. sameSite: "none",
  49. httpOnly: true,
  50. path: "/",
  51. });
  52. });
  53. });