Skip to content

Commit b73d57a

Browse files
authored
fix: sanitize original order before copy (#1913)
* fix: sanitize original order before copy * refactor: fix tests * refactor: apply PR requested changes * refactor: fix tests
1 parent 6b6a22a commit b73d57a

4 files changed

Lines changed: 358 additions & 58 deletions

File tree

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

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { faker } from '@faker-js/faker';
22
import { and, eq, inArray, ne } from 'drizzle-orm';
3+
import { asc } from 'drizzle-orm/sql';
34
import FormData from 'form-data';
45
import fs from 'fs';
56
import { ReasonPhrases, StatusCodes } from 'http-status-codes';
@@ -1709,7 +1710,7 @@ describe('Item routes tests', () => {
17091710
});
17101711
});
17111712
});
1712-
// // copy many items
1713+
// copy many items
17131714
describe('POST /items/copy', () => {
17141715
it('Throws if signed out', async () => {
17151716
const {
@@ -2104,6 +2105,59 @@ describe('Item routes tests', () => {
21042105
}
21052106
}, MULTIPLE_ITEMS_LOADING_TIME);
21062107
});
2108+
it('Copying corrupted ordered item results in correct copy', async () => {
2109+
const {
2110+
actor,
2111+
items: [targetItem, parentItem, c1, c2, c3],
2112+
} = await seedFromJson({
2113+
items: [
2114+
{
2115+
memberships: [{ account: 'actor', permission: PermissionLevel.Write }],
2116+
},
2117+
{
2118+
memberships: [{ account: 'actor', permission: PermissionLevel.Write }],
2119+
children: [
2120+
{ order: 20, createdAt: '2012-10-05T14:48:00.000Z' },
2121+
{ order: 20, createdAt: '2011-10-05T14:48:00.000Z' },
2122+
{ order: 20, createdAt: '2013-10-05T14:48:00.000Z' },
2123+
],
2124+
},
2125+
],
2126+
});
2127+
assertIsDefined(actor);
2128+
assertIsMemberForTest(actor);
2129+
mockAuthenticate(actor);
2130+
2131+
const response = await app.inject({
2132+
method: HttpMethod.Post,
2133+
url: '/items/copy',
2134+
query: { id: [parentItem.id] },
2135+
payload: {
2136+
parentId: targetItem.id,
2137+
},
2138+
});
2139+
expect(response.statusCode).toBe(StatusCodes.ACCEPTED);
2140+
// wait a bit for tasks to complete
2141+
await waitForExpect(async () => {
2142+
const copyRoot = await db.query.itemsRawTable.findFirst({
2143+
where: isDirectChild(itemsRawTable.path, targetItem.path),
2144+
});
2145+
expect(copyRoot).toBeDefined();
2146+
const copiedChildren = await db.query.itemsRawTable.findMany({
2147+
where: isDirectChild(itemsRawTable.path, copyRoot!.path),
2148+
orderBy: asc(itemsRawTable.order),
2149+
});
2150+
expect(copiedChildren).toHaveLength(3);
2151+
2152+
// order are repaired
2153+
expect(copiedChildren[0].name).toEqual(c2.name);
2154+
expect(copiedChildren[0].order).toEqual(20);
2155+
expect(copiedChildren[1].name).toEqual(c1.name);
2156+
expect(copiedChildren[1].order).toEqual(40);
2157+
expect(copiedChildren[2].name).toEqual(c3.name);
2158+
expect(copiedChildren[2].order).toEqual(60);
2159+
}, MULTIPLE_ITEMS_LOADING_TIME);
2160+
});
21072161
it('Bad request if one id is invalid', async () => {
21082162
const { actor, items } = await seedFromJson({
21092163
items: [

0 commit comments

Comments
 (0)