import { describe, test, expect, beforeEach, afterEach, beforeAll, afterAll } from 'bun:test'; import { execa } from 'execa'; import { setupTest } from '../helpers/setup.js'; import { createMockServer, type MockServer } from '../helpers/mock-server.js'; import { FIXTURES } from '../helpers/fixtures.js'; import { join } from 'path'; import { fileExists, readTextFile } from '../../src/utils/file.js'; import { fileURLToPath } from 'url'; import { dirname } from 'path'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const CLI_PATH = join(__dirname, '../../src/cli.ts'); describe('E2E Generation', () => { let tempDir: string; let cleanup: () => Promise; let mockServer: MockServer; beforeAll(() => { mockServer = createMockServer(); mockServer.start(); }); afterAll(() => { mockServer.stop(); }); beforeEach(async () => { const setup = await setupTest(); tempDir = setup.tempDir; cleanup = setup.cleanup; mockServer.reset(); }); afterEach(async () => { await cleanup(); }); describe('полный цикл генерации', () => { test.skip('CLI генерация → создание файла → импорт → использование', async () => { const outputPath = join(tempDir, 'output'); // 1. Генерация через CLI const { exitCode } = await execa('bun', [ 'run', CLI_PATH, '--input', FIXTURES.VALID, '--output', outputPath, '--name', 'TestApi', ]); expect(exitCode).toBe(0); // 2. Проверка создания файла const generatedFile = join(outputPath, 'TestApi.ts'); const exists = await fileExists(generatedFile); expect(exists).toBe(true); // 3. Проверка импорта (компиляция TypeScript) const testFile = join(tempDir, 'test-import.ts'); const testCode = ` import { Api } from '${generatedFile}'; const api = new Api(); console.log('Import successful'); `; await Bun.write(testFile, testCode); // Компилируем тестовый файл const { exitCode: compileExitCode } = await execa('bun', ['build', testFile, '--outdir', tempDir]); expect(compileExitCode).toBe(0); }, 60000); test('генерация из локального файла', async () => { const outputPath = join(tempDir, 'output'); const { exitCode } = await execa('bun', [ 'run', CLI_PATH, '--input', FIXTURES.MINIMAL, '--output', outputPath, ]); expect(exitCode).toBe(0); const generatedFile = join(outputPath, 'MinimalAPI.ts'); const exists = await fileExists(generatedFile); expect(exists).toBe(true); }, 30000); test('повторная генерация (перезапись файлов)', async () => { const outputPath = join(tempDir, 'output'); const fileName = 'TestApi'; // Первая генерация await execa('bun', [ 'run', CLI_PATH, '--input', FIXTURES.MINIMAL, '--output', outputPath, '--name', fileName, ]); const generatedFile = join(outputPath, `${fileName}.ts`); const firstContent = await readTextFile(generatedFile); // Вторая генерация (перезапись) await execa('bun', [ 'run', CLI_PATH, '--input', FIXTURES.VALID, '--output', outputPath, '--name', fileName, ]); const secondContent = await readTextFile(generatedFile); // Содержимое должно отличаться expect(firstContent).not.toBe(secondContent); // Файл должен существовать const exists = await fileExists(generatedFile); expect(exists).toBe(true); }, 60000); }); describe('HTTP запросы с mock сервером', () => { test.skip('GET запрос без параметров', async () => { const outputPath = join(tempDir, 'output'); await execa('bun', [ 'run', CLI_PATH, '--input', FIXTURES.VALID, '--output', outputPath, '--name', 'TestApi', ]); // Создаем тестовый файл для вызова API const testFile = join(tempDir, 'test-get.ts'); const testCode = ` import { Api } from '${join(outputPath, 'TestApi.ts')}'; const api = new Api(); const result = await api.user.getAll(); console.log(JSON.stringify(result)); `; await Bun.write(testFile, testCode); const { stdout } = await execa('bun', ['run', testFile]); const data = JSON.parse(stdout); expect(Array.isArray(data)).toBe(true); expect(data.length).toBe(2); }, 60000); test.skip('POST запрос с body', async () => { const outputPath = join(tempDir, 'output'); await execa('bun', [ 'run', CLI_PATH, '--input', FIXTURES.VALID, '--output', outputPath, '--name', 'TestApi', ]); const testFile = join(tempDir, 'test-post.ts'); const testCode = ` import { Api } from '${join(outputPath, 'TestApi.ts')}'; const api = new Api(); const result = await api.user.create({ email: 'new@example.com', password: 'password123' }); console.log(JSON.stringify(result)); `; await Bun.write(testFile, testCode); const { stdout } = await execa('bun', ['run', testFile]); const data = JSON.parse(stdout); expect(data.id).toBe('3'); expect(data.email).toBe('new@example.com'); }, 60000); test.skip('обработка 404 статуса', async () => { const outputPath = join(tempDir, 'output'); await execa('bun', [ 'run', CLI_PATH, '--input', FIXTURES.VALID, '--output', outputPath, '--name', 'TestApi', ]); const testFile = join(tempDir, 'test-404.ts'); const testCode = ` import { Api } from '${join(outputPath, 'TestApi.ts')}'; const api = new Api(); try { await api.user.getById('999'); } catch (error) { console.log('error'); } `; await Bun.write(testFile, testCode); const { stdout } = await execa('bun', ['run', testFile]); expect(stdout).toContain('error'); }, 60000); test.skip('Bearer token authentication', async () => { const outputPath = join(tempDir, 'output'); await execa('bun', [ 'run', CLI_PATH, '--input', FIXTURES.WITH_AUTH, '--output', outputPath, '--name', 'AuthApi', ]); const testFile = join(tempDir, 'test-auth.ts'); const testCode = ` import { Api } from '${join(outputPath, 'AuthApi.ts')}'; const api = new Api(); // Логин const { token } = await api.auth.login({ email: 'test@example.com', password: 'password' }); // Установка токена api.instance.setSecurityData(token); // Запрос с токеном const profile = await api.profile.get(); console.log(JSON.stringify(profile)); `; await Bun.write(testFile, testCode); const { stdout } = await execa('bun', ['run', testFile]); const data = JSON.parse(stdout); expect(data.email).toBe('test@example.com'); }, 60000); }); });