Compare commits

...

2 Commits

Author SHA1 Message Date
Matt Miller
a6507ff961 test: update cloud export e2e assertions for flat naming strategy
The bulk download-as-zip now always uses the 'flat' naming strategy;
update the cloud e2e export tests to match the source and unit-test change.
2026-07-14 14:27:33 -07:00
Matt Miller
2d097913e6 fix: use flat naming strategy for bulk download-as-zip
Bulk "download as zip" previously chose group_by_job_time (multi-job) or
preserve (single-job), both of which nest files in subfolders. Always
request the flat strategy so the archive extracts to a single level.
Per-job asset name filtering is unchanged.
2026-07-14 13:35:47 -07:00
4 changed files with 16 additions and 20 deletions

View File

@@ -731,7 +731,7 @@ test.describe('Assets sidebar - bulk actions', () => {
cloudTest.describe('Assets sidebar - cloud exports', { tag: '@cloud' }, () => {
cloudTest(
'Single job selection uses preserve naming strategy',
'Single job selection uses flat naming strategy',
async ({ comfyPage, mockCloudAssetSidebarData }) => {
void mockCloudAssetSidebarData
const exportRequests = await comfyPage.assets.captureAssetExportRequests()
@@ -749,12 +749,12 @@ cloudTest.describe('Assets sidebar - cloud exports', { tag: '@cloud' }, () => {
const payload = exportRequests[0]
expect(payload.job_ids).toEqual(['job-gamma'])
expect(payload.job_asset_name_filters).toBeUndefined()
expect(payload.naming_strategy).toBe('preserve')
expect(payload.naming_strategy).toBe('flat')
}
)
cloudTest(
'Multiple selected assets from one job use preserve naming strategy',
'Multiple selected assets from one job keep name filters with flat naming strategy',
async ({ comfyPage, mockCloudAssetSidebarData }) => {
void mockCloudAssetSidebarData
const exportRequests = await comfyPage.assets.captureAssetExportRequests()
@@ -785,12 +785,12 @@ cloudTest.describe('Assets sidebar - cloud exports', { tag: '@cloud' }, () => {
expect(payload.job_asset_name_filters?.['job-gamma']?.toSorted()).toEqual(
['abstract_art.png', 'abstract_art_alt.png']
)
expect(payload.naming_strategy).toBe('preserve')
expect(payload.naming_strategy).toBe('flat')
}
)
cloudTest(
'Multiple selected jobs use job-time naming strategy',
'Multiple selected jobs use flat naming strategy',
async ({ comfyPage, mockCloudAssetSidebarData }) => {
void mockCloudAssetSidebarData
const exportRequests = await comfyPage.assets.captureAssetExportRequests()
@@ -811,7 +811,7 @@ cloudTest.describe('Assets sidebar - cloud exports', { tag: '@cloud' }, () => {
const payload = exportRequests[0]
expect(payload.job_ids?.toSorted()).toEqual(['job-alpha', 'job-beta'])
expect(payload.job_asset_name_filters).toBeUndefined()
expect(payload.naming_strategy).toBe('group_by_job_time')
expect(payload.naming_strategy).toBe('flat')
}
)
})

View File

@@ -587,7 +587,7 @@ describe('useMediaAssetActions', () => {
expect(mockDownloadFile).not.toHaveBeenCalled()
expect(mockCreateAssetExport).toHaveBeenCalledWith({
job_ids: ['job1'],
naming_strategy: 'preserve',
naming_strategy: 'flat',
include_previews: true
})
expect(mockTrackExport).toHaveBeenCalledWith('test-task-id')
@@ -852,7 +852,7 @@ describe('useMediaAssetActions', () => {
})
}
it('should use preserve strategy when selection spans a single job', async () => {
it('should use flat strategy with no name filters for a single job-level selection', async () => {
const assets = [createOutputAsset('a1', 'img1.png', 'job1', 3)]
const actions = useMediaAssetActions()
@@ -865,7 +865,7 @@ describe('useMediaAssetActions', () => {
const payload = mockCreateAssetExport.mock.calls[0][0]
expect(payload.job_ids).toEqual(['job1'])
expect(payload.job_asset_name_filters).toBeUndefined()
expect(payload.naming_strategy).toBe('preserve')
expect(payload.naming_strategy).toBe('flat')
})
it('should omit name filters for multiple job-level selections', async () => {
@@ -883,7 +883,7 @@ describe('useMediaAssetActions', () => {
const payload = mockCreateAssetExport.mock.calls[0][0]
expect(payload.job_ids).toEqual(['job1', 'job2'])
expect(payload.job_asset_name_filters).toBeUndefined()
expect(payload.naming_strategy).toBe('group_by_job_time')
expect(payload.naming_strategy).toBe('flat')
})
it('should include name filters when outputCount is unknown', async () => {
@@ -902,7 +902,7 @@ describe('useMediaAssetActions', () => {
job1: ['img1.png'],
job2: ['img2.png']
})
expect(payload.naming_strategy).toBe('group_by_job_time')
expect(payload.naming_strategy).toBe('flat')
})
it('should mix: omit filters for known outputCount, keep for unknown', async () => {
@@ -922,10 +922,10 @@ describe('useMediaAssetActions', () => {
expect(payload.job_asset_name_filters).toEqual({
job2: ['img2.png']
})
expect(payload.naming_strategy).toBe('group_by_job_time')
expect(payload.naming_strategy).toBe('flat')
})
it('should preserve multiple selected outputs from one job', async () => {
it('should keep name filters for multiple selected outputs from one job', async () => {
const asset1 = createOutputAsset('a1', 'img1.png', 'job1')
const asset2 = createOutputAsset('a2', 'img2.png', 'job1')
@@ -941,7 +941,7 @@ describe('useMediaAssetActions', () => {
expect(payload.job_asset_name_filters).toEqual({
job1: ['img1.png', 'img2.png']
})
expect(payload.naming_strategy).toBe('preserve')
expect(payload.naming_strategy).toBe('flat')
})
})

View File

@@ -257,18 +257,13 @@ export function useMediaAssetActions() {
}
}
const spansMultipleJobs = jobIds.length > 1
const namingStrategy = spansMultipleJobs
? 'group_by_job_time'
: 'preserve'
const result = await assetService.createAssetExport({
...(jobIds.length > 0 ? { job_ids: jobIds } : {}),
...(assetIds.length > 0 ? { asset_ids: assetIds } : {}),
...(Object.keys(jobAssetNameFilters).length > 0
? { job_asset_name_filters: jobAssetNameFilters }
: {}),
naming_strategy: namingStrategy,
naming_strategy: 'flat',
include_previews: true
})

View File

@@ -55,6 +55,7 @@ interface AssetExportOptions {
| 'group_by_job_time'
| 'preserve'
| 'asset_id'
| 'flat'
job_asset_name_filters?: Record<string, string[]>
include_previews?: boolean
}