206 lines
6.9 KiB
TypeScript
206 lines
6.9 KiB
TypeScript
// tests/api/01-generation-basic.ts
|
|
// Basic Image Generation Tests - Run FIRST to verify core functionality
|
|
|
|
import { api, log, runTest, saveImage, waitForGeneration, testContext, verifyImageAccessible } from './utils';
|
|
import { endpoints } from './config';
|
|
|
|
async function main() {
|
|
log.section('GENERATION BASIC TESTS');
|
|
|
|
// Test 1: Simple generation without references
|
|
await runTest('Generate image - simple prompt', async () => {
|
|
const result = await api(endpoints.generations, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
prompt: 'A beautiful sunset over mountains',
|
|
aspectRatio: '16:9',
|
|
}),
|
|
});
|
|
|
|
if (!result.data.data || !result.data.data.id) {
|
|
throw new Error('No generation returned');
|
|
}
|
|
|
|
testContext.basicGenerationId = result.data.data.id;
|
|
log.detail('Generation ID', result.data.data.id);
|
|
log.detail('Status', result.data.data.status);
|
|
|
|
// Wait for completion
|
|
log.info('Waiting for generation to complete...');
|
|
const generation = await waitForGeneration(testContext.basicGenerationId);
|
|
|
|
if (generation.status !== 'success') {
|
|
throw new Error(`Generation failed: ${generation.errorMessage}`);
|
|
}
|
|
|
|
if (!generation.outputImageId) {
|
|
throw new Error('No output image ID');
|
|
}
|
|
|
|
log.detail('Processing time', `${generation.processingTimeMs}ms`);
|
|
log.detail('Output image ID', generation.outputImageId);
|
|
|
|
// Verify image exists and is accessible
|
|
const imageResult = await api(`${endpoints.images}/${generation.outputImageId}`);
|
|
const imageUrl = imageResult.data.data.storageUrl;
|
|
|
|
const accessible = await verifyImageAccessible(imageUrl);
|
|
if (!accessible) {
|
|
throw new Error('Generated image not accessible');
|
|
}
|
|
|
|
// Save for manual inspection
|
|
const imageResponse = await fetch(imageUrl);
|
|
const imageBuffer = await imageResponse.arrayBuffer();
|
|
await saveImage(imageBuffer, 'gen-basic-simple.png');
|
|
|
|
testContext.basicOutputImageId = generation.outputImageId;
|
|
});
|
|
|
|
// Test 2: Generation with aspect ratio 1:1
|
|
await runTest('Generate image - square (1:1)', async () => {
|
|
const result = await api(endpoints.generations, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
prompt: 'A minimalist logo design',
|
|
aspectRatio: '1:1',
|
|
}),
|
|
});
|
|
|
|
const generation = await waitForGeneration(result.data.data.id);
|
|
|
|
if (generation.status !== 'success') {
|
|
throw new Error(`Generation failed: ${generation.errorMessage}`);
|
|
}
|
|
|
|
log.detail('Output image', generation.outputImageId);
|
|
});
|
|
|
|
// Test 3: Generation with aspect ratio 9:16 (portrait)
|
|
await runTest('Generate image - portrait (9:16)', async () => {
|
|
const result = await api(endpoints.generations, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
prompt: 'A tall building at night',
|
|
aspectRatio: '9:16',
|
|
}),
|
|
});
|
|
|
|
const generation = await waitForGeneration(result.data.data.id);
|
|
|
|
if (generation.status !== 'success') {
|
|
throw new Error(`Generation failed: ${generation.errorMessage}`);
|
|
}
|
|
|
|
log.detail('Aspect ratio', '9:16');
|
|
log.detail('Output image', generation.outputImageId);
|
|
});
|
|
|
|
// Test 4: Get generation details
|
|
await runTest('Get generation by ID', async () => {
|
|
const result = await api(`${endpoints.generations}/${testContext.basicGenerationId}`);
|
|
|
|
if (!result.data.data) {
|
|
throw new Error('Generation not found');
|
|
}
|
|
|
|
const generation = result.data.data;
|
|
|
|
// Verify all expected fields present
|
|
if (!generation.id) throw new Error('Missing id');
|
|
if (!generation.prompt) throw new Error('Missing prompt');
|
|
if (!generation.status) throw new Error('Missing status');
|
|
if (!generation.outputImageId) throw new Error('Missing outputImageId');
|
|
if (!generation.createdAt) throw new Error('Missing createdAt');
|
|
|
|
log.detail('Generation ID', generation.id);
|
|
log.detail('Prompt', generation.prompt);
|
|
log.detail('Status', generation.status);
|
|
log.detail('Has output image', !!generation.outputImage);
|
|
});
|
|
|
|
// Test 5: List generations
|
|
await runTest('List all generations', async () => {
|
|
const result = await api(endpoints.generations);
|
|
|
|
if (!result.data.data || !Array.isArray(result.data.data)) {
|
|
throw new Error('No generations array returned');
|
|
}
|
|
|
|
log.detail('Total generations', result.data.data.length);
|
|
|
|
// Verify our generation is in the list
|
|
const found = result.data.data.find((g: any) => g.id === testContext.basicGenerationId);
|
|
if (!found) {
|
|
throw new Error('Created generation not in list');
|
|
}
|
|
|
|
log.detail('Found our generation', '✓');
|
|
log.detail('Successful generations', result.data.data.filter((g: any) => g.status === 'success').length);
|
|
});
|
|
|
|
// Test 6: List generations with pagination
|
|
await runTest('List generations with pagination', async () => {
|
|
const result = await api(`${endpoints.generations}?limit=2&offset=0`);
|
|
|
|
if (!result.data.data || !Array.isArray(result.data.data)) {
|
|
throw new Error('No generations array returned');
|
|
}
|
|
|
|
if (!result.data.pagination) {
|
|
throw new Error('No pagination data');
|
|
}
|
|
|
|
log.detail('Limit', result.data.pagination.limit);
|
|
log.detail('Offset', result.data.pagination.offset);
|
|
log.detail('Total', result.data.pagination.total);
|
|
log.detail('Has more', result.data.pagination.hasMore);
|
|
|
|
// Results should be limited
|
|
if (result.data.data.length > 2) {
|
|
throw new Error('Pagination limit not applied');
|
|
}
|
|
});
|
|
|
|
// Test 7: List generations with status filter
|
|
await runTest('List generations - filter by status', async () => {
|
|
const result = await api(`${endpoints.generations}?status=success`);
|
|
|
|
if (!result.data.data || !Array.isArray(result.data.data)) {
|
|
throw new Error('No generations array returned');
|
|
}
|
|
|
|
// All results should have success status
|
|
const allSuccess = result.data.data.every((g: any) => g.status === 'success');
|
|
if (!allSuccess) {
|
|
throw new Error('Status filter not working');
|
|
}
|
|
|
|
log.detail('Success generations', result.data.data.length);
|
|
});
|
|
|
|
// Test 8: Generation processing time is recorded
|
|
await runTest('Verify processing time recorded', async () => {
|
|
const result = await api(`${endpoints.generations}/${testContext.basicGenerationId}`);
|
|
const generation = result.data.data;
|
|
|
|
if (typeof generation.processingTimeMs !== 'number') {
|
|
throw new Error('Processing time not recorded');
|
|
}
|
|
|
|
if (generation.processingTimeMs <= 0) {
|
|
throw new Error('Processing time should be positive');
|
|
}
|
|
|
|
log.detail('Processing time', `${generation.processingTimeMs}ms`);
|
|
log.detail('Approximately', `${(generation.processingTimeMs / 1000).toFixed(2)}s`);
|
|
});
|
|
|
|
log.section('GENERATION BASIC TESTS COMPLETED');
|
|
}
|
|
|
|
main().catch(console.error);
|