Skip to content

Commit 12bb6b3

Browse files
authored
fix: take into account previousItemId parameter to get correct ordering when creating folder with thumbnail (#2110)
1 parent 91e5a61 commit 12bb6b3

3 files changed

Lines changed: 115 additions & 2 deletions

File tree

src/services/item/item.controller.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ const plugin: FastifyPluginAsyncTypebox = async (fastify) => {
9090
async (request) => {
9191
const {
9292
user,
93-
query: { parentId },
93+
query: { parentId, previousItemId },
9494
} = request;
9595
const member = asDefined(user?.account);
9696
assertIsMember(member);
@@ -109,6 +109,7 @@ const plugin: FastifyPluginAsyncTypebox = async (fastify) => {
109109
parentId,
110110
geolocation,
111111
thumbnail,
112+
previousItemId,
112113
});
113114
await itemActionService.postPostAction(tsx, request, item);
114115
return item;

src/services/item/item.controller.update.test.ts

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,116 @@ describe('Item routes tests', () => {
730730
expect(response.statusCode).toBe(StatusCodes.OK);
731731
expect(uploadDoneMock).toHaveBeenCalled();
732732
});
733+
734+
it('Post item with thumbnail inside parent', async () => {
735+
const {
736+
actor,
737+
items: [parent],
738+
} = await seedFromJson({
739+
items: [{ name: 'parent', memberships: [{ account: 'actor', permission: 'admin' }] }],
740+
});
741+
assertIsDefined(actor);
742+
assertIsMemberForTest(actor);
743+
mockAuthenticate(actor);
744+
const imageStream = fs.createReadStream(path.resolve(__dirname, './test/fixtures/image.png'));
745+
const itemName = 'Test Item';
746+
const payload = new FormData();
747+
payload.append('name', itemName);
748+
payload.append('type', 'folder');
749+
payload.append('description', '');
750+
payload.append('file', imageStream);
751+
const response = await app.inject({
752+
method: HttpMethod.Post,
753+
url: `/api/items/with-thumbnail`,
754+
query: {
755+
parentId: parent.id,
756+
},
757+
payload,
758+
headers: payload.getHeaders(),
759+
});
760+
761+
const newItem = response.json();
762+
expectItem(
763+
newItem,
764+
FolderItemFactory({
765+
parentItem: parent,
766+
name: itemName,
767+
type: 'folder',
768+
description: '',
769+
settings: { hasThumbnail: true },
770+
lang: parent.lang,
771+
}),
772+
actor,
773+
);
774+
expect(response.statusCode).toBe(StatusCodes.OK);
775+
expect(uploadDoneMock).toHaveBeenCalled();
776+
});
777+
778+
it('Post item with thumbnail inside parent after first item', async () => {
779+
const {
780+
actor,
781+
items: [parent, firstChild],
782+
} = await seedFromJson({
783+
items: [
784+
{
785+
name: 'parent',
786+
type: 'folder',
787+
memberships: [{ account: 'actor', permission: 'admin' }],
788+
children: [
789+
{
790+
name: 'first',
791+
// we need to specify the order as it is not set automatically, without this it returns a wrong ordering
792+
order: 20,
793+
},
794+
],
795+
},
796+
],
797+
});
798+
assertIsDefined(actor);
799+
assertIsMemberForTest(actor);
800+
mockAuthenticate(actor);
801+
const imageStream = fs.createReadStream(path.resolve(__dirname, './test/fixtures/image.png'));
802+
const itemName = 'Test Item';
803+
const payload = new FormData();
804+
payload.append('name', itemName);
805+
payload.append('type', 'folder');
806+
payload.append('description', '');
807+
payload.append('file', imageStream);
808+
const response = await app.inject({
809+
method: HttpMethod.Post,
810+
url: `/api/items/with-thumbnail`,
811+
query: {
812+
parentId: parent.id,
813+
previousItemId: firstChild.id,
814+
},
815+
payload,
816+
headers: payload.getHeaders(),
817+
});
818+
819+
const newItem = response.json();
820+
expectItem(
821+
newItem,
822+
FolderItemFactory({
823+
parentItem: parent,
824+
name: itemName,
825+
type: 'folder',
826+
description: '',
827+
settings: { hasThumbnail: true },
828+
lang: parent.lang,
829+
}),
830+
actor,
831+
);
832+
expect(response.statusCode).toBe(StatusCodes.OK);
833+
expect(uploadDoneMock).toHaveBeenCalled();
834+
835+
// check the children order is correct: first should be first and the new item should be second
836+
const childrenResp = await app.inject({
837+
method: HttpMethod.Get,
838+
url: `/api/items/${parent.id}/children`,
839+
});
840+
const children = await childrenResp.json();
841+
expectItem(newItem, children.at(1));
842+
});
733843
});
734844

735845
describe('PATCH /api/items/:id', () => {

src/services/item/item.schemas.create.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ export const createWithThumbnail = {
161161
summary: 'Create an item with a thumbnail',
162162
description: 'Create an item with a thumbnail. The data is sent using a form-data.',
163163

164-
querystring: Type.Partial(customType.StrictObject({ parentId: customType.UUID() })),
164+
querystring: Type.Partial(
165+
customType.StrictObject({ parentId: customType.UUID(), previousItemId: customType.UUID() }),
166+
),
165167
response: { [StatusCodes.OK]: genericItemSchemaRef, '4xx': errorSchemaRef },
166168
} as const satisfies FastifySchema;

0 commit comments

Comments
 (0)