banatie-service/tests/api/02-flows.ts

227 lines
7.3 KiB
TypeScript

// tests/api/02-flows.ts
import { api, log, runTest, saveImage, waitForGeneration, testContext } from './utils';
import { endpoints } from './config';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
async function main() {
log.section('FLOW TESTS');
// Test 1: Create flow
await runTest('Create flow', async () => {
const result = await api(endpoints.flows, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
meta: { purpose: 'test-flow', description: 'Testing flow functionality' },
}),
});
if (!result.data.data || !result.data.data.id) {
throw new Error('No flow returned');
}
testContext.flowId = result.data.data.id;
log.detail('Flow ID', result.data.data.id);
log.detail('Aliases', JSON.stringify(result.data.data.aliases));
});
// Test 2: List flows
await runTest('List flows', async () => {
const result = await api(endpoints.flows);
if (!result.data.data || !Array.isArray(result.data.data)) {
throw new Error('No flows array returned');
}
log.detail('Total flows', result.data.data.length);
log.detail('Has pagination', !!result.data.pagination);
});
// Test 3: Generate in flow (first generation)
await runTest('Generate in flow (first)', async () => {
const result = await api(endpoints.generations, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
prompt: 'A red sports car on a mountain road',
aspectRatio: '16:9',
flowId: testContext.flowId,
}),
});
if (!result.data.data) {
throw new Error('No generation returned');
}
log.detail('Generation ID', result.data.data.id);
log.detail('Flow ID', result.data.data.flowId);
// Wait for completion
log.info('Waiting for generation to complete...');
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);
// Save image
if (generation.outputImageId) {
const imageResult = await api(`${endpoints.images}/${generation.outputImageId}`);
const imageUrl = imageResult.data.image.storageUrl;
const imageResponse = await fetch(imageUrl);
const imageBuffer = await imageResponse.arrayBuffer();
await saveImage(imageBuffer, 'flow-gen-1.png');
}
});
// Test 4: Generate in flow (second generation) with @last reference
await runTest('Generate in flow with @last', async () => {
const result = await api(endpoints.generations, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
prompt: 'Same as @last but make it blue instead of red',
aspectRatio: '16:9',
flowId: testContext.flowId,
referenceImages: ['@last'],
}),
});
if (!result.data.data) {
throw new Error('No generation returned');
}
log.detail('Generation ID', result.data.data.id);
log.detail('Referenced @last', result.data.data.referencedImages?.some((r: any) => r.alias === '@last'));
// Wait for completion
log.info('Waiting for generation to complete...');
const generation = await waitForGeneration(result.data.data.id);
if (generation.status !== 'success') {
throw new Error(`Generation failed: ${generation.errorMessage}`);
}
// Save image
if (generation.outputImageId) {
const imageResult = await api(`${endpoints.images}/${generation.outputImageId}`);
const imageUrl = imageResult.data.image.storageUrl;
const imageResponse = await fetch(imageUrl);
const imageBuffer = await imageResponse.arrayBuffer();
await saveImage(imageBuffer, 'flow-gen-2-with-last.png');
}
});
// Test 5: Get flow details
await runTest('Get flow details', async () => {
const result = await api(`${endpoints.flows}/${testContext.flowId}`);
if (!result.data.data) {
throw new Error('Flow not found');
}
log.detail('Flow ID', result.data.data.id);
log.detail('Generations count', result.data.datas?.length || 0);
log.detail('Images count', result.data.data?.length || 0);
log.detail('Resolved aliases', Object.keys(result.data.resolvedAliases || {}).length);
});
// Test 6: Update flow aliases
await runTest('Update flow aliases', async () => {
// First, get the latest generation's image ID
const flowResult = await api(`${endpoints.flows}/${testContext.flowId}`);
const lastGeneration = flowResult.data.generations[flowResult.data.generations.length - 1];
if (!lastGeneration.outputImageId) {
throw new Error('No output image for alias assignment');
}
const result = await api(`${endpoints.flows}/${testContext.flowId}/aliases`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
aliases: {
'@hero': lastGeneration.outputImageId,
'@featured': lastGeneration.outputImageId,
},
}),
});
if (!result.data.data) {
throw new Error('Flow not returned');
}
log.detail('Updated aliases', JSON.stringify(result.data.data.aliases));
});
// Test 7: Generate with flow-scoped alias
await runTest('Generate with flow-scoped alias', async () => {
const result = await api(endpoints.generations, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
prompt: 'A poster design featuring @hero image',
aspectRatio: '9:16',
flowId: testContext.flowId,
referenceImages: ['@hero'],
}),
});
if (!result.data.data) {
throw new Error('No generation returned');
}
log.detail('Generation ID', result.data.data.id);
log.detail('Referenced @hero', result.data.data.referencedImages?.some((r: any) => r.alias === '@hero'));
// Wait for completion
log.info('Waiting for generation to complete...');
const generation = await waitForGeneration(result.data.data.id);
if (generation.status !== 'success') {
throw new Error(`Generation failed: ${generation.errorMessage}`);
}
// Save image
if (generation.outputImageId) {
const imageResult = await api(`${endpoints.images}/${generation.outputImageId}`);
const imageUrl = imageResult.data.image.storageUrl;
const imageResponse = await fetch(imageUrl);
const imageBuffer = await imageResponse.arrayBuffer();
await saveImage(imageBuffer, 'flow-gen-with-hero.png');
}
});
// Test 8: Delete flow alias
await runTest('Delete flow alias', async () => {
await api(`${endpoints.flows}/${testContext.flowId}/aliases/@featured`, {
method: 'DELETE',
});
// Verify it's deleted
const result = await api(`${endpoints.flows}/${testContext.flowId}`);
const hasFeatureAlias = '@featured' in result.data.data.aliases;
if (hasFeatureAlias) {
throw new Error('Alias was not deleted');
}
log.detail('Remaining aliases', JSON.stringify(result.data.data.aliases));
});
log.section('FLOW TESTS COMPLETED');
}
main().catch(console.error);