import { expect, test, vi } from "vitest" import { createApiSchema, createApiTest, testApi } from "#Source/http/index.ts" import type { Standard } from "#Source/validation/index.ts" const createSchema = ( validate: (value: unknown) => Standard.Schema.Result, ): Standard.Schema => { return { "~standard": { version: 1 as const, vendor: "mobius-http-test", validate, }, } } const passthroughSchema = createSchema((value) => { return { value, } }) const apiSchema = createApiSchema({ path: "/health", method: "get", inputQuerySchema: passthroughSchema, inputBodySchema: passthroughSchema, outputSuccessSchema: passthroughSchema, outputErrorSchema: passthroughSchema, }) const beforeApiTestHandler = vi.fn(async () => { await Promise.resolve() return { token: "before", } }) const apiTestHandler = vi.fn(async () => { await Promise.resolve() return { token: "during", } }) const afterApiTestHandler = vi.fn(async () => { await Promise.resolve() return { token: "after", } }) const apiTest = createApiTest({ apiSchema, beforeApiTestHandler, apiTestHandler, afterApiTestHandler, }) test("ApiTest.getApiSchema returns the configured schema", () => { expect(apiTest.getApiSchema()).toBe(apiSchema) }) test("ApiTest.getBeforeApiTestHandler returns the configured before handler", () => { expect(apiTest.getBeforeApiTestHandler()).toBe(beforeApiTestHandler) }) test("ApiTest.getApiTestHandler returns the configured test handler", () => { expect(apiTest.getApiTestHandler()).toBe(apiTestHandler) }) test("ApiTest.getAfterApiTestHandler returns the configured after handler", () => { expect(apiTest.getAfterApiTestHandler()).toBe(afterApiTestHandler) }) test("testApi executes the configured handlers in order and forwards intermediate results", async () => { const callOrder: string[] = [] const orchestratedApiTest = createApiTest({ apiSchema, beforeApiTestHandler: async (context) => { await Promise.resolve() callOrder.push(`before:${context.apiSchema.getPath()}`) return { requestId: "r1", } }, apiTestHandler: async (context) => { await Promise.resolve() callOrder.push(`test:${context.beforeApiTestResult.requestId}`) return { statusCode: 200, } }, afterApiTestHandler: async (context) => { await Promise.resolve() callOrder.push(`after:${context.apiTestResult.statusCode}`) return { summary: `${context.apiSchema.getMethod()} ${context.beforeApiTestResult.requestId}`, } }, }) const result = await testApi({ apiTest: orchestratedApiTest, }) expect(callOrder).toEqual(["before:/health", "test:r1", "after:200"]) expect(result).toEqual({ summary: "get r1", }) })