JonathanJ
tRPC12mo ago
3 replies
Jonathan

How to Test TRPC

I am trying to setup testing TRPC

My Init looks like this:

import { initTRPC, TRPCError } from "@trpc/server";
import superjson from "superjson";
import { ZodError } from "zod";

import { auth, clerkClient } from "@clerk/nextjs/server";

// export const createTRPCContext = async (opts: { headers: Headers }) => {
export const createTRPCContext = async () => {
  // This is where you would do things like verify the user's session, etc.
  const authResult = await auth();

  return {
    clerk: authResult,    
  };
};

const t = initTRPC.context<typeof createTRPCContext>().create({
  transformer: superjson,
  errorFormatter({ shape, error }) {
    return {
      ...shape,
      data: {
        ...shape.data,
        zodError:
          error.cause instanceof ZodError ? error.cause.flatten() : null,
      },
    };
  },
});

export const createCallerFactory = t.createCallerFactory;

export const createTRPCRouter = t.router;

export const publicProcedure = t.procedure;

const isAuthed = t.middleware(async ({ next, ctx }) => {
  if (!ctx.clerk.userId) {
    throw new TRPCError({ code: "UNAUTHORIZED", message: "Not logged in" });
  }

  const client = await clerkClient();

  const memberships = await client.users.getOrganizationMembershipList({
    userId: ctx.clerk.userId,
  });

  const activeMembership = memberships.data.find(
    (mem) => mem.organization.id === ctx.clerk.orgId,
  );

  return next({
    ctx: {      
      user: ctx.clerk.userId,
      CustomerId: activeMembership?.organization.publicMetadata?.customerId as string,
      UserId: activeMembership?.publicMetadata?.userId as string,
    },
  });
});

/** Reusable middleware that enforces users are logged in before running the procedure. */
export const protectedProcedure = t.procedure.use(isAuthed);


My test looks like this

import { type inferProcedureInput } from "@trpc/server";
import { expect, test } from "vitest";

import { appRouter, type AppRouter } from "@/server/routers/_app";
import { createTRPCContext } from "@/server/init";


test("example router", async () => {
    const ctx = await createTRPCContext();
    const caller = appRouter.createCaller(ctx);

    type Input = inferProcedureInput<AppRouter["entities"]["get"]>;
    const input: Input = {
        entityType: "test",
        Id: "test",
    };

    const example = await caller.entities.get(input);

    expect(example).toMatchObject({ greeting: "Hello test" });
});


All I really need in the context to test with is CustomerId and UserId but how do I build a test context that has this information?
Was this page helpful?