From 3a9b8380d4bfbdb742859b87bc674f5bd3be12b3 Mon Sep 17 00:00:00 2001 From: Arunavo Ray Date: Sun, 27 Jul 2025 20:27:33 +0530 Subject: [PATCH] fix: resolve CI test failures and timeouts - Update Bun version in CI to match local version (1.2.16) - Add bunfig.toml with 5s test timeout to prevent hanging tests - Mock setTimeout globally in test setup to avoid timing issues - Add NODE_ENV check to skip delays during tests - Fix missing exports in config-encryption mock - Remove retryDelay in tests to ensure immediate execution These changes ensure tests run consistently between local and CI environments --- .github/workflows/astro-build-test.yml | 2 +- bunfig.toml | 6 ++++++ src/lib/gitea-enhanced.test.ts | 13 ++----------- src/lib/gitea-enhanced.ts | 6 ++++-- src/lib/mirror-sync-errors.test.ts | 9 +++++++++ src/tests/setup.bun.ts | 25 +++++++++++++++++++++++++ 6 files changed, 47 insertions(+), 14 deletions(-) create mode 100644 bunfig.toml diff --git a/.github/workflows/astro-build-test.yml b/.github/workflows/astro-build-test.yml index f874d3a..4905931 100644 --- a/.github/workflows/astro-build-test.yml +++ b/.github/workflows/astro-build-test.yml @@ -28,7 +28,7 @@ jobs: - name: Setup Bun uses: oven-sh/setup-bun@v1 with: - bun-version: '1.2.9' + bun-version: '1.2.16' - name: Check lockfile and install dependencies run: | diff --git a/bunfig.toml b/bunfig.toml new file mode 100644 index 0000000..b0cfcc4 --- /dev/null +++ b/bunfig.toml @@ -0,0 +1,6 @@ +[test] +# Set test timeout to 5 seconds (5000ms) to prevent hanging tests +timeout = 5000 + +# Preload the setup file +preload = ["./src/tests/setup.bun.ts"] \ No newline at end of file diff --git a/src/lib/gitea-enhanced.test.ts b/src/lib/gitea-enhanced.test.ts index b00c404..0b32fb4 100644 --- a/src/lib/gitea-enhanced.test.ts +++ b/src/lib/gitea-enhanced.test.ts @@ -38,27 +38,17 @@ import { repoStatusEnum } from "@/types/Repository"; describe("Enhanced Gitea Operations", () => { let originalFetch: typeof global.fetch; - let originalTimeout: typeof global.setTimeout; beforeEach(() => { originalFetch = global.fetch; - originalTimeout = global.setTimeout; // Clear mocks mockCreateMirrorJob.mockClear(); mockDb.insert.mockClear(); mockDb.update.mockClear(); - - // Mock setTimeout for consistent timing in tests - global.setTimeout = ((fn: Function, delay: number) => { - // Execute immediately in tests to avoid timing issues - fn(); - return 0; - }) as any; }); afterEach(() => { global.fetch = originalFetch; - global.setTimeout = originalTimeout; }); describe("getGiteaRepoInfo", () => { @@ -196,7 +186,7 @@ describe("Enhanced Gitea Operations", () => { orgName: "starred", config, maxRetries: 3, - retryDelay: 10, + retryDelay: 0, // No delay in tests }); expect(orgId).toBe(999); @@ -248,6 +238,7 @@ describe("Enhanced Gitea Operations", () => { const orgId = await getOrCreateGiteaOrgEnhanced({ orgName: "neworg", config, + retryDelay: 0, // No delay in tests }); expect(orgId).toBe(777); diff --git a/src/lib/gitea-enhanced.ts b/src/lib/gitea-enhanced.ts index 46db399..021043c 100644 --- a/src/lib/gitea-enhanced.ts +++ b/src/lib/gitea-enhanced.ts @@ -157,9 +157,11 @@ export async function getOrCreateGiteaOrgEnhanced({ console.log(`[Org Creation] Organization creation failed due to duplicate. Will retry check.`); // Wait before retry with exponential backoff - const delay = retryDelay * Math.pow(2, attempt); + const delay = process.env.NODE_ENV === 'test' ? 0 : retryDelay * Math.pow(2, attempt); console.log(`[Org Creation] Waiting ${delay}ms before retry...`); - await new Promise(resolve => setTimeout(resolve, delay)); + if (delay > 0) { + await new Promise(resolve => setTimeout(resolve, delay)); + } continue; // Retry the loop } } diff --git a/src/lib/mirror-sync-errors.test.ts b/src/lib/mirror-sync-errors.test.ts index 59c6524..74d3020 100644 --- a/src/lib/mirror-sync-errors.test.ts +++ b/src/lib/mirror-sync-errors.test.ts @@ -6,10 +6,18 @@ import type { Config, Repository } from "./db/schema"; describe("Mirror Sync Error Handling", () => { let originalFetch: typeof global.fetch; + let originalSetTimeout: typeof global.setTimeout; let mockDbUpdate: any; beforeEach(() => { originalFetch = global.fetch; + originalSetTimeout = global.setTimeout; + + // Mock setTimeout to avoid delays in tests + global.setTimeout = ((fn: Function) => { + Promise.resolve().then(() => fn()); + return 0; + }) as any; // Mock database update operations mockDbUpdate = mock(() => ({ @@ -24,6 +32,7 @@ describe("Mirror Sync Error Handling", () => { afterEach(() => { global.fetch = originalFetch; + global.setTimeout = originalSetTimeout; }); describe("Mirror sync API errors", () => { diff --git a/src/tests/setup.bun.ts b/src/tests/setup.bun.ts index a4ebef7..281e970 100644 --- a/src/tests/setup.bun.ts +++ b/src/tests/setup.bun.ts @@ -8,6 +8,23 @@ import { mock } from "bun:test"; // Set NODE_ENV to test process.env.NODE_ENV = "test"; +// Mock setTimeout globally to prevent hanging tests +const originalSetTimeout = global.setTimeout; +global.setTimeout = ((fn: Function, delay?: number) => { + // In tests, execute immediately or with minimal delay + if (delay && delay > 100) { + // For long delays, execute immediately + Promise.resolve().then(() => fn()); + } else { + // For short delays, use setImmediate-like behavior + Promise.resolve().then(() => fn()); + } + return 0; +}) as any; + +// Restore setTimeout for any code that needs real timing +(global as any).__originalSetTimeout = originalSetTimeout; + // Mock the database module to prevent real database access during tests mock.module("@/lib/db", () => { const mockDb = { @@ -66,6 +83,14 @@ mock.module("@/lib/utils/config-encryption", () => { encryptConfigTokens: (config: any) => { // Return the config as-is for tests return config; + }, + getDecryptedGitHubToken: (config: any) => { + // Return the token as-is for tests + return config.githubConfig?.token || ""; + }, + getDecryptedGiteaToken: (config: any) => { + // Return the token as-is for tests + return config.giteaConfig?.token || ""; } }; });