2022-03-22 18:19:46 +01:00
|
|
|
'use strict';
|
|
|
|
|
2022-04-26 11:23:07 +02:00
|
|
|
const fs = require('fs');
|
|
|
|
const path = require('path');
|
2022-03-22 18:19:46 +01:00
|
|
|
|
2022-04-29 09:51:55 +02:00
|
|
|
const { omit, pick, map } = require('lodash/fp');
|
2022-03-22 18:19:46 +01:00
|
|
|
|
|
|
|
const { createTestBuilder } = require('../../../../../test/helpers/builder');
|
|
|
|
const { createStrapiInstance } = require('../../../../../test/helpers/strapi');
|
|
|
|
const { createAuthRequest } = require('../../../../../test/helpers/request');
|
|
|
|
|
|
|
|
let strapi;
|
|
|
|
let rq;
|
|
|
|
let data = {
|
|
|
|
folders: [],
|
|
|
|
};
|
|
|
|
|
2022-04-05 17:36:09 +02:00
|
|
|
const uuidRegex = /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i;
|
2022-04-12 16:32:05 +02:00
|
|
|
const rootPathRegex = /^\/[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i;
|
|
|
|
const getFolderPathRegex = uid =>
|
2022-04-05 17:36:09 +02:00
|
|
|
new RegExp(
|
|
|
|
'^/' + uid + '/[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$',
|
|
|
|
'i'
|
|
|
|
);
|
|
|
|
|
2022-04-26 11:23:07 +02:00
|
|
|
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];
|
|
|
|
};
|
|
|
|
|
2022-03-22 18:19:46 +01:00
|
|
|
describe('Folder', () => {
|
|
|
|
const builder = createTestBuilder();
|
|
|
|
|
|
|
|
beforeAll(async () => {
|
|
|
|
strapi = await createStrapiInstance();
|
|
|
|
rq = await createAuthRequest({ strapi });
|
|
|
|
});
|
|
|
|
|
|
|
|
afterAll(async () => {
|
2022-04-07 18:00:21 +02:00
|
|
|
await rq({
|
|
|
|
method: 'POST',
|
2022-04-26 11:23:07 +02:00
|
|
|
url: '/upload/actions/bulk-delete',
|
2022-04-07 18:00:21 +02:00
|
|
|
body: {
|
2022-04-26 11:23:07 +02:00
|
|
|
folderIds: data.folders.map(f => f.id),
|
2022-04-07 18:00:21 +02:00
|
|
|
},
|
|
|
|
});
|
|
|
|
|
2022-03-22 18:19:46 +01:00
|
|
|
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?populate=parent',
|
|
|
|
body: {
|
2022-03-28 16:51:11 +02:00
|
|
|
name: 'folder 1',
|
2022-03-22 18:19:46 +01:00
|
|
|
parent: null,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
2022-04-04 14:32:08 +02:00
|
|
|
expect(res.status).toBe(200);
|
2022-03-22 18:19:46 +01:00
|
|
|
expect(res.body.data).toMatchObject({
|
|
|
|
id: expect.anything(),
|
2022-03-28 16:51:11 +02:00
|
|
|
name: 'folder 1',
|
2022-04-05 17:36:09 +02:00
|
|
|
uid: expect.stringMatching(uuidRegex),
|
2022-04-12 16:32:05 +02:00
|
|
|
path: expect.stringMatching(rootPathRegex),
|
2022-03-22 18:19:46 +01:00
|
|
|
createdAt: expect.anything(),
|
|
|
|
updatedAt: expect.anything(),
|
|
|
|
parent: null,
|
|
|
|
});
|
2022-04-12 16:32:05 +02:00
|
|
|
expect(res.body.data.uid).toBe(res.body.data.path.split('/').pop());
|
2022-03-22 18:19:46 +01:00
|
|
|
|
|
|
|
data.folders.push(omit('parent', res.body.data));
|
|
|
|
});
|
|
|
|
|
2022-04-04 14:32:08 +02:00
|
|
|
test('Can create a folder inside another folder', async () => {
|
|
|
|
const res = await rq({
|
|
|
|
method: 'POST',
|
|
|
|
url: '/upload/folders?populate=parent',
|
|
|
|
body: {
|
|
|
|
name: 'folder-2',
|
|
|
|
parent: data.folders[0].id,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(res.body.data).toMatchObject({
|
|
|
|
id: expect.anything(),
|
|
|
|
name: 'folder-2',
|
2022-04-05 17:36:09 +02:00
|
|
|
uid: expect.stringMatching(uuidRegex),
|
2022-04-12 16:32:05 +02:00
|
|
|
path: expect.stringMatching(getFolderPathRegex(data.folders[0].uid)),
|
2022-04-04 14:32:08 +02:00
|
|
|
createdAt: expect.anything(),
|
|
|
|
updatedAt: expect.anything(),
|
|
|
|
parent: data.folders[0],
|
|
|
|
});
|
2022-04-12 16:32:05 +02:00
|
|
|
expect(res.body.data.uid).toBe(res.body.data.path.split('/').pop());
|
2022-04-04 14:32:08 +02:00
|
|
|
|
|
|
|
data.folders.push(omit('parent', res.body.data));
|
|
|
|
});
|
|
|
|
|
2022-03-22 18:19:46 +01:00
|
|
|
test('Cannot create a folder with duplicated name at root level', async () => {
|
|
|
|
const res = await rq({
|
|
|
|
method: 'POST',
|
|
|
|
url: '/upload/folders?populate=parent',
|
|
|
|
body: {
|
2022-03-28 16:51:11 +02:00
|
|
|
name: 'folder 1',
|
2022-03-22 18:19:46 +01:00
|
|
|
parent: null,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(res.status).toBe(400);
|
2022-05-02 16:31:27 +02:00
|
|
|
expect(res.body.error.message).toBe('folder already exists');
|
2022-03-22 18:19:46 +01:00
|
|
|
});
|
|
|
|
|
2022-04-04 14:32:08 +02:00
|
|
|
test('Cannot create a folder with duplicated name inside a folder', async () => {
|
|
|
|
const res = await rq({
|
|
|
|
method: 'POST',
|
|
|
|
url: '/upload/folders?populate=parent',
|
|
|
|
body: {
|
|
|
|
name: 'folder-2',
|
2022-04-26 11:23:07 +02:00
|
|
|
parent: data.folders[0].id,
|
2022-04-04 14:32:08 +02:00
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(res.status).toBe(400);
|
2022-05-02 16:31:27 +02:00
|
|
|
expect(res.body.error.message).toBe('folder already exists');
|
2022-04-04 14:32:08 +02:00
|
|
|
});
|
|
|
|
|
2022-04-26 11:23:07 +02:00
|
|
|
test('Cannot create a folder inside a folder that does not exist', async () => {
|
|
|
|
const res = await rq({
|
|
|
|
method: 'POST',
|
|
|
|
url: '/upload/folders?populate=parent',
|
|
|
|
body: {
|
|
|
|
name: 'folder-3',
|
|
|
|
parent: 99999,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(res.status).toBe(400);
|
|
|
|
expect(res.body.error.message).toBe('parent folder does not exist');
|
|
|
|
});
|
|
|
|
|
2022-03-28 16:51:11 +02:00
|
|
|
test('Cannot create a folder with name containing a slash', async () => {
|
2022-03-22 18:19:46 +01:00
|
|
|
const res = await rq({
|
|
|
|
method: 'POST',
|
|
|
|
url: '/upload/folders?populate=parent',
|
|
|
|
body: {
|
2022-03-28 16:51:11 +02:00
|
|
|
name: 'folder 1/2',
|
2022-03-22 18:19:46 +01:00
|
|
|
parent: null,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(res.status).toBe(400);
|
|
|
|
expect(res.body.error.message).toBe('name cannot contain slashes');
|
|
|
|
});
|
|
|
|
|
2022-03-28 16:51:11 +02:00
|
|
|
test.each([[' abc'], [' abc '], ['abc '], [' abc '], [' abc ']])(
|
2022-04-04 14:32:08 +02:00
|
|
|
'Cannot create a folder with name starting or ending with a whitespace (%p)',
|
2022-03-28 16:51:11 +02:00
|
|
|
async name => {
|
|
|
|
const res = await rq({
|
|
|
|
method: 'POST',
|
|
|
|
url: '/upload/folders?populate=parent',
|
|
|
|
body: {
|
|
|
|
name,
|
|
|
|
parent: null,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(res.status).toBe(400);
|
|
|
|
expect(res.body.error.message).toBe('name cannot start or end with a whitespace');
|
|
|
|
}
|
|
|
|
);
|
2022-03-22 18:19:46 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
describe('read', () => {
|
|
|
|
test('Can read folders', async () => {
|
|
|
|
const res = await rq({
|
|
|
|
method: 'GET',
|
|
|
|
url: '/upload/folders',
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(res.body.pagination).toMatchObject({
|
|
|
|
page: 1,
|
|
|
|
pageCount: 1,
|
|
|
|
pageSize: 10,
|
|
|
|
total: 2,
|
|
|
|
});
|
|
|
|
expect(res.body.results).toEqual(
|
|
|
|
expect.arrayContaining([
|
|
|
|
{
|
2022-04-05 17:36:09 +02:00
|
|
|
...data.folders[0],
|
2022-03-22 18:19:46 +01:00
|
|
|
children: { count: 1 },
|
|
|
|
createdBy: {
|
2022-03-22 18:57:50 +01:00
|
|
|
firstname: expect.anything(),
|
2022-03-22 18:19:46 +01:00
|
|
|
id: expect.anything(),
|
2022-03-22 18:57:50 +01:00
|
|
|
lastname: expect.anything(),
|
2022-03-22 18:19:46 +01:00
|
|
|
username: null,
|
|
|
|
},
|
|
|
|
files: { count: 0 },
|
|
|
|
parent: null,
|
|
|
|
updatedBy: {
|
2022-03-22 18:57:50 +01:00
|
|
|
firstname: expect.anything(),
|
2022-03-22 18:19:46 +01:00
|
|
|
id: expect.anything(),
|
2022-03-22 18:57:50 +01:00
|
|
|
lastname: expect.anything(),
|
2022-03-22 18:19:46 +01:00
|
|
|
username: null,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2022-04-05 17:36:09 +02:00
|
|
|
...data.folders[1],
|
2022-03-22 18:19:46 +01:00
|
|
|
children: { count: 0 },
|
|
|
|
createdBy: {
|
2022-03-22 18:57:50 +01:00
|
|
|
firstname: expect.anything(),
|
2022-03-22 18:19:46 +01:00
|
|
|
id: expect.anything(),
|
2022-03-22 18:57:50 +01:00
|
|
|
lastname: expect.anything(),
|
2022-03-22 18:19:46 +01:00
|
|
|
username: null,
|
|
|
|
},
|
2022-03-22 18:57:50 +01:00
|
|
|
files: { count: 0 },
|
2022-04-12 16:32:05 +02:00
|
|
|
parent: pick(['createdAt', 'id', 'name', 'path', 'uid', 'updatedAt'], data.folders[0]),
|
2022-03-22 18:19:46 +01:00
|
|
|
updatedBy: {
|
2022-03-22 18:57:50 +01:00
|
|
|
firstname: expect.anything(),
|
2022-03-22 18:19:46 +01:00
|
|
|
id: expect.anything(),
|
2022-03-22 18:57:50 +01:00
|
|
|
lastname: expect.anything(),
|
2022-03-22 18:19:46 +01:00
|
|
|
username: null,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
])
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
2022-04-04 14:32:08 +02:00
|
|
|
|
2022-04-29 09:51:55 +02:00
|
|
|
describe('update', () => {
|
|
|
|
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',
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(res.body.data).toMatchObject({
|
|
|
|
name: 'new name',
|
|
|
|
path: folder.path,
|
|
|
|
});
|
|
|
|
data.folders.push(res.body.data);
|
|
|
|
});
|
|
|
|
|
2022-05-02 16:31:27 +02:00
|
|
|
test('cannot move and rename a folder if duplicated', async () => {
|
2022-04-29 09:51:55 +02:00
|
|
|
const folder0 = await createFolder('folder-a-0', null);
|
|
|
|
const folder1 = await createFolder('folder-a-1', null);
|
2022-05-02 10:35:48 +02:00
|
|
|
const folder00 = await createFolder('folder-a-00', folder0.id);
|
|
|
|
data.folders.push(folder0, folder1, folder00);
|
2022-04-29 09:51:55 +02:00
|
|
|
|
|
|
|
const res = await rq({
|
|
|
|
method: 'PUT',
|
|
|
|
url: `/upload/folders/${folder1.id}`,
|
|
|
|
body: {
|
|
|
|
name: 'folder-a-00',
|
|
|
|
parent: folder0.id,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(res.status).toBe(400);
|
2022-05-02 16:31:27 +02:00
|
|
|
expect(res.body.error.message).toBe('folder 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('folder already exists');
|
2022-04-29 09:51:55 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
test('cannot move a folder to a folder that does not exist', async () => {
|
2022-05-02 16:31:27 +02:00
|
|
|
const folder = await createFolder('folder-c-0', null);
|
2022-05-02 10:35:48 +02:00
|
|
|
data.folders.push(folder);
|
2022-04-29 09:51:55 +02:00
|
|
|
|
|
|
|
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('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.uid}`,
|
|
|
|
});
|
|
|
|
|
|
|
|
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.results[0]).toMatchObject({ path: folder0.path, parent: null });
|
|
|
|
expect(resFolders.body.results[1]).toMatchObject({
|
|
|
|
path: `${folder01.path}/${folder00.uid}`,
|
|
|
|
parent: { id: folder01.id },
|
|
|
|
});
|
|
|
|
expect(resFolders.body.results[2]).toMatchObject({
|
|
|
|
path: folder01.path,
|
|
|
|
parent: { id: folder0.id },
|
|
|
|
});
|
|
|
|
expect(resFolders.body.results[3]).toMatchObject({
|
|
|
|
path: folder02.path,
|
|
|
|
parent: { id: folder0.id },
|
|
|
|
});
|
|
|
|
expect(resFolders.body.results[4]).toMatchObject({
|
|
|
|
path: `${folder01.path}/${folder00.uid}/${folder000.uid}`,
|
|
|
|
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.uid}/${folder000.uid}`,
|
|
|
|
});
|
|
|
|
expect(resFiles.body.results[1]).toMatchObject({ folderPath: file02.folderPath });
|
|
|
|
|
|
|
|
data.folders.push(...resFolders.body.results);
|
|
|
|
});
|
|
|
|
|
|
|
|
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.uid}`,
|
|
|
|
});
|
|
|
|
|
|
|
|
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.results[0]).toMatchObject({ path: folder0.path, parent: null });
|
|
|
|
expect(resFolders.body.results[1]).toMatchObject({
|
|
|
|
path: `/${folder00.uid}`,
|
|
|
|
parent: null,
|
|
|
|
});
|
|
|
|
expect(resFolders.body.results[2]).toMatchObject({
|
|
|
|
path: folder02.path,
|
|
|
|
parent: { id: folder0.id },
|
|
|
|
});
|
|
|
|
expect(resFolders.body.results[3]).toMatchObject({
|
|
|
|
path: `/${folder00.uid}/${folder000.uid}`,
|
|
|
|
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.uid}/${folder000.uid}`,
|
|
|
|
});
|
|
|
|
expect(resFiles.body.results[1]).toMatchObject({ folderPath: file02.folderPath });
|
|
|
|
|
|
|
|
data.folders.push(...resFolders.body.results);
|
|
|
|
});
|
|
|
|
});
|
2022-03-22 18:19:46 +01:00
|
|
|
});
|