UNPKG

apiveritas

Version:

Lightweight CLI tool for consumer-driven API contract testing via JSON schema and payload comparisons.

113 lines (95 loc) 4.01 kB
/** * @file TestSuiteLoader.ts * @author Mario Galea * @description * Responsible for loading API test suites from disk and preparing them for execution by enriching them with metadata. * Supports both real and mock test modes depending on configuration. */ import fs from 'fs'; import path from 'path'; import { IApiRequest } from '../../interfaces/IApiRequest'; import { Logger } from '../utils/Logger'; import { IComparerOptions } from '../../interfaces/IComparerOptions'; /** * Handles loading of test suite files (JSON), enriching each test with metadata like baseUrl and testSuite name. * Also supports mock server mode for isolated contract test runs. */ export class TestSuiteLoader { private static logger = new Logger({ level: 'info' }); /** * Loads and parses a test suite JSON file, returning a list of API requests enriched with suite-specific metadata. * * - Validates file presence and schema integrity. * - Supports switching to mock test mode via `config.enableMockServer`. * - Injects `testSuite` and `baseUrl` fields into each request. * * @param testFileName - The name of the test suite JSON file (e.g., `bookings.json`). * @param config - Optional comparer configuration, including mock mode and base URL overrides. * @returns An array of enriched `ApiRequest` objects ready to be called. * * @throws Will throw if: * - The file doesn't exist. * - The file doesn't contain an array. * - Any test entry is missing required fields (`name`, `url`). * - JSON parse fails. */ static loadSuite(testFileName: string, config?: IComparerOptions): IApiRequest[] { const useMock = config?.enableMockServer; const actualFile = useMock ? 'mock.json' : testFileName; const baseUrl = useMock ? 'http://localhost:3000' : config?.baseUrl || 'http://localhost:8080'; if (useMock) { this.logger.info( '\n> Mock server mode enabled\n> Mock Test Suite: mock.json\n> Mock BaseUrl: http://localhost:3000\n' ); } const testFolder = useMock ? 'mock' : 'real'; const testFilePath = path.resolve(process.cwd(), 'apiveritas', 'tests', testFolder, actualFile); console.log(testFolder); // Check file existence if (!fs.existsSync(testFilePath)) { this.logger.error(`Test file not found: ${testFilePath}`); throw new Error(`Test file not found: ${testFilePath}`); } try { // Read and parse the test suite JSON const rawData = fs.readFileSync(testFilePath, 'utf-8'); const parsed = JSON.parse(rawData); if (!Array.isArray(parsed)) { throw new Error('Test suite JSON must be an array of API definitions'); } const suiteName = path.basename(actualFile, '.json'); // Validate and enrich each test case const enrichedRequests = parsed.map((entry, i) => { if (!entry.name || !entry.url) { throw new Error(`Test case at index ${i} is missing required fields (name, url)`); } return { ...entry, testSuite: suiteName, baseUrl, // inject resolved base URL }; }); return enrichedRequests as IApiRequest[]; } catch (err: any) { this.logger.error(`Failed to parse or validate test suite file: ${err.message}`); throw err; } } /** * Lists all available test suite JSON files in the `tests/` directory. * * Useful for CLI commands like `apiveritas list-tests` or for UI tools. * * @returns A list of file names ending in `.json` from the `tests/` folder. */ static listAvailableSuites(): string[] { const testsDir = path.resolve(process.cwd(), 'apiveritas', 'tests', 'real'); // If folder doesn't exist, return empty list if (!fs.existsSync(testsDir)) return []; return fs .readdirSync(testsDir) .filter((file) => file.endsWith('.json')); } }