Skip to main content
Glama
alexander-zuev

Kollektiv | Your private LLM knowledgebase

apiClient.test.ts4.86 kB
import {createApiClient} from "@/api/client/base"; import {ApiError} from "@/api/types/base"; import {describe, expect, it} from "vitest"; // Define the expected structure for the /json endpoint response interface HttpbinJsonResponse { slideshow: { author: string; date: string; slides: Array<{ title: string; type: string; items?: string[] }>; title: string; }; } const skipIntegration = process.env.CI || process.env.SKIP_INTEGRATION; describe.skipIf(skipIntegration)("API Client integration tests using HTTPBIN", () => { const apiClient = createApiClient({baseUrl: "https://httpbin.org"}); const testTimeoutMs = 10000; // 10 sec for external calls // Helper to handle potential 5xx errors from httpbin and skip the test const runTestHandlingHttpbin5xx = async (testFn: () => Promise<void>, context: any) => { try { await testFn(); } catch (error) { // If httpbin returns 5xx, it's their issue, not ours. Skip the test. if (error instanceof ApiError && error.status >= 500) { console.warn( `[WARN] Skipping test due to httpbin server error: ${error.status} ${error.message}`, ); context.skip(); // Use Vitest's context.skip() return; // Exit early } // If it's an assertion error with a message about 5xx status, also skip the test if ( error instanceof Error && (error.message.includes("503") || error.message.includes("5xx") || error.message.includes("server error")) ) { console.warn(`[WARN] Skipping test due to possible httpbin server error: ${error.message}`); context.skip(); // Use Vitest's context.skip() return; // Exit early } // Re-throw other errors (like 4xx, network errors, other assertion failures) throw error; } }; // Updated Test: GET request to /json endpoint it( "should GET JSON structure from /json endpoint", async (context) => { await runTestHandlingHttpbin5xx(async () => { const response = await apiClient.get<HttpbinJsonResponse>("/json" as any, { timeoutMs: testTimeoutMs, // Add test-specific timeout }); // Basic structure checks: Verify the 'slideshow' object and some of its properties exist expect(response).toBeDefined(); expect(response).toHaveProperty("slideshow"); expect(response.slideshow).toHaveProperty("author"); expect(response.slideshow).toHaveProperty("title"); expect(response.slideshow).toHaveProperty("slides"); expect(Array.isArray(response.slideshow.slides)).toBe(true); // You could add more specific checks here if needed, e.g., checking types or specific values expect(typeof response.slideshow.author).toBe("string"); }, context); }, testTimeoutMs + 1000, ); // Vitest timeout slightly longer than request timeout it( "should POST JSON (camelCase) and receive echoed data (camelCase)", async (context) => { await runTestHandlingHttpbin5xx(async () => { const body = {userId: "testUser", isActive: true, nestedData: {value: 1}}; // Client converts body to snake_case, httpbin echoes it, client converts response back to camelCase const response = await apiClient.post<{ json: typeof body; }>("/anything" as any, body, {timeoutMs: testTimeoutMs}); expect(response.json).toEqual(body); }, context); }, testTimeoutMs + 1000, ); it( "should handle expected 4xx client errors correctly", async (context) => { await runTestHandlingHttpbin5xx(async () => { // First test: Check that the request throws an ApiError await expect( apiClient.get("/status/404" as any, {timeoutMs: testTimeoutMs}), ).rejects.toThrowError(ApiError); // Expect ApiError specifically // Second test: Check the error properties try { await apiClient.get("/status/404" as any, {timeoutMs: testTimeoutMs}); } catch (error: any) { expect(error).toBeInstanceOf(ApiError); // Check that it's an error status code (4xx or 5xx) expect(error.status).toBeGreaterThanOrEqual(400); } }, context); }, testTimeoutMs + 1000, ); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/alexander-zuev/kollektiv-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server