68 lines
4.0 KiB
JavaScript
68 lines
4.0 KiB
JavaScript
import test from 'node:test'
|
|
import assert from 'node:assert/strict'
|
|
import { readFileSync } from 'node:fs'
|
|
import ts from 'typescript'
|
|
|
|
const source = readFileSync(new URL('../utils/libraryBrowse.ts', import.meta.url), 'utf8')
|
|
const js = ts.transpileModule(source, { compilerOptions: { module: ts.ModuleKind.ESNext, target: ts.ScriptTarget.ES2022 } }).outputText
|
|
const { buildLibraryEntries, chronologicalStills } = await import(`data:text/javascript;base64,${Buffer.from(js).toString('base64')}`)
|
|
const image = (id, extra = {}) => ({ id, folderId: 'inbox', filename: `${id}.png`, role: 'output', createdAt: 1, width: 512, height: 512, ...extra })
|
|
const entries = stills => buildLibraryEntries({ stills, clips: [], folderId: 'all', filter: 'images', search: '', sort: 'date-desc' })
|
|
|
|
test('manual grouping joins unrelated images without changing iteration ancestry', () => {
|
|
const a = image('a', { familyId: 'iteration-a', chainIndex: 8, manualGroupId: 'manual', manualGroupName: 'Favorites', manualGroupIndex: 0 })
|
|
const b = image('b', { familyId: 'iteration-b', chainIndex: 0, manualGroupId: 'manual', manualGroupName: 'Favorites', manualGroupIndex: 1 })
|
|
const grouped = entries([b, a])
|
|
assert.equal(grouped.length, 1)
|
|
assert.equal(grouped[0].name, 'Favorites')
|
|
assert.deepEqual(chronologicalStills(grouped[0].stillGroup.parts).map(x => x.id), ['a', 'b'])
|
|
assert.equal(a.familyId, 'iteration-a')
|
|
assert.equal(b.familyId, 'iteration-b')
|
|
assert.equal(entries([a, b].map(({ manualGroupId, manualGroupName, manualGroupIndex, ...rest }) => rest)).length, 2)
|
|
})
|
|
|
|
test('groups remain folder scoped and do not absorb future iterations', () => {
|
|
const a = image('a', { familyId: 'iteration', manualGroupId: 'manual' })
|
|
const b = image('b', { familyId: 'iteration' })
|
|
const c = image('c', { folderId: 'private', manualGroupId: 'manual' })
|
|
assert.equal(entries([a, b, c]).length, 3)
|
|
})
|
|
|
|
const librarySource = readFileSync(new URL('../server/utils/library.ts', import.meta.url), 'utf8')
|
|
const ast = ts.createSourceFile('library.ts', librarySource, ts.ScriptTarget.Latest, true)
|
|
const names = ['stillsInSameFamily', 'groupLibraryStills', 'moveStillFamily', 'renameStillFamily']
|
|
const functions = ast.statements.filter(node => ts.isFunctionDeclaration(node) && names.includes(node.name?.text)).map(node => node.getText(ast).replace(/^export /, '')).join('\n')
|
|
const serverJs = ts.transpileModule(functions, { compilerOptions: { target: ts.ScriptTarget.ES2022 } }).outputText
|
|
function server(catalog) {
|
|
return new Function('mutate', 'stillRole', 'createError', 'familyBaseName', 'stillChainName', `${serverJs}; return { ${names.join(',')} };`)(
|
|
async (_, fn) => fn(catalog), item => item.role, error => Object.assign(new Error(error.statusMessage), error), name => name, (name, index) => `${name} ${index}`)
|
|
}
|
|
|
|
test('group, rename, move and ungroup preserve original generation links and names', async () => {
|
|
const a = image('a', { familyId: 'first', name: 'Original A' })
|
|
const b = image('b', { familyId: 'second', name: 'Original B' })
|
|
const catalog = { stills: [a, b], folders: [{ id: 'inbox' }, { id: 'other' }] }
|
|
const api = server(catalog)
|
|
await api.groupLibraryStills('owner', ['a', 'b'])
|
|
assert.equal(a.manualGroupId, b.manualGroupId)
|
|
await api.renameStillFamily('owner', 'a', 'Favorites')
|
|
await api.moveStillFamily('owner', 'a', 'other')
|
|
assert.equal(b.folderId, 'other')
|
|
assert.equal(b.manualGroupName, 'Favorites')
|
|
assert.equal(a.name, 'Original A')
|
|
assert.equal(b.familyId, 'second')
|
|
await api.groupLibraryStills('owner', ['a'], true)
|
|
assert.equal(a.manualGroupId, undefined)
|
|
assert.equal(b.manualGroupId, undefined)
|
|
assert.equal(a.familyId, 'first')
|
|
})
|
|
|
|
test('invalid grouping is rejected before modifying any images', async () => {
|
|
const a = image('a')
|
|
const b = image('b', { folderId: 'private' })
|
|
const api = server({ stills: [a, b] })
|
|
await assert.rejects(api.groupLibraryStills('owner', ['a', 'b']), /same folder/)
|
|
await assert.rejects(api.groupLibraryStills('owner', ['a', 'missing']), /generated images/)
|
|
assert.equal(a.manualGroupId, undefined)
|
|
})
|