fix: get asset by id for stacks (#15522)

This commit is contained in:
Jason Rasmussen 2025-01-22 13:13:09 -05:00 committed by GitHub
parent c8abe9a2fd
commit 8d6cbb51e2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 61 additions and 81 deletions

View File

@ -119,93 +119,57 @@ describe('/stacks', () => {
const stacksAfter = await searchStacks({}, { headers: asBearerAuth(user1.accessToken) }); const stacksAfter = await searchStacks({}, { headers: asBearerAuth(user1.accessToken) });
expect(stacksAfter.length).toBe(stacksBefore.length); expect(stacksAfter.length).toBe(stacksBefore.length);
}); });
// it('should require a valid parent id', async () => {
// const { status, body } = await request(app)
// .put('/assets')
// .set('Authorization', `Bearer ${user1.accessToken}`)
// .send({ stackParentId: uuidDto.invalid, ids: [stackAssets[0].id] });
// expect(status).toBe(400);
// expect(body).toEqual(errorDto.badRequest(['stackParentId must be a UUID']));
// });
}); });
// it('should require access to the parent', async () => { describe('GET /assets/:id', () => {
// const { status, body } = await request(app) it('should include stack details for the primary asset', async () => {
// .put('/assets') const [asset1, asset2] = await Promise.all([
// .set('Authorization', `Bearer ${user1.accessToken}`) utils.createAsset(user1.accessToken),
// .send({ stackParentId: stackAssets[3].id, ids: [user1Assets[0].id] }); utils.createAsset(user1.accessToken),
]);
// expect(status).toBe(400); await utils.createStack(user1.accessToken, [asset1.id, asset2.id]);
// expect(body).toEqual(errorDto.noPermission);
// });
// it('should add stack children', async () => { const { status, body } = await request(app)
// const { status } = await request(app) .get(`/assets/${asset1.id}`)
// .put('/assets') .set('Authorization', `Bearer ${user1.accessToken}`);
// .set('Authorization', `Bearer ${stackUser.accessToken}`)
// .send({ stackParentId: stackAssets[0].id, ids: [stackAssets[3].id] });
// expect(status).toBe(204); expect(status).toBe(200);
expect(body).toEqual(
// const asset = await getAssetInfo({ id: stackAssets[0].id }, { headers: asBearerAuth(stackUser.accessToken) }); expect.objectContaining({
// expect(asset.stack).not.toBeUndefined(); id: asset1.id,
// expect(asset.stack).toEqual(expect.arrayContaining([expect.objectContaining({ id: stackAssets[3].id })])); stack: {
// }); id: expect.any(String),
assetCount: 2,
// it('should remove stack children', async () => { primaryAssetId: asset1.id,
// const { status } = await request(app) },
// .put('/assets') }),
// .set('Authorization', `Bearer ${stackUser.accessToken}`) );
// .send({ removeParent: true, ids: [stackAssets[1].id] }); });
// expect(status).toBe(204); it('should include stack details for a non-primary asset', async () => {
const [asset1, asset2] = await Promise.all([
// const asset = await getAssetInfo({ id: stackAssets[0].id }, { headers: asBearerAuth(stackUser.accessToken) }); utils.createAsset(user1.accessToken),
// expect(asset.stack).not.toBeUndefined(); utils.createAsset(user1.accessToken),
// expect(asset.stack).toEqual( ]);
// expect.arrayContaining([
// expect.objectContaining({ id: stackAssets[2].id }), await utils.createStack(user1.accessToken, [asset1.id, asset2.id]);
// expect.objectContaining({ id: stackAssets[3].id }),
// ]), const { status, body } = await request(app)
// ); .get(`/assets/${asset2.id}`)
// }); .set('Authorization', `Bearer ${user1.accessToken}`);
// it('should remove all stack children', async () => { expect(status).toBe(200);
// const { status } = await request(app) expect(body).toEqual(
// .put('/assets') expect.objectContaining({
// .set('Authorization', `Bearer ${stackUser.accessToken}`) id: asset2.id,
// .send({ removeParent: true, ids: [stackAssets[2].id, stackAssets[3].id] }); stack: {
id: expect.any(String),
// expect(status).toBe(204); assetCount: 2,
primaryAssetId: asset1.id,
// const asset = await getAssetInfo({ id: stackAssets[0].id }, { headers: asBearerAuth(stackUser.accessToken) }); },
// expect(asset.stack).toBeUndefined(); }),
// }); );
});
// it('should merge stack children', async () => { });
// // create stack after previous test removed stack children
// await updateAssets(
// { assetBulkUpdateDto: { stackParentId: stackAssets[0].id, ids: [stackAssets[1].id, stackAssets[2].id] } },
// { headers: asBearerAuth(stackUser.accessToken) },
// );
// const { status } = await request(app)
// .put('/assets')
// .set('Authorization', `Bearer ${stackUser.accessToken}`)
// .send({ stackParentId: stackAssets[3].id, ids: [stackAssets[0].id] });
// expect(status).toBe(204);
// const asset = await getAssetInfo({ id: stackAssets[3].id }, { headers: asBearerAuth(stackUser.accessToken) });
// expect(asset.stack).not.toBeUndefined();
// expect(asset.stack).toEqual(
// expect.arrayContaining([
// expect.objectContaining({ id: stackAssets[0].id }),
// expect.objectContaining({ id: stackAssets[1].id }),
// expect.objectContaining({ id: stackAssets[2].id }),
// ]),
// );
// });
}); });

View File

@ -284,7 +284,23 @@ export class AssetRepository implements IAssetRepository {
.$if(!!library, (qb) => qb.select(withLibrary)) .$if(!!library, (qb) => qb.select(withLibrary))
.$if(!!owner, (qb) => qb.select(withOwner)) .$if(!!owner, (qb) => qb.select(withOwner))
.$if(!!smartSearch, withSmartSearch) .$if(!!smartSearch, withSmartSearch)
.$if(!!stack, (qb) => withStack(qb, { assets: !!stack!.assets, count: false })) .$if(!!stack, (qb) =>
qb
.leftJoin('asset_stack', 'asset_stack.id', 'assets.stackId')
.leftJoinLateral(
(eb) =>
eb
.selectFrom('assets as stacked')
.selectAll('asset_stack')
.select((eb) => eb.fn('array_agg', [eb.table('stacked')]).as('assets'))
.where('stacked.deletedAt', 'is', null)
.whereRef('stacked.id', '!=', 'asset_stack.primaryAssetId')
.whereRef('stacked.stackId', '=', 'asset_stack.id')
.as('stacked_assets'),
(join) => join.on('asset_stack.id', 'is not', null),
)
.select((eb) => eb.fn.toJson(eb.table('stacked_assets')).as('stack')),
)
.$if(!!files, (qb) => qb.select(withFiles)) .$if(!!files, (qb) => qb.select(withFiles))
.$if(!!tags, (qb) => qb.select(withTags)) .$if(!!tags, (qb) => qb.select(withTags))
.limit(1) .limit(1)