strapi/api-tests/core/upload/admin/folder.test.api.js
Josh 4f4e3c3acd
feat(cm): D&P pt2 (#19380)
* feat: return metadata on content manager endpoints (#19361)

* feat: return metadata on content manager endpoints

* feat: return meta

* fix: cm tests

* feat: fix cm metadata api tests (#19375)

* feat: return metadata on content manager endpoints

* feat: return meta

* fix: cm tests

* fix: admin test

* chore(cm): refactor CM (#19341)

* chore(cm): refactor EditView

comes with a host of new re-usable APIs!

* feat(cm): add useDocument hook

* feat(cm): add useDocumentOperations hook

* feat(cm): initialise EditView header

* feat(cm): add useDocumentLayout hook

* fix: listView from layout refactor

* chore(cm): refactor editview form input renderer

* chore: fix lint & ts

* fix: re-add custom fields

* test: fix admin/CM unit tests

* docs(cm): add docs at a high level of how the CM works

* test: add useDocumentRBAC tests

* chore: pr amends

* feat: add addEditViewSidePanel API to strapi (#19398)

* feat: add addEditViewSidePanel API to strapi

fix: don't pass all the query params to the create route

* chore: pr amends

* fix: return available status when content type doesnt have i18n enabled (#19419)

* fix: return available status when content type doesnt have i18n enabled

* chore: remove comment

* fix(cm): list view & build process

* feat: save and publish

* feat: update contract

* feat: dp tests

* chore: use document from create and update

* feat: save and publish single types

* feat: return metadata on content manager endpoints (#19361)

* feat: return metadata on content manager endpoints

* feat: return meta

* fix: cm tests

* feat: fix cm metadata api tests (#19375)

* feat: return metadata on content manager endpoints

* feat: return meta

* fix: cm tests

* fix: admin test

* chore(cm): refactor CM (#19341)

* chore(cm): refactor EditView

comes with a host of new re-usable APIs!

* feat(cm): add useDocument hook

* feat(cm): add useDocumentOperations hook

* feat(cm): initialise EditView header

* feat(cm): add useDocumentLayout hook

* fix: listView from layout refactor

* chore(cm): refactor editview form input renderer

* chore: fix lint & ts

* fix: re-add custom fields

* test: fix admin/CM unit tests

* docs(cm): add docs at a high level of how the CM works

* test: add useDocumentRBAC tests

* chore: pr amends

* feat: add addEditViewSidePanel API to strapi (#19398)

* feat: add addEditViewSidePanel API to strapi

fix: don't pass all the query params to the create route

* chore: pr amends

* fix: return available status when content type doesnt have i18n enabled (#19419)

* fix: return available status when content type doesnt have i18n enabled

* chore: remove comment

* fix(cm): list view & build process

* feat: add publish & update action (#19423)

* feat: return metadata on content manager endpoints (#19361)

* feat: return metadata on content manager endpoints

* feat: return meta

* fix: cm tests

* feat: fix cm metadata api tests (#19375)

* feat: return metadata on content manager endpoints

* feat: return meta

* fix: cm tests

* fix: admin test

* chore(cm): refactor CM (#19341)

* chore(cm): refactor EditView

comes with a host of new re-usable APIs!

* feat(cm): add useDocument hook

* feat(cm): add useDocumentOperations hook

* feat(cm): initialise EditView header

* feat(cm): add useDocumentLayout hook

* fix: listView from layout refactor

* chore(cm): refactor editview form input renderer

* chore: fix lint & ts

* fix: re-add custom fields

* test: fix admin/CM unit tests

* docs(cm): add docs at a high level of how the CM works

* test: add useDocumentRBAC tests

* chore: pr amends

* feat: add addEditViewSidePanel API to strapi (#19398)

* feat: add addEditViewSidePanel API to strapi

fix: don't pass all the query params to the create route

* chore: pr amends

* fix: return available status when content type doesnt have i18n enabled (#19419)

* fix: return available status when content type doesnt have i18n enabled

* chore: remove comment

* feat: add publish & update action

* feat: add published disabled state

* test: fix suite

* test: add unit for Panels

* fix(cm): status not state for redirect

* fix(cm): list view status & component main field property

* chore: pr feedback

* chore: apply suggestions

Co-authored-by: markkaylor <mark.kaylor@strapi.io>

---------

Co-authored-by: Marc Roig <marc12info@gmail.com>
Co-authored-by: markkaylor <mark.kaylor@strapi.io>

* feat: test single types

* feat: wrap single type publish into a transaction

* feat(cm): add unpublish & delete actions, also re-enable single-types (#19459)

* fix: delete url was wrong way round

* feat: compute modified status

* fix(cm): reimplement ListSettingsView (#19432)

* chore: PR feedback

* feat: discard endpoint

* feat: discard draft api tests

* feat: unpublish and discard

* chore: pr comments

* chore: update sanitizer

* feat(cm): add publish and save (#19500)

* feat(cm): add publish and save

* test(cm): fix unit for useDocumentActions

* Update packages/core/content-manager/server/src/controllers/collection-types.ts

Co-authored-by: Jamie Howard <48524071+jhoward1994@users.noreply.github.com>

* Update packages/core/content-manager/shared/contracts/single-types-v5.ts

Co-authored-by: Jamie Howard <48524071+jhoward1994@users.noreply.github.com>

* feat(document-service): map document ID to entry ID (#19248)

* feat: use document service in content manager

* feat: update contracts with meta information

* chore: group metadata types into a single type

* feat: metadata information in single types

* chore: change meta contract to return documents instead of strings

* fix: remove unused type

* fix: ignore doc id if entry is null

* fix: update contract metadata

* feat: document metadata service

* feat: locale and status filtering

* chore: add comment

* chore: refactor metadata service

* chore: refactor entity manager exists to handle single types

* feat: refactor single type controllers to use documents

* feat: get locale param from in cm endpoints

* Revert "feat: get locale param from in cm endpoints"

This reverts commit 856c38588b8f8521cadd85c8c933f42a36a2178a.

* feat: get locale param from cm endpoints

* Update packages/plugins/i18n/server/src/controllers/validate-locale-creation.ts

Co-authored-by: Ben Irvin <ben@innerdvations.com>

* fix: entity manager unit tests

* chore: unit test document metadata

* feat: prevent empty string locale filtering

* fix: cm contract import

* chore: test new d&p cm features

* fix: search content manager api test

* fix: cm tests

* fix: cm tests

* fix: cm tests

* fix(content-manager): access to non default locale documents (#19190)

* fix(content-manager): access to non default locale documents

* chore(content-manager): revert route construction

* fix(content-manager): api tests for number of draft relations

* test(content-manager): counting number of draft relations for non default locales

* chore(content-manager): remove default locale from entity manager countDraftRelations

* chore: basic relations testing for document service

* chore(e2e): disable edit view tests (#19235)

* feat: get relation ids

* chore: clean functions into other folders

* chore: rename files

* fix: group document ids by its uid

* feat: id mapper

* chore: improve typings

* chore: rename transform functions

* fix: id-transform tests

* chore: simplify function return value

* chore: improve comments

* fix: api tests

* fix: single types unit test

* fix: skip relations test

* fix: exclude fields

* fix: short hand ifs

* fix: merge conflict

* fix: transform output of find one

* Update packages/core/core/src/services/document-service/transform/utils.ts

Co-authored-by: Ben Irvin <ben.irvin@strapi.io>

* feat[Document Service]: Param transformation (#19373)

* fix(core): wip param transformation

* feat(core): wip param transformation based on relational status

* feat(core): wip populate and filter transformation based on relational status

* chore(core): simplify fields and sort

* chore(core): clean up

* feat(core): wip filter transformation with traverseQueryFilters

* feat(core): reorganise and PR feedback

* fix(core): filters traversal logic

* feat(core): populate relational transformations

* chore(core): reintroduce populate transformation

* fix(core): enforce that fields must include id

* fix(core): enforce that fields must include id

* fix(core): filter and sort transformation

* chore(core): typos

* chore(core): further filters test cases

* feat(core): support object based sorts

* chore(core): fields test naming

* feat(core): handle logical operators in filters

* fix: skip conditions test

* fix(core): switchIdForDocumentId (#19497)

* fix: uniqueness test

* fix: available status should be an array

* fix: available statuses

* fix: skip uniqueness folder

* fix: skip uniqueness test errors

* fix: skip failing test

---------

Co-authored-by: Ben Irvin <ben@innerdvations.com>
Co-authored-by: Jamie Howard <48524071+jhoward1994@users.noreply.github.com>
Co-authored-by: Josh <37798644+joshuaellis@users.noreply.github.com>
Co-authored-by: Jamie Howard <jamie.howard@strapi.io>
Co-authored-by: Ben Irvin <ben.irvin@strapi.io>

* chore: re-implement edit configuration (#19488)

* chore: re-implement edit configuration

* chore: cleanups

* test: fix unit tests

* feat(cm): add discard changes action (#19509)

* feat(cm): add discard changes action

* feat(cm): add discard when unpublishing

* test(e2e): fix editview e2e

* test(e2e): fix uniqueness partially

* test(unit): fix unit tests for actions & add for discard

* chore: bump playwright

* fix(webkit): add shim for requestIdCallback

* chore: pr amends

* feat: return status on available locales

* feat: add document-actions to list-view (#19523)

* fix(cm): add gap and alignment for edit-view heading with super long names

* fix(cm): list view status'

* feat: add list-view actions

* fix: conditions for actions to be enabled

* fix: stay on draft tab when published

* fix: stop propogation on list-view row click

* test(e2e): fix editview tests

* chore: update spelling error

Co-authored-by: Jamie Howard <48524071+jhoward1994@users.noreply.github.com>

---------

Co-authored-by: Jamie Howard <48524071+jhoward1994@users.noreply.github.com>

* feat: test document metadata

* chore: remove unnecessary unit test

* fix: return modified on published documents

* chore: init split single-type collection-type in document service

* Fix/fields test case (#19481)

* Update packages/core/content-manager/server/src/services/document-metadata.ts

Co-authored-by: Jamie Howard <48524071+jhoward1994@users.noreply.github.com>

* fix: pretty

* chore: refactor middlewares

* feat: send empty object if locale does not exist on document

* feat: single types

* chore: add tests to middlewares

* feat: update locale using query params (#19546)

* feat: return available locales when not finding locale

* chore: update typings

* feat: add clone action (#19526)

* feat: add clone action

* test(e2e): add auto clone tests

* chore: pr amends

* feat: add information to header actions menu (#19548)

* feat: add information to header actions menu

* fix: dont use non-null-assertion

* feat: manage relations on publish (#19427)


---------

Co-authored-by: Ben Irvin <ben@innerdvations.com>
Co-authored-by: Jamie Howard <48524071+jhoward1994@users.noreply.github.com>
Co-authored-by: Josh <37798644+joshuaellis@users.noreply.github.com>
Co-authored-by: Jamie Howard <jamie.howard@strapi.io>

* feat: v5 i18n relations (#19504)


Co-authored-by: Ben Irvin <ben@innerdvations.com>
Co-authored-by: Jamie Howard <48524071+jhoward1994@users.noreply.github.com>
Co-authored-by: Josh <37798644+joshuaellis@users.noreply.github.com>
Co-authored-by: Jamie Howard <jamie.howard@strapi.io>

* fix: locale test api

* chore: refactor i18n (#19555)

* chore: remove types package, should be using strapi

* chore: refactor i18n settings page

* feat: add i18n to CM

* feat(i18n): add delete locale action (#19562)

* chore: pr amends

Co-authored-by: Simone <startae14@gmail.com>

---------

Co-authored-by: Simone <startae14@gmail.com>

* feat(cm): re-implement validation (#19578)

* feat: re-implement validation in the CM

feat: add blocker

feat: handle validation errors from the API

chore: reimplement useFieldHint

test(unit): fix fe tests

chore: fix bad logical operator

* chore: await notifications to leave before trying to go to other pages

* fix: validation issues & blocker showing up incorrectly

* fix: broken publish behaviour

* fix(content-manager): uid availability and generation (#19518)

* fix(content-manager): uid availability and generation

* fix(content-manager): pass locale as is from UID service

* fix(content-manager): match UIDs based on startsWith

---------

Co-authored-by: Marc Roig <marc12info@gmail.com>
Co-authored-by: markkaylor <mark.kaylor@strapi.io>
Co-authored-by: Jamie Howard <48524071+jhoward1994@users.noreply.github.com>
Co-authored-by: Ben Irvin <ben@innerdvations.com>
Co-authored-by: Jamie Howard <jamie.howard@strapi.io>
Co-authored-by: Ben Irvin <ben.irvin@strapi.io>
Co-authored-by: Alexandre Bodin <bodin.alex@gmail.com>
Co-authored-by: Alexandre BODIN <alexandrebodin@users.noreply.github.com>
Co-authored-by: Simone <startae14@gmail.com>
2024-02-22 17:18:32 +00:00

521 lines
15 KiB
JavaScript

'use strict';
const fs = require('fs');
const path = require('path');
const { pick, map } = require('lodash/fp');
const { createTestBuilder } = require('api-tests/builder');
const { createStrapiInstance } = require('api-tests/strapi');
const { createAuthRequest } = require('api-tests/request');
let strapi;
let rq;
const data = {
folders: [],
};
const rootPathRegex = /^\/[0-9]*$/i;
const getFolderPathRegex = (pathId) => new RegExp(`^/${pathId}/[0-9]*$`, 'i');
const createFolder = async (name, parent = null) => {
const res = await rq({
method: 'POST',
url: '/upload/folders',
body: { name, parent },
});
return res.body.data;
};
const createAFile = async (parent = null) => {
const res = await rq({
method: 'POST',
url: '/upload',
formData: {
files: fs.createReadStream(path.join(__dirname, '../utils/rec.jpg')),
fileInfo: JSON.stringify({ folder: parent }),
},
});
return res.body[0];
};
describe.skip('Folder', () => {
const builder = createTestBuilder();
beforeAll(async () => {
strapi = await createStrapiInstance();
rq = await createAuthRequest({ strapi });
});
afterAll(async () => {
await rq({
method: 'POST',
url: '/upload/actions/bulk-delete',
body: {
folderIds: data.folders.map((f) => f.id),
},
});
await strapi.destroy();
await builder.cleanup();
});
describe('create', () => {
test('Can create a folder at root level', async () => {
const res = await rq({
method: 'POST',
url: '/upload/folders',
body: {
name: 'folder 1',
parent: null,
},
});
expect(res.status).toBe(200);
expect(res.body.data).toMatchObject({
id: expect.anything(),
name: 'folder 1',
pathId: expect.any(Number),
path: expect.stringMatching(rootPathRegex),
createdAt: expect.anything(),
updatedAt: expect.anything(),
});
expect(res.body.data.pathId.toString()).toBe(res.body.data.path.split('/').pop());
data.folders.push(res.body.data);
});
test('Can create a folder inside another folder', async () => {
const res = await rq({
method: 'POST',
url: '/upload/folders',
body: {
name: 'folder-2',
parent: data.folders[0].id,
},
});
expect(res.body.data).toMatchObject({
id: expect.anything(),
name: 'folder-2',
pathId: expect.any(Number),
path: expect.stringMatching(getFolderPathRegex(data.folders[0].pathId)),
createdAt: expect.anything(),
updatedAt: expect.anything(),
});
expect(res.body.data.pathId.toString()).toBe(res.body.data.path.split('/').pop());
data.folders.push(res.body.data);
});
test('Cannot create a folder with duplicated name at root level', async () => {
const res = await rq({
method: 'POST',
url: '/upload/folders',
body: {
name: 'folder 1',
parent: null,
},
});
expect(res.status).toBe(400);
expect(res.body.error.message).toBe('A folder with this name already exists');
});
test('Cannot create a folder with duplicated name inside a folder', async () => {
const res = await rq({
method: 'POST',
url: '/upload/folders',
body: {
name: 'folder-2',
parent: data.folders[0].id,
},
});
expect(res.status).toBe(400);
expect(res.body.error.message).toBe('A folder with this name already exists');
});
test('Cannot create a folder inside a folder that does not exist', async () => {
const res = await rq({
method: 'POST',
url: '/upload/folders',
body: {
name: 'folder-3',
parent: 99999,
},
});
expect(res.status).toBe(400);
expect(res.body.error.message).toBe('parent folder does not exist');
});
test('Cannot create a folder with name containing a slash', async () => {
const res = await rq({
method: 'POST',
url: '/upload/folders',
body: {
name: 'folder 1/2',
parent: null,
},
});
expect(res.status).toBe(400);
expect(res.body.error.message).toBe('name cannot contain slashes');
});
test.each([[' abc'], [' abc '], ['abc '], [' abc '], [' abc ']])(
'Cannot create a folder with name starting or ending with a whitespace (%p)',
async (name) => {
const res = await rq({
method: 'POST',
url: '/upload/folders',
body: {
name,
parent: null,
},
});
expect(res.status).toBe(400);
expect(res.body.error.message).toBe('name cannot start or end with a whitespace');
}
);
});
describe('read', () => {
test('Can read a folder', async () => {
const res = await rq({
method: 'GET',
url: `/upload/folders/${data.folders[0].id}`,
});
expect(res.body.data).toMatchObject({
...pick(['id', 'name', 'pathId', 'path', 'createAt', 'updatedAt'], data.folders[0]),
children: {
count: expect.anything(),
},
files: {
count: expect.anything(),
},
});
});
test('Can read a folder & populate its parent', async () => {
const res = await rq({
method: 'GET',
url: `/upload/folders/${data.folders[1].id}`,
qs: {
populate: 'parent',
},
});
expect(res.body.data).toMatchObject({
...pick(['id', 'name', 'pathId', 'path', 'createAt', 'updatedAt'], data.folders[1]),
parent: {
id: expect.any(Number),
},
});
});
test('Return 404 when folder does not exist', async () => {
const res = await rq({
method: 'GET',
url: '/upload/folders/99999',
});
expect(res.status).toBe(404);
});
test('Can read folders', async () => {
const res = await rq({
method: 'GET',
url: '/upload/folders',
});
expect(res.body.data).toEqual(
expect.arrayContaining([
{
...data.folders[0],
children: { count: 1 },
files: { count: 0 },
},
{
...data.folders[1],
children: { count: 0 },
files: { count: 0 },
},
])
);
});
});
describe('update', () => {
test('Return 404 when folder does not exist', async () => {
const res = await rq({
method: 'PUT',
url: '/upload/folders/99999',
body: {
name: 'new name',
},
});
expect(res.status).toBe(404);
});
test('Rename a folder', async () => {
const folder = await createFolder('folder-name', null);
const res = await rq({
method: 'PUT',
url: `/upload/folders/${folder.id}`,
body: {
name: 'new name folder',
},
});
expect(res.body.data).toMatchObject({
name: 'new name',
path: folder.path,
});
data.folders.push(res.body.data);
});
test('Cannot move and rename a folder if duplicated', async () => {
const folder0 = await createFolder('folder-a-0', null);
const folder1 = await createFolder('folder-a-1', null);
const folder00 = await createFolder('folder-a-00', folder0.id);
data.folders.push(folder0, folder1, folder00);
const res = await rq({
method: 'PUT',
url: `/upload/folders/${folder1.id}`,
body: {
name: 'folder-a-00',
parent: folder0.id,
},
});
expect(res.status).toBe(400);
expect(res.body.error.message).toBe('A folder with this name already exists');
});
test('Cannot move a folder if duplicated', async () => {
const folder0 = await createFolder('folder-b-0', null);
const folder1 = await createFolder('folder-b-samename', null);
await createFolder('folder-b-samename', folder0.id);
data.folders.push(folder0, folder1);
const res = await rq({
method: 'PUT',
url: `/upload/folders/${folder1.id}`,
body: {
parent: folder0.id,
},
});
expect(res.status).toBe(400);
expect(res.body.error.message).toBe('A folder with this name already exists');
});
test('Cannot move a folder to a folder that does not exist', async () => {
const folder = await createFolder('folder-c-0', null);
data.folders.push(folder);
const res = await rq({
method: 'PUT',
url: `/upload/folders/${folder.id}`,
body: {
parent: 9999,
},
});
expect(res.status).toBe(400);
expect(res.body.error.message).toBe('parent folder does not exist');
});
test('Cannot move a folder inside itself (0 level)', async () => {
const folder = await createFolder('folder-d-0', null);
data.folders.push(folder);
const res = await rq({
method: 'PUT',
url: `/upload/folders/${folder.id}`,
body: {
parent: folder.id,
},
});
expect(res.status).toBe(400);
expect(res.body.error.message).toBe('folder cannot be moved inside itself');
});
test('Cannot move a folder inside itself (1 level)', async () => {
const folder0 = await createFolder('folder-e-0', null);
const folder00 = await createFolder('folder-e-00', folder0.id);
data.folders.push(folder0, folder00);
const res = await rq({
method: 'PUT',
url: `/upload/folders/${folder0.id}`,
body: {
parent: folder00.id,
},
});
expect(res.status).toBe(400);
expect(res.body.error.message).toBe('folder cannot be moved inside itself');
});
test('Cannot move a folder inside itself (2 levels)', async () => {
const folder0 = await createFolder('folder-f-0', null);
const folder00 = await createFolder('folder-f-00', folder0.id);
const folder000 = await createFolder('folder-f-000', folder00.id);
data.folders.push(folder0, folder00, folder000);
const res = await rq({
method: 'PUT',
url: `/upload/folders/${folder0.id}`,
body: {
parent: folder000.id,
},
});
expect(res.status).toBe(400);
expect(res.body.error.message).toBe('folder cannot be moved inside itself');
});
test('Move a folder inside another folder', async () => {
const folder0 = await createFolder('folder-0', null);
const folder00 = await createFolder('folder-00', folder0.id);
const folder01 = await createFolder('folder-01', folder0.id);
const folder02 = await createFolder('folder-02', folder0.id);
const folder000 = await createFolder('folder-000', folder00.id);
const file000 = await createAFile(folder000.id);
const file02 = await createAFile(folder02.id);
// moving folder00 in folder01
const res = await rq({
method: 'PUT',
url: `/upload/folders/${folder00.id}`,
body: {
name: 'folder-00-new',
parent: folder01.id,
},
});
expect(res.body.data).toMatchObject({
name: 'folder-00-new',
path: `${folder01.path}/${folder00.pathId}`,
});
const resFolders = await rq({
method: 'GET',
url: '/upload/folders',
qs: {
filters: { id: { $in: map('id', [folder0, folder00, folder01, folder02, folder000]) } },
sort: 'id:asc',
populate: { parent: '*' },
},
});
expect(resFolders.body.data[0]).toMatchObject({ path: folder0.path, parent: null });
expect(resFolders.body.data[1]).toMatchObject({
path: `${folder01.path}/${folder00.pathId}`,
parent: { id: folder01.id },
});
expect(resFolders.body.data[2]).toMatchObject({
path: folder01.path,
parent: { id: folder0.id },
});
expect(resFolders.body.data[3]).toMatchObject({
path: folder02.path,
parent: { id: folder0.id },
});
expect(resFolders.body.data[4]).toMatchObject({
path: `${folder01.path}/${folder00.pathId}/${folder000.pathId}`,
parent: { id: folder00.id },
});
const resFiles = await rq({
method: 'GET',
url: '/upload/files',
qs: {
filters: { id: { $in: [file000.id, file02.id] } },
sort: 'id:asc',
},
});
expect(resFiles.body.results[0]).toMatchObject({
folderPath: `${folder01.path}/${folder00.pathId}/${folder000.pathId}`,
});
expect(resFiles.body.results[1]).toMatchObject({ folderPath: file02.folderPath });
data.folders.push(...resFolders.body.data);
});
test('Move a folder to root level', async () => {
const folder0 = await createFolder('folder-test-0', null);
const folder00 = await createFolder('folder-test-00', folder0.id);
const folder02 = await createFolder('folder-test-02', folder0.id);
const folder000 = await createFolder('folder-test-000', folder00.id);
const file000 = await createAFile(folder000.id);
const file02 = await createAFile(folder02.id);
// moving folder00 in folder01
const res = await rq({
method: 'PUT',
url: `/upload/folders/${folder00.id}`,
body: {
name: 'folder-test-00-new',
parent: null,
},
});
expect(res.body.data).toMatchObject({
name: 'folder-test-00-new',
path: `/${folder00.pathId}`,
});
const resFolders = await rq({
method: 'GET',
url: '/upload/folders',
qs: {
filters: { id: { $in: map('id', [folder0, folder00, folder02, folder000]) } },
sort: 'id:asc',
populate: { parent: '*' },
},
});
expect(resFolders.body.data[0]).toMatchObject({ path: folder0.path, parent: null });
expect(resFolders.body.data[1]).toMatchObject({
path: `/${folder00.pathId}`,
parent: null,
});
expect(resFolders.body.data[2]).toMatchObject({
path: folder02.path,
parent: { id: folder0.id },
});
expect(resFolders.body.data[3]).toMatchObject({
path: `/${folder00.pathId}/${folder000.pathId}`,
parent: { id: folder00.id },
});
const resFiles = await rq({
method: 'GET',
url: '/upload/files',
qs: {
filters: { id: { $in: [file000.id, file02.id] } },
sort: 'id:asc',
},
});
expect(resFiles.body.results[0]).toMatchObject({
folderPath: `/${folder00.pathId}/${folder000.pathId}`,
});
expect(resFiles.body.results[1]).toMatchObject({ folderPath: file02.folderPath });
data.folders.push(...resFolders.body.data);
});
});
});