import { describe, test, expect, mock, beforeEach, afterEach } from "bun:test"; import type { MirrorRepoRequest } from "@/types/mirror"; import { POST } from "./mirror-repo"; // Mock the database module const mockDb = { select: mock(() => ({ from: mock((table: any) => ({ where: mock(() => { // Return config for configs table if (table === mockConfigs) { return { limit: mock(() => Promise.resolve([{ id: "config-id", userId: "user-id", githubConfig: { token: "github-token", preserveOrgStructure: false, mirrorIssues: false }, giteaConfig: { url: "https://gitea.example.com", token: "gitea-token", username: "giteauser" } }])) }; } // Return repositories for repositories table return Promise.resolve([ { id: "repo-id-1", name: "test-repo-1", visibility: "public", status: "pending", organization: null, lastMirrored: null, errorMessage: null, forkedFrom: null, mirroredLocation: "" }, { id: "repo-id-2", name: "test-repo-2", visibility: "public", status: "pending", organization: null, lastMirrored: null, errorMessage: null, forkedFrom: null, mirroredLocation: "" } ]); }) })) })) }; const mockConfigs = {}; const mockRepositories = {}; mock.module("@/lib/db", () => ({ db: mockDb, configs: mockConfigs, repositories: mockRepositories })); // Mock the gitea module const mockMirrorGithubRepoToGitea = mock(() => Promise.resolve()); const mockMirrorGitHubOrgRepoToGiteaOrg = mock(() => Promise.resolve()); mock.module("@/lib/gitea", () => ({ mirrorGithubRepoToGitea: mockMirrorGithubRepoToGitea, mirrorGitHubOrgRepoToGiteaOrg: mockMirrorGitHubOrgRepoToGiteaOrg })); // Mock the github module const mockCreateGitHubClient = mock(() => ({})); mock.module("@/lib/github", () => ({ createGitHubClient: mockCreateGitHubClient })); // Mock the concurrency module const mockProcessWithResilience = mock(() => Promise.resolve([])); mock.module("@/lib/utils/concurrency", () => ({ processWithResilience: mockProcessWithResilience })); // Mock drizzle-orm mock.module("drizzle-orm", () => ({ eq: mock(() => ({})), inArray: mock(() => ({})) })); // Mock the types mock.module("@/types/Repository", () => ({ repositoryVisibilityEnum: { parse: mock((value: string) => value) }, repoStatusEnum: { parse: mock((value: string) => value) } })); describe("Repository Mirroring API", () => { // Mock console.log and console.error to prevent test output noise let originalConsoleLog: typeof console.log; let originalConsoleError: typeof console.error; beforeEach(() => { originalConsoleLog = console.log; originalConsoleError = console.error; console.log = mock(() => {}); console.error = mock(() => {}); }); afterEach(() => { console.log = originalConsoleLog; console.error = originalConsoleError; }); test("returns 400 if userId is missing", async () => { const request = new Request("http://localhost/api/job/mirror-repo", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ repositoryIds: ["repo-id-1", "repo-id-2"] }) }); const response = await POST({ request } as any); expect(response.status).toBe(400); const data = await response.json(); expect(data.success).toBe(false); expect(data.message).toBe("userId and repositoryIds are required."); }); test("returns 400 if repositoryIds is missing", async () => { const request = new Request("http://localhost/api/job/mirror-repo", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ userId: "user-id" }) }); const response = await POST({ request } as any); expect(response.status).toBe(400); const data = await response.json(); expect(data.success).toBe(false); expect(data.message).toBe("userId and repositoryIds are required."); }); test("returns 200 and starts mirroring repositories", async () => { const request = new Request("http://localhost/api/job/mirror-repo", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ userId: "user-id", repositoryIds: ["repo-id-1", "repo-id-2"] }) }); const response = await POST({ request } as any); expect(response.status).toBe(200); const data = await response.json(); expect(data.success).toBe(true); expect(data.message).toBe("Mirror job started."); expect(data.repositories).toBeDefined(); }); });