banatie-service/tests/api/04-aliases.rest

591 lines
15 KiB
ReStructuredText

@base = http://localhost:3000
@apiKey = bnt_727d2f4f72bd03ed96da5278bb971a00cb0a2454d4d70f9748b5c39f3f69d88d
###############################################################################
# ALIAS RESOLUTION TESTS
# Tests: 3-Tier Alias Resolution (Technical -> Flow -> Project)
#
# Test Coverage:
# 1. Technical alias @last
# 2. Technical alias @first
# 3. Technical alias @upload
# 4. Technical alias requires flowId
# 5. Flow-scoped alias resolution
# 6. Project-scoped alias resolution
# 7. Alias precedence (flow > project)
# 8. Reserved aliases cannot be assigned
# 9. Alias reassignment removes old
# 10. Same alias in different flows
# 11. Technical alias in generation prompt
# 12. Upload with both project and flow alias
###############################################################################
###############################################################################
# SETUP: Create Test Flow
###############################################################################
### Setup: Create flow for alias tests
# @name setupGen
POST {{base}}/api/v1/generations
Content-Type: application/json
X-API-Key: {{apiKey}}
{
"prompt": "Setup image for alias tests",
"aspectRatio": "1:1",
"flowAlias": "@alias-test-flow"
}
###
@aliasFlowId = {{setupGen.response.body.$.data.flowId}}
@setupGenId = {{setupGen.response.body.$.data.id}}
### Poll setup generation
# @name checkSetupGen
GET {{base}}/api/v1/generations/{{setupGenId}}
X-API-Key: {{apiKey}}
###
@setupImageId = {{checkSetupGen.response.body.$.data.outputImageId}}
###############################################################################
# TEST 1: Technical Alias @last
# Resolves to last generated image in flow
###############################################################################
### Step 1.1: Resolve @last (requires flowId)
# @name resolveLast
GET {{base}}/api/v1/images/@last?flowId={{aliasFlowId}}
X-API-Key: {{apiKey}}
###
# Verify:
# - Returns image (status 200)
# - Returns the most recently generated image in the flow
###############################################################################
# TEST 2: Technical Alias @first
# Resolves to first generated image in flow
###############################################################################
### Step 2.1: Resolve @first (requires flowId)
# @name resolveFirst
GET {{base}}/api/v1/images/@first?flowId={{aliasFlowId}}
X-API-Key: {{apiKey}}
###
# Verify:
# - Returns image (status 200)
# - Returns the first generated image in the flow
###############################################################################
# TEST 3: Technical Alias @upload
# Resolves to last uploaded image in flow
###############################################################################
### Step 3.1: Upload image to flow
# @name uploadForTest
POST {{base}}/api/v1/images/upload
X-API-Key: {{apiKey}}
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="test-image.png"
Content-Type: image/png
< ./fixture/test-image.png
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="flowId"
{{aliasFlowId}}
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="description"
Uploaded for @upload test
------WebKitFormBoundary7MA4YWxkTrZu0gW--
###
@uploadedImageId = {{uploadForTest.response.body.$.data.id}}
### Step 3.2: Resolve @upload (requires flowId)
# @name resolveUpload
GET {{base}}/api/v1/images/@upload?flowId={{aliasFlowId}}
X-API-Key: {{apiKey}}
###
# Verify:
# - Returns image (status 200)
# - Returns uploaded image (source = "uploaded")
###############################################################################
# TEST 4: Technical Alias Requires Flow Context
# @last, @first, @upload require flowId parameter
###############################################################################
### Step 4.1: Try @last without flowId (should fail)
# @name resolveLastNoFlow
GET {{base}}/api/v1/images/@last
X-API-Key: {{apiKey}}
###
# Expected: 404 with error "Technical aliases require flowId"
###############################################################################
# TEST 5: Flow-Scoped Alias Resolution
###############################################################################
### Step 5.1: Create generation with flow alias
# @name flowAliasGen
POST {{base}}/api/v1/generations
Content-Type: application/json
X-API-Key: {{apiKey}}
{
"prompt": "Image for flow alias test",
"aspectRatio": "1:1",
"flowId": "{{aliasFlowId}}",
"flowAlias": "@flow-hero"
}
###
@flowAliasGenId = {{flowAliasGen.response.body.$.data.id}}
### Step 5.2: Poll generation
# @name checkFlowAliasGen
GET {{base}}/api/v1/generations/{{flowAliasGenId}}
X-API-Key: {{apiKey}}
###
@flowHeroImageId = {{checkFlowAliasGen.response.body.$.data.outputImageId}}
### Step 5.3: Resolve flow alias
# @name resolveFlowAlias
GET {{base}}/api/v1/images/@flow-hero?flowId={{aliasFlowId}}
X-API-Key: {{apiKey}}
###
# Verify:
# - Returns the image from step 5.1
# - Only works with flowId parameter
###############################################################################
# TEST 6: Project-Scoped Alias Resolution
###############################################################################
### Step 6.1: Create generation with project alias
# @name projectAliasGen
POST {{base}}/api/v1/generations
Content-Type: application/json
X-API-Key: {{apiKey}}
{
"prompt": "Image for project alias test",
"aspectRatio": "1:1",
"alias": "@project-logo",
"flowId": null
}
###
@projectAliasGenId = {{projectAliasGen.response.body.$.data.id}}
### Step 6.2: Poll generation
# @name checkProjectAliasGen
GET {{base}}/api/v1/generations/{{projectAliasGenId}}
X-API-Key: {{apiKey}}
###
@projectLogoImageId = {{checkProjectAliasGen.response.body.$.data.outputImageId}}
### Step 6.3: Resolve project alias (no flowId needed)
# @name resolveProjectAlias
GET {{base}}/api/v1/images/@project-logo
X-API-Key: {{apiKey}}
###
# Verify:
# - Returns the image from step 6.1
# - Works without flowId parameter
###############################################################################
# TEST 7: Alias Precedence (Flow > Project)
###############################################################################
### Step 7.1: Create project-scoped alias @priority-test
# @name priorityProject
POST {{base}}/api/v1/generations
Content-Type: application/json
X-API-Key: {{apiKey}}
{
"prompt": "Project scoped image for priority test",
"aspectRatio": "1:1",
"alias": "@priority-test",
"flowId": null
}
###
@priorityProjectGenId = {{priorityProject.response.body.$.data.id}}
### Step 7.2: Poll generation
# @name checkPriorityProject
GET {{base}}/api/v1/generations/{{priorityProjectGenId}}
X-API-Key: {{apiKey}}
###
@priorityProjectImageId = {{checkPriorityProject.response.body.$.data.outputImageId}}
### Step 7.3: Create flow-scoped alias @priority-test (same name)
# @name priorityFlow
POST {{base}}/api/v1/generations
Content-Type: application/json
X-API-Key: {{apiKey}}
{
"prompt": "Flow scoped image for priority test",
"aspectRatio": "1:1",
"flowId": "{{aliasFlowId}}",
"flowAlias": "@priority-test"
}
###
@priorityFlowGenId = {{priorityFlow.response.body.$.data.id}}
### Step 7.4: Poll generation
# @name checkPriorityFlow
GET {{base}}/api/v1/generations/{{priorityFlowGenId}}
X-API-Key: {{apiKey}}
###
@priorityFlowImageId = {{checkPriorityFlow.response.body.$.data.outputImageId}}
### Step 7.5: Resolve WITHOUT flowId (should get project)
# @name resolvePriorityNoFlow
GET {{base}}/api/v1/images/@priority-test
X-API-Key: {{apiKey}}
###
# Verify: Returns project image ({{priorityProjectImageId}})
### Step 7.6: Resolve WITH flowId (should get flow)
# @name resolvePriorityWithFlow
GET {{base}}/api/v1/images/@priority-test?flowId={{aliasFlowId}}
X-API-Key: {{apiKey}}
###
# Verify: Returns flow image ({{priorityFlowImageId}})
###############################################################################
# TEST 8: Reserved Aliases Cannot Be Assigned
###############################################################################
### Step 8.1: Try to use @last as alias (should fail or warn)
# @name reservedLast
POST {{base}}/api/v1/generations
Content-Type: application/json
X-API-Key: {{apiKey}}
{
"prompt": "Test reserved alias",
"aspectRatio": "1:1",
"alias": "@last"
}
###
# Expected: 400 validation error OR generation succeeds but @last not assigned
### Step 8.2: Try to use @first as alias
# @name reservedFirst
POST {{base}}/api/v1/generations
Content-Type: application/json
X-API-Key: {{apiKey}}
{
"prompt": "Test reserved alias",
"aspectRatio": "1:1",
"alias": "@first"
}
###
### Step 8.3: Try to use @upload as alias
# @name reservedUpload
POST {{base}}/api/v1/generations
Content-Type: application/json
X-API-Key: {{apiKey}}
{
"prompt": "Test reserved alias",
"aspectRatio": "1:1",
"alias": "@upload"
}
###
###############################################################################
# TEST 9: Alias Reassignment (Override Behavior)
###############################################################################
### Step 9.1: Create first image with alias
# @name reassign1
POST {{base}}/api/v1/generations
Content-Type: application/json
X-API-Key: {{apiKey}}
{
"prompt": "First image for reassign test",
"aspectRatio": "1:1",
"alias": "@reassign-test",
"flowId": null
}
###
@reassign1GenId = {{reassign1.response.body.$.data.id}}
### Step 9.2: Poll first generation
# @name checkReassign1
GET {{base}}/api/v1/generations/{{reassign1GenId}}
X-API-Key: {{apiKey}}
###
@reassign1ImageId = {{checkReassign1.response.body.$.data.outputImageId}}
### Step 9.3: Create second image with SAME alias
# @name reassign2
POST {{base}}/api/v1/generations
Content-Type: application/json
X-API-Key: {{apiKey}}
{
"prompt": "Second image for reassign test",
"aspectRatio": "1:1",
"alias": "@reassign-test",
"flowId": null
}
###
@reassign2GenId = {{reassign2.response.body.$.data.id}}
### Step 9.4: Poll second generation
# @name checkReassign2
GET {{base}}/api/v1/generations/{{reassign2GenId}}
X-API-Key: {{apiKey}}
###
@reassign2ImageId = {{checkReassign2.response.body.$.data.outputImageId}}
### Step 9.5: Resolve alias (should be second image)
# @name resolveReassign
GET {{base}}/api/v1/images/@reassign-test
X-API-Key: {{apiKey}}
###
# Verify: Returns second image ({{reassign2ImageId}})
### Step 9.6: Check first image lost alias
# @name checkFirstLostAlias
GET {{base}}/api/v1/images/{{reassign1ImageId}}
X-API-Key: {{apiKey}}
###
# Verify: alias = null
###############################################################################
# TEST 10: Same Alias in Different Flows
###############################################################################
### Step 10.1: Create flow 1 with @shared-name alias
# @name sharedFlow1
POST {{base}}/api/v1/generations
Content-Type: application/json
X-API-Key: {{apiKey}}
{
"prompt": "Flow 1 image with shared name",
"aspectRatio": "1:1",
"flowAlias": "@shared-name"
}
###
@sharedFlow1Id = {{sharedFlow1.response.body.$.data.flowId}}
@sharedGen1Id = {{sharedFlow1.response.body.$.data.id}}
### Step 10.2: Poll generation 1
# @name checkSharedGen1
GET {{base}}/api/v1/generations/{{sharedGen1Id}}
X-API-Key: {{apiKey}}
###
@sharedImage1Id = {{checkSharedGen1.response.body.$.data.outputImageId}}
### Step 10.3: Create flow 2 with SAME @shared-name alias
# @name sharedFlow2
POST {{base}}/api/v1/generations
Content-Type: application/json
X-API-Key: {{apiKey}}
{
"prompt": "Flow 2 image with shared name",
"aspectRatio": "1:1",
"flowAlias": "@shared-name"
}
###
@sharedFlow2Id = {{sharedFlow2.response.body.$.data.flowId}}
@sharedGen2Id = {{sharedFlow2.response.body.$.data.id}}
### Step 10.4: Poll generation 2
# @name checkSharedGen2
GET {{base}}/api/v1/generations/{{sharedGen2Id}}
X-API-Key: {{apiKey}}
###
@sharedImage2Id = {{checkSharedGen2.response.body.$.data.outputImageId}}
### Step 10.5: Resolve @shared-name in flow 1
# @name resolveSharedFlow1
GET {{base}}/api/v1/images/@shared-name?flowId={{sharedFlow1Id}}
X-API-Key: {{apiKey}}
###
# Verify: Returns {{sharedImage1Id}}
### Step 10.6: Resolve @shared-name in flow 2
# @name resolveSharedFlow2
GET {{base}}/api/v1/images/@shared-name?flowId={{sharedFlow2Id}}
X-API-Key: {{apiKey}}
###
# Verify: Returns {{sharedImage2Id}} (different from flow 1)
###############################################################################
# TEST 11: Technical Alias in Generation Prompt
###############################################################################
### Step 11.1: Generate using @last in prompt
# @name techAliasPrompt
POST {{base}}/api/v1/generations
Content-Type: application/json
X-API-Key: {{apiKey}}
{
"prompt": "New variation based on @last",
"aspectRatio": "1:1",
"flowId": "{{aliasFlowId}}"
}
###
@techAliasGenId = {{techAliasPrompt.response.body.$.data.id}}
### Step 11.2: Poll generation
# @name checkTechAliasGen
GET {{base}}/api/v1/generations/{{techAliasGenId}}
X-API-Key: {{apiKey}}
###
# Verify:
# - status = "success"
# - referencedImages contains @last alias
###############################################################################
# TEST 12: Upload with Both Project and Flow Alias
###############################################################################
### Step 12.1: Upload with both aliases
# @name dualAliasUpload
POST {{base}}/api/v1/images/upload
X-API-Key: {{apiKey}}
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="test-image.png"
Content-Type: image/png
< ./fixture/test-image.png
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="alias"
@dual-project
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="flowId"
{{aliasFlowId}}
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="flowAlias"
@dual-flow
------WebKitFormBoundary7MA4YWxkTrZu0gW--
###
@dualAliasImageId = {{dualAliasUpload.response.body.$.data.id}}
### Step 12.2: Resolve project alias
# @name resolveDualProject
GET {{base}}/api/v1/images/@dual-project
X-API-Key: {{apiKey}}
###
# Verify: Returns {{dualAliasImageId}}
### Step 12.3: Resolve flow alias
# @name resolveDualFlow
GET {{base}}/api/v1/images/@dual-flow?flowId={{aliasFlowId}}
X-API-Key: {{apiKey}}
###
# Verify: Returns {{dualAliasImageId}} (same image)
###############################################################################
# NOTES
###############################################################################
#
# 3-Tier Alias Resolution Order:
# 1. Technical (@last, @first, @upload) - require flowId
# 2. Flow-scoped (stored in flow.aliases) - require flowId
# 3. Project-scoped (stored in images.alias) - no flowId needed
#
# Alias Format:
# - Must start with @
# - Alphanumeric + hyphens only
# - Reserved: @last, @first, @upload
#
# Override Behavior (Section 5.2):
# - New alias assignment takes priority
# - Previous image loses its alias
# - Previous image is NOT deleted
#