257 lines
8.6 KiB
TypeScript
257 lines
8.6 KiB
TypeScript
// tests/api/03-aliases.ts
|
|
|
|
import { join } from 'path';
|
|
import { api, log, runTest, saveImage, uploadFile, waitForGeneration, testContext } from './utils';
|
|
import { config, endpoints } from './config';
|
|
|
|
async function main() {
|
|
log.section('ALIAS TESTS');
|
|
|
|
// Test 1: Upload with project-scoped alias
|
|
await runTest('Upload with project alias', async () => {
|
|
const fixturePath = join(__dirname, config.fixturesDir, 'test-image.png');
|
|
|
|
const response = await uploadFile(fixturePath, {
|
|
alias: '@brand-logo',
|
|
description: 'Brand logo for project-wide use',
|
|
});
|
|
|
|
if (!response.image.alias || response.image.alias !== '@brand-logo') {
|
|
throw new Error('Alias not set correctly');
|
|
}
|
|
|
|
log.detail('Image ID', response.image.id);
|
|
log.detail('Project alias', response.image.alias);
|
|
log.detail('Flow ID', response.image.flowId || 'null (project-scoped)');
|
|
});
|
|
|
|
// Test 2: Upload with flow-scoped alias
|
|
await runTest('Upload with flow alias', async () => {
|
|
const fixturePath = join(__dirname, config.fixturesDir, 'test-image.png');
|
|
|
|
const response = await uploadFile(fixturePath, {
|
|
flowAlias: '@temp-logo',
|
|
flowId: testContext.flowId,
|
|
description: 'Temporary logo for flow use',
|
|
});
|
|
|
|
if (!response.flow || !response.flow.aliases['@temp-logo']) {
|
|
throw new Error('Flow alias not set');
|
|
}
|
|
|
|
log.detail('Image ID', response.image.id);
|
|
log.detail('Flow ID', response.image.flowId);
|
|
log.detail('Flow aliases', JSON.stringify(response.flow.aliases));
|
|
});
|
|
|
|
// Test 3: Upload with BOTH project and flow aliases
|
|
await runTest('Upload with dual aliases', async () => {
|
|
const fixturePath = join(__dirname, config.fixturesDir, 'test-image.png');
|
|
|
|
const response = await uploadFile(fixturePath, {
|
|
alias: '@global-asset',
|
|
flowAlias: '@flow-asset',
|
|
flowId: testContext.flowId,
|
|
description: 'Image with both alias types',
|
|
});
|
|
|
|
if (!response.image.alias || response.image.alias !== '@global-asset') {
|
|
throw new Error('Project alias not set');
|
|
}
|
|
|
|
if (!response.flow || !response.flow.aliases['@flow-asset']) {
|
|
throw new Error('Flow alias not set');
|
|
}
|
|
|
|
log.detail('Image ID', response.image.id);
|
|
log.detail('Project alias', response.image.alias);
|
|
log.detail('Flow alias', '@flow-asset');
|
|
});
|
|
|
|
// Test 4: Resolve project-scoped alias
|
|
await runTest('Resolve project alias', async () => {
|
|
const result = await api(`${endpoints.images}/resolve/@brand-logo`);
|
|
|
|
if (!result.data.image) {
|
|
throw new Error('Image not resolved');
|
|
}
|
|
|
|
if (result.data.scope !== 'project') {
|
|
throw new Error(`Wrong scope: ${result.data.scope}`);
|
|
}
|
|
|
|
log.detail('Image ID', result.data.image.id);
|
|
log.detail('Scope', result.data.scope);
|
|
log.detail('Alias', result.data.image.alias);
|
|
});
|
|
|
|
// Test 5: Resolve flow-scoped alias
|
|
await runTest('Resolve flow alias', async () => {
|
|
const result = await api(`${endpoints.images}/resolve/@temp-logo?flowId=${testContext.flowId}`);
|
|
|
|
if (!result.data.image) {
|
|
throw new Error('Image not resolved');
|
|
}
|
|
|
|
if (result.data.scope !== 'flow') {
|
|
throw new Error(`Wrong scope: ${result.data.scope}`);
|
|
}
|
|
|
|
log.detail('Image ID', result.data.image.id);
|
|
log.detail('Scope', result.data.scope);
|
|
log.detail('Flow ID', result.data.flow?.id);
|
|
});
|
|
|
|
// Test 6: Resolve @last technical alias
|
|
await runTest('Resolve @last technical alias', async () => {
|
|
const result = await api(`${endpoints.images}/resolve/@last?flowId=${testContext.flowId}`);
|
|
|
|
if (!result.data.image) {
|
|
throw new Error('Image not resolved');
|
|
}
|
|
|
|
if (result.data.scope !== 'technical') {
|
|
throw new Error(`Wrong scope: ${result.data.scope}`);
|
|
}
|
|
|
|
log.detail('Image ID', result.data.image.id);
|
|
log.detail('Scope', result.data.scope);
|
|
log.detail('Technical alias', '@last');
|
|
});
|
|
|
|
// Test 7: Resolve @first technical alias
|
|
await runTest('Resolve @first technical alias', async () => {
|
|
const result = await api(`${endpoints.images}/resolve/@first?flowId=${testContext.flowId}`);
|
|
|
|
if (!result.data.image) {
|
|
throw new Error('Image not resolved');
|
|
}
|
|
|
|
if (result.data.scope !== 'technical') {
|
|
throw new Error(`Wrong scope: ${result.data.scope}`);
|
|
}
|
|
|
|
log.detail('Image ID', result.data.image.id);
|
|
log.detail('Scope', result.data.scope);
|
|
});
|
|
|
|
// Test 8: Resolve @upload technical alias
|
|
await runTest('Resolve @upload technical alias', async () => {
|
|
const result = await api(`${endpoints.images}/resolve/@upload?flowId=${testContext.flowId}`);
|
|
|
|
if (!result.data.image) {
|
|
throw new Error('Image not resolved');
|
|
}
|
|
|
|
if (result.data.scope !== 'technical') {
|
|
throw new Error(`Wrong scope: ${result.data.scope}`);
|
|
}
|
|
|
|
log.detail('Image ID', result.data.image.id);
|
|
log.detail('Scope', result.data.scope);
|
|
log.detail('Source', result.data.image.source);
|
|
});
|
|
|
|
// Test 9: Generate with assignAlias (project-scoped)
|
|
await runTest('Generate with project alias assignment', 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',
|
|
assignAlias: '@generated-logo',
|
|
}),
|
|
});
|
|
|
|
log.info('Waiting for generation to complete...');
|
|
const generation = await waitForGeneration(result.data.generation.id);
|
|
|
|
if (generation.status !== 'success') {
|
|
throw new Error(`Generation failed: ${generation.errorMessage}`);
|
|
}
|
|
|
|
// Check if alias was assigned
|
|
const imageResult = await api(`${endpoints.images}/${generation.outputImageId}`);
|
|
|
|
if (imageResult.data.image.alias !== '@generated-logo') {
|
|
throw new Error('Alias not assigned to generated image');
|
|
}
|
|
|
|
log.detail('Output image', generation.outputImageId);
|
|
log.detail('Assigned alias', imageResult.data.image.alias);
|
|
|
|
// Save image
|
|
const imageUrl = imageResult.data.image.storageUrl;
|
|
const imageResponse = await fetch(imageUrl);
|
|
const imageBuffer = await imageResponse.arrayBuffer();
|
|
await saveImage(imageBuffer, 'generated-with-alias.png');
|
|
});
|
|
|
|
// Test 10: Generate with assignFlowAlias (flow-scoped)
|
|
await runTest('Generate with flow alias assignment', async () => {
|
|
const result = await api(endpoints.generations, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
prompt: 'A vibrant abstract pattern',
|
|
aspectRatio: '1:1',
|
|
flowId: testContext.flowId,
|
|
assignFlowAlias: '@pattern',
|
|
}),
|
|
});
|
|
|
|
log.info('Waiting for generation to complete...');
|
|
const generation = await waitForGeneration(result.data.generation.id);
|
|
|
|
if (generation.status !== 'success') {
|
|
throw new Error(`Generation failed: ${generation.errorMessage}`);
|
|
}
|
|
|
|
// Check if flow alias was assigned
|
|
const flowResult = await api(`${endpoints.flows}/${testContext.flowId}`);
|
|
|
|
if (!flowResult.data.flow.aliases['@pattern']) {
|
|
throw new Error('Flow alias not assigned');
|
|
}
|
|
|
|
log.detail('Output image', generation.outputImageId);
|
|
log.detail('Flow alias assigned', '@pattern');
|
|
});
|
|
|
|
// Test 11: Alias precedence (flow > project)
|
|
await runTest('Test alias precedence', async () => {
|
|
// Create project alias @test
|
|
const fixturePath = join(__dirname, config.fixturesDir, 'test-image.png');
|
|
const projectResponse = await uploadFile(fixturePath, {
|
|
alias: '@precedence-test',
|
|
});
|
|
const projectImageId = projectResponse.image.id;
|
|
|
|
// Create flow alias @test (different image)
|
|
const flowResponse = await uploadFile(fixturePath, {
|
|
flowAlias: '@precedence-test',
|
|
flowId: testContext.flowId,
|
|
});
|
|
const flowImageId = flowResponse.image.id;
|
|
|
|
// Resolve without flowId (should get project alias)
|
|
const withoutFlow = await api(`${endpoints.images}/resolve/@precedence-test`);
|
|
if (withoutFlow.data.image.id !== projectImageId) {
|
|
throw new Error('Should resolve to project alias');
|
|
}
|
|
log.detail('Without flow context', 'resolved to project alias ✓');
|
|
|
|
// Resolve with flowId (should get flow alias)
|
|
const withFlow = await api(`${endpoints.images}/resolve/@precedence-test?flowId=${testContext.flowId}`);
|
|
if (withFlow.data.image.id !== flowImageId) {
|
|
throw new Error('Should resolve to flow alias');
|
|
}
|
|
log.detail('With flow context', 'resolved to flow alias ✓');
|
|
});
|
|
|
|
log.section('ALIAS TESTS COMPLETED');
|
|
}
|
|
|
|
main().catch(console.error);
|