banatie-service/tests/api/test-04-live.ts

228 lines
7.1 KiB
TypeScript

// tests/api/04-live.ts
import { api, log, runTest, saveImage, wait } from './utils';
import { endpoints } from './config';
async function main() {
log.section('LIVE ENDPOINT TESTS');
// Test 1: First call (cache MISS)
await runTest('Live generation - cache MISS', async () => {
const params = new URLSearchParams({
prompt: 'A serene zen garden with rocks and sand',
aspectRatio: '16:9',
});
const startTime = Date.now();
const result = await api(`${endpoints.live}?${params}`, {
timeout: 60000, // Longer timeout for generation
});
const duration = Date.now() - startTime;
// Should return image buffer
if (!(result.data instanceof ArrayBuffer)) {
throw new Error('Expected image buffer');
}
// Check cache status header
const cacheStatus = result.headers.get('X-Cache-Status');
if (cacheStatus !== 'MISS') {
throw new Error(`Expected cache MISS, got: ${cacheStatus}`);
}
log.detail('Cache status', cacheStatus);
log.detail('Duration', `${duration}ms`);
log.detail('Content-Type', result.headers.get('Content-Type'));
log.detail('Image size', `${result.data.byteLength} bytes`);
await saveImage(result.data, 'live-cache-miss.png');
});
// Test 2: Second call with same params (cache HIT)
await runTest('Live generation - cache HIT', async () => {
const params = new URLSearchParams({
prompt: 'A serene zen garden with rocks and sand',
aspectRatio: '16:9',
});
const startTime = Date.now();
const result = await api(`${endpoints.live}?${params}`);
const duration = Date.now() - startTime;
// Check cache status header
const cacheStatus = result.headers.get('X-Cache-Status');
if (cacheStatus !== 'HIT') {
throw new Error(`Expected cache HIT, got: ${cacheStatus}`);
}
log.detail('Cache status', cacheStatus);
log.detail('Duration', `${duration}ms (should be faster)`);
log.detail('Image size', `${result.data.byteLength} bytes`);
await saveImage(result.data, 'live-cache-hit.png');
});
// Test 3: Different aspect ratio (new cache entry)
await runTest('Live generation - different params', async () => {
const params = new URLSearchParams({
prompt: 'A serene zen garden with rocks and sand',
aspectRatio: '1:1', // Different aspect ratio
});
const result = await api(`${endpoints.live}?${params}`, {
timeout: 60000,
});
const cacheStatus = result.headers.get('X-Cache-Status');
if (cacheStatus !== 'MISS') {
throw new Error(`Expected cache MISS for different params, got: ${cacheStatus}`);
}
log.detail('Cache status', cacheStatus);
log.detail('Aspect ratio', '1:1');
await saveImage(result.data, 'live-different-aspect.png');
});
// Test 4: With reference image
await runTest('Live generation - with reference', async () => {
const params = new URLSearchParams({
prompt: 'Product photo featuring @brand-logo',
aspectRatio: '16:9',
reference: '@brand-logo',
});
const result = await api(`${endpoints.live}?${params}`, {
timeout: 60000,
});
const cacheStatus = result.headers.get('X-Cache-Status');
log.detail('Cache status', cacheStatus);
log.detail('With reference', '@brand-logo');
await saveImage(result.data, 'live-with-reference.png');
});
// Test 5: Multiple references
await runTest('Live generation - multiple references', async () => {
const params = new URLSearchParams({
prompt: 'Combine @brand-logo and @generated-logo',
aspectRatio: '1:1',
});
params.append('reference', '@brand-logo');
params.append('reference', '@generated-logo');
const result = await api(`${endpoints.live}?${params}`, {
timeout: 60000,
});
const cacheStatus = result.headers.get('X-Cache-Status');
log.detail('Cache status', cacheStatus);
log.detail('References', '[@brand-logo, @generated-logo]');
await saveImage(result.data, 'live-multiple-refs.png');
});
// Test 6: Custom dimensions
await runTest('Live generation - custom dimensions', async () => {
const params = new URLSearchParams({
prompt: 'A landscape painting',
width: '1024',
height: '768',
});
const result = await api(`${endpoints.live}?${params}`, {
timeout: 60000,
});
const cacheStatus = result.headers.get('X-Cache-Status');
log.detail('Cache status', cacheStatus);
log.detail('Dimensions', '1024x768');
await saveImage(result.data, 'live-custom-dims.png');
});
// Test 7: Verify cache works as URL
await runTest('Live as direct URL (browser-like)', async () => {
const url = `${endpoints.live}?prompt=${encodeURIComponent('A beautiful sunset')}&aspectRatio=16:9`;
log.info('Testing URL format:');
log.detail('URL', url);
const result = await api(url, { timeout: 60000 });
if (!(result.data instanceof ArrayBuffer)) {
throw new Error('Should return image directly');
}
const cacheStatus = result.headers.get('X-Cache-Status');
log.detail('Cache status', cacheStatus);
log.detail('Works as direct URL', '✓');
await saveImage(result.data, 'live-direct-url.png');
});
// Test 8: Verify Cache-Control header for CDN
await runTest('Check Cache-Control headers', async () => {
const params = new URLSearchParams({
prompt: 'Test cache control',
aspectRatio: '1:1',
});
const result = await api(`${endpoints.live}?${params}`, {
timeout: 60000,
});
const cacheControl = result.headers.get('Cache-Control');
const contentType = result.headers.get('Content-Type');
log.detail('Cache-Control', cacheControl || 'NOT SET');
log.detail('Content-Type', contentType || 'NOT SET');
if (!cacheControl || !cacheControl.includes('public')) {
log.warning('Cache-Control should be set for CDN optimization');
}
});
// Test 9: Rapid repeated calls (verify cache performance)
await runTest('Cache performance test', async () => {
const params = new URLSearchParams({
prompt: 'Performance test image',
aspectRatio: '1:1',
});
// First call (MISS)
log.info('Making first call (MISS)...');
const firstCall = await api(`${endpoints.live}?${params}`, {
timeout: 60000,
});
const firstDuration = firstCall.duration;
await wait(1000);
// Rapid subsequent calls (all HITs)
log.info('Making 5 rapid cache HIT calls...');
const durations: number[] = [];
for (let i = 0; i < 5; i++) {
const result = await api(`${endpoints.live}?${params}`);
durations.push(result.duration);
const cacheStatus = result.headers.get('X-Cache-Status');
if (cacheStatus !== 'HIT') {
throw new Error(`Call ${i + 1} expected HIT, got ${cacheStatus}`);
}
}
const avgHitDuration = durations.reduce((a, b) => a + b, 0) / durations.length;
log.detail('First call (MISS)', `${firstDuration}ms`);
log.detail('Avg HIT calls', `${avgHitDuration.toFixed(0)}ms`);
log.detail('Speedup', `${(firstDuration / avgHitDuration).toFixed(1)}x faster`);
});
log.section('LIVE ENDPOINT TESTS COMPLETED');
}
main().catch(console.error);