190 lines
5.6 KiB
TypeScript
190 lines
5.6 KiB
TypeScript
import { describe, expect, it, vi, beforeEach } from "vitest";
|
|
import { appRouter } from "./routers";
|
|
import type { TrpcContext } from "./_core/context";
|
|
|
|
// Mock db module
|
|
vi.mock("./db", () => ({
|
|
getAllCategories: vi.fn().mockResolvedValue([]),
|
|
getAllBounties: vi.fn().mockResolvedValue([]),
|
|
getBounties: vi.fn().mockResolvedValue([]),
|
|
getBountyById: vi.fn().mockResolvedValue(null),
|
|
createBounty: vi.fn().mockResolvedValue(undefined),
|
|
getUserBounties: vi.fn().mockResolvedValue([]),
|
|
getUserNotifications: vi.fn().mockResolvedValue([]),
|
|
getUnreadNotificationCount: vi.fn().mockResolvedValue(0),
|
|
getUserById: vi.fn().mockResolvedValue(null),
|
|
updateUserStripeInfo: vi.fn().mockResolvedValue(undefined),
|
|
}));
|
|
|
|
// Mock stripe module
|
|
vi.mock("./stripe", () => ({
|
|
createBountyEscrowCheckout: vi.fn().mockResolvedValue({ url: "https://checkout.stripe.com/test" }),
|
|
createConnectAccount: vi.fn().mockResolvedValue({ id: "acct_test" }),
|
|
createAccountLink: vi.fn().mockResolvedValue({ url: "https://connect.stripe.com/test" }),
|
|
getAccountStatus: vi.fn().mockResolvedValue({ chargesEnabled: true, payoutsEnabled: true, detailsSubmitted: true }),
|
|
transferToConnectedAccount: vi.fn().mockResolvedValue({ id: "tr_test" }),
|
|
}));
|
|
|
|
type AuthenticatedUser = NonNullable<TrpcContext["user"]>;
|
|
|
|
function createMockContext(authenticated: boolean = false): TrpcContext {
|
|
const user: AuthenticatedUser | null = authenticated ? {
|
|
id: 1,
|
|
openId: "test-user-123",
|
|
email: "test@example.com",
|
|
name: "Test User",
|
|
loginMethod: "manus",
|
|
role: "user",
|
|
createdAt: new Date(),
|
|
updatedAt: new Date(),
|
|
lastSignedIn: new Date(),
|
|
} : null;
|
|
|
|
return {
|
|
user,
|
|
req: {
|
|
protocol: "https",
|
|
headers: {
|
|
origin: "http://localhost:3000",
|
|
},
|
|
} as TrpcContext["req"],
|
|
res: {
|
|
clearCookie: vi.fn(),
|
|
} as unknown as TrpcContext["res"],
|
|
};
|
|
}
|
|
|
|
describe("Bounty Routes", () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
describe("bounty.list", () => {
|
|
it("returns bounty list for public users", async () => {
|
|
const ctx = createMockContext(false);
|
|
const caller = appRouter.createCaller(ctx);
|
|
|
|
const result = await caller.bounty.list({});
|
|
|
|
expect(result).toEqual([]);
|
|
});
|
|
|
|
it("filters bounties by status", async () => {
|
|
const ctx = createMockContext(false);
|
|
const caller = appRouter.createCaller(ctx);
|
|
|
|
const result = await caller.bounty.list({ status: "open" });
|
|
|
|
expect(result).toBeDefined();
|
|
});
|
|
});
|
|
|
|
describe("bounty.create", () => {
|
|
it("requires authentication to create bounty", async () => {
|
|
const ctx = createMockContext(false);
|
|
const caller = appRouter.createCaller(ctx);
|
|
|
|
await expect(
|
|
caller.bounty.create({
|
|
title: "Test Bounty",
|
|
description: "Test description",
|
|
reward: "100",
|
|
})
|
|
).rejects.toThrow();
|
|
});
|
|
|
|
it("creates bounty for authenticated users", async () => {
|
|
const ctx = createMockContext(true);
|
|
const caller = appRouter.createCaller(ctx);
|
|
|
|
const result = await caller.bounty.create({
|
|
title: "Test Bounty",
|
|
description: "Test description",
|
|
reward: "100",
|
|
});
|
|
|
|
expect(result).toEqual({ success: true });
|
|
});
|
|
});
|
|
|
|
describe("bounty.myPublished", () => {
|
|
it("requires authentication", async () => {
|
|
const ctx = createMockContext(false);
|
|
const caller = appRouter.createCaller(ctx);
|
|
|
|
await expect(caller.bounty.myPublished()).rejects.toThrow();
|
|
});
|
|
|
|
it("returns user published bounties", async () => {
|
|
const ctx = createMockContext(true);
|
|
const caller = appRouter.createCaller(ctx);
|
|
|
|
const result = await caller.bounty.myPublished();
|
|
|
|
expect(result).toEqual([]);
|
|
});
|
|
});
|
|
|
|
describe("bounty.myAccepted", () => {
|
|
it("requires authentication", async () => {
|
|
const ctx = createMockContext(false);
|
|
const caller = appRouter.createCaller(ctx);
|
|
|
|
await expect(caller.bounty.myAccepted()).rejects.toThrow();
|
|
});
|
|
|
|
it("returns user accepted bounties", async () => {
|
|
const ctx = createMockContext(true);
|
|
const caller = appRouter.createCaller(ctx);
|
|
|
|
const result = await caller.bounty.myAccepted();
|
|
|
|
expect(result).toEqual([]);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("Notification Routes", () => {
|
|
describe("notification.list", () => {
|
|
it("requires authentication", async () => {
|
|
const ctx = createMockContext(false);
|
|
const caller = appRouter.createCaller(ctx);
|
|
|
|
await expect(caller.notification.list()).rejects.toThrow();
|
|
});
|
|
|
|
it("returns notifications for authenticated users", async () => {
|
|
const ctx = createMockContext(true);
|
|
const caller = appRouter.createCaller(ctx);
|
|
|
|
const result = await caller.notification.list();
|
|
|
|
expect(result).toEqual([]);
|
|
});
|
|
});
|
|
|
|
describe("notification.unreadCount", () => {
|
|
it("returns unread count for authenticated users", async () => {
|
|
const ctx = createMockContext(true);
|
|
const caller = appRouter.createCaller(ctx);
|
|
|
|
const result = await caller.notification.unreadCount();
|
|
|
|
expect(result).toBe(0);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("Category Routes", () => {
|
|
describe("category.list", () => {
|
|
it("returns categories for public users", async () => {
|
|
const ctx = createMockContext(false);
|
|
const caller = appRouter.createCaller(ctx);
|
|
|
|
const result = await caller.category.list();
|
|
|
|
expect(result).toEqual([]);
|
|
});
|
|
});
|
|
});
|