diff options
| author | Mohamed Bassem <me@mbassem.com> | 2024-12-30 16:55:49 +0000 |
|---|---|---|
| committer | Mohamed Bassem <me@mbassem.com> | 2024-12-30 16:56:23 +0000 |
| commit | 058e7238840b362135fd080045478025e31bf720 (patch) | |
| tree | f094b35163961065d3d145e8ff826219b0bb3506 /packages/e2e_tests/setup | |
| parent | 5aee3404aa7f446a221a88c9b2cd529d1249e22f (diff) | |
| download | karakeep-058e7238840b362135fd080045478025e31bf720.tar.zst | |
chore: Setup and add e2e tests for the API endpoints
Diffstat (limited to 'packages/e2e_tests/setup')
| -rw-r--r-- | packages/e2e_tests/setup/seed.ts | 27 | ||||
| -rw-r--r-- | packages/e2e_tests/setup/startContainers.ts | 75 |
2 files changed, 102 insertions, 0 deletions
diff --git a/packages/e2e_tests/setup/seed.ts b/packages/e2e_tests/setup/seed.ts new file mode 100644 index 00000000..9ab68499 --- /dev/null +++ b/packages/e2e_tests/setup/seed.ts @@ -0,0 +1,27 @@ +import { GlobalSetupContext } from "vitest/node"; + +import { getTrpcClient } from "../utils/trpc"; + +export async function setup({ provide }: GlobalSetupContext) { + const trpc = getTrpcClient(); + await trpc.users.create.mutate({ + name: "Test User", + email: "admin@example.com", + password: "test1234", + confirmPassword: "test1234", + }); + + const { key } = await trpc.apiKeys.exchange.mutate({ + email: "admin@example.com", + password: "test1234", + keyName: "test-key", + }); + provide("adminApiKey", key); + return () => ({}); +} + +declare module "vitest" { + export interface ProvidedContext { + adminApiKey: string; + } +} diff --git a/packages/e2e_tests/setup/startContainers.ts b/packages/e2e_tests/setup/startContainers.ts new file mode 100644 index 00000000..8cc30162 --- /dev/null +++ b/packages/e2e_tests/setup/startContainers.ts @@ -0,0 +1,75 @@ +import { execSync } from "child_process"; +import net from "net"; +import path from "path"; +import { fileURLToPath } from "url"; +import type { GlobalSetupContext } from "vitest/node"; + +async function getRandomPort(): Promise<number> { + const server = net.createServer(); + return new Promise<number>((resolve, reject) => { + server.unref(); + server.on("error", reject); + server.listen(0, () => { + const port = (server.address() as net.AddressInfo).port; + server.close(() => resolve(port)); + }); + }); +} + +async function waitForHealthy(port: number, timeout = 60000): Promise<void> { + const startTime = Date.now(); + + while (Date.now() - startTime < timeout) { + try { + const response = await fetch(`http://localhost:${port}/api/health`); + if (response.status === 200) { + return; + } + } catch (error) { + // Ignore errors and retry + } + await new Promise((resolve) => setTimeout(resolve, 1000)); + } + + throw new Error(`Health check failed after ${timeout}ms`); +} + +export default async function ({ provide }: GlobalSetupContext) { + const __dirname = path.dirname(fileURLToPath(import.meta.url)); + const port = await getRandomPort(); + + console.log(`Starting docker compose on port ${port}...`); + execSync(`docker compose up -d`, { + cwd: __dirname, + stdio: "inherit", + env: { + ...process.env, + HOARDER_PORT: port.toString(), + }, + }); + + console.log("Waiting for service to become healthy..."); + await waitForHealthy(port); + + // Wait 5 seconds for the worker to start + await new Promise((resolve) => setTimeout(resolve, 5000)); + + provide("hoarderPort", port); + + process.env.HOARDER_PORT = port.toString(); + + return async () => { + console.log("Stopping docker compose..."); + execSync("docker compose down", { + cwd: __dirname, + stdio: "inherit", + }); + return Promise.resolve(); + }; +} + +declare module "vitest" { + export interface ProvidedContext { + hoarderPort: number; + } +} |
