mirror of
				https://github.com/strapi/strapi.git
				synced 2025-10-31 01:47:13 +00:00 
			
		
		
		
	add ability to set and change file folder location
This commit is contained in:
		
							parent
							
								
									fd5d1c2fdc
								
							
						
					
					
						commit
						a44e2cd25e
					
				| @ -2,7 +2,7 @@ | |||||||
| 
 | 
 | ||||||
| const { getService } = require('../utils'); | const { getService } = require('../utils'); | ||||||
| const { ACTIONS } = require('../constants'); | const { ACTIONS } = require('../constants'); | ||||||
| const findEntityAndCheckPermissions = require('./utils/find-entity-and-check-permissions'); | const { findEntityAndCheckPermissions } = require('./utils/find-entity-and-check-permissions'); | ||||||
| 
 | 
 | ||||||
| const fileModel = 'plugin::upload.file'; | const fileModel = 'plugin::upload.file'; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -42,11 +42,10 @@ module.exports = { | |||||||
| 
 | 
 | ||||||
|     const existingFolders = await strapi.entityService.findMany(folderModel, { |     const existingFolders = await strapi.entityService.findMany(folderModel, { | ||||||
|       filters: { |       filters: { | ||||||
|         parent: body.parent, |         parent: body.parent || null, | ||||||
|         name: body.name, |         name: body.name, | ||||||
|       }, |       }, | ||||||
|     }); |     }); | ||||||
| 
 |  | ||||||
|     if (existingFolders.length > 0) { |     if (existingFolders.length > 0) { | ||||||
|       throw new ApplicationError('name already taken'); |       throw new ApplicationError('name already taken'); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -5,7 +5,7 @@ const { ApplicationError } = require('@strapi/utils').errors; | |||||||
| const { getService } = require('../utils'); | const { getService } = require('../utils'); | ||||||
| const { ACTIONS } = require('../constants'); | const { ACTIONS } = require('../constants'); | ||||||
| const validateUploadBody = require('./validation/upload'); | const validateUploadBody = require('./validation/upload'); | ||||||
| const findEntityAndCheckPermissions = require('./utils/find-entity-and-check-permissions'); | const { findEntityAndCheckPermissions } = require('./utils/find-entity-and-check-permissions'); | ||||||
| 
 | 
 | ||||||
| const fileModel = 'plugin::upload.file'; | const fileModel = 'plugin::upload.file'; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ const { getService } = require('../../utils'); | |||||||
| const { CREATED_BY_ATTRIBUTE } = contentTypesUtils.constants; | const { CREATED_BY_ATTRIBUTE } = contentTypesUtils.constants; | ||||||
| 
 | 
 | ||||||
| const findEntityAndCheckPermissions = async (ability, action, model, id) => { | const findEntityAndCheckPermissions = async (ability, action, model, id) => { | ||||||
|   const file = await getService('upload').findOne(id, [CREATED_BY_ATTRIBUTE]); |   const file = await getService('upload').findOne(id, [CREATED_BY_ATTRIBUTE, 'folder']); | ||||||
| 
 | 
 | ||||||
|   if (_.isNil(file)) { |   if (_.isNil(file)) { | ||||||
|     throw new NotFoundError(); |     throw new NotFoundError(); | ||||||
|  | |||||||
| @ -6,6 +6,7 @@ const fileInfoSchema = yup.object({ | |||||||
|   name: yup.string().nullable(), |   name: yup.string().nullable(), | ||||||
|   alternativeText: yup.string().nullable(), |   alternativeText: yup.string().nullable(), | ||||||
|   caption: yup.string().nullable(), |   caption: yup.string().nullable(), | ||||||
|  |   folder: yup.strapiID().nullable(), | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| const uploadSchema = yup.object({ | const uploadSchema = yup.object({ | ||||||
|  | |||||||
| @ -45,7 +45,7 @@ module.exports = ({ strapi }) => { | |||||||
|   const formatFile = async (upload, extraInfo, metas) => { |   const formatFile = async (upload, extraInfo, metas) => { | ||||||
|     const uploadService = getUploadService('upload'); |     const uploadService = getUploadService('upload'); | ||||||
|     const { filename, mimetype, createReadStream } = await upload; |     const { filename, mimetype, createReadStream } = await upload; | ||||||
|     const currentFile = uploadService.formatFileInfo( |     const currentFile = await uploadService.formatFileInfo( | ||||||
|       { |       { | ||||||
|         filename, |         filename, | ||||||
|         type: mimetype, |         type: mimetype, | ||||||
|  | |||||||
							
								
								
									
										25
									
								
								packages/core/upload/server/services/__tests__/file.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								packages/core/upload/server/services/__tests__/file.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | |||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | const { getPath } = require('../file'); | ||||||
|  | 
 | ||||||
|  | describe('file', () => { | ||||||
|  |   describe('getPath', () => { | ||||||
|  |     beforeAll(() => { | ||||||
|  |       global.strapi = { | ||||||
|  |         entityService: { | ||||||
|  |           findOne: jest.fn(() => ({ path: '/parent-path' })), | ||||||
|  |         }, | ||||||
|  |       }; | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     test.each([ | ||||||
|  |       [[1, 'myFile.txt'], '/parent-path/myFile.txt'], | ||||||
|  |       [[undefined, 'myFile.txt'], '/myFile.txt'], | ||||||
|  |       [[null, 'myFile.txt'], '/myFile.txt'], | ||||||
|  |     ])('inputs %s should give %s', async (args, expectedResult) => { | ||||||
|  |       const result = await getPath(...args); | ||||||
|  | 
 | ||||||
|  |       expect(result).toBe(expectedResult); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
| @ -0,0 +1,33 @@ | |||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | const { setPathAndUID } = require('../folder'); | ||||||
|  | 
 | ||||||
|  | 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; | ||||||
|  | 
 | ||||||
|  | describe('folder', () => { | ||||||
|  |   describe('setPathAndUID', () => { | ||||||
|  |     beforeAll(() => { | ||||||
|  |       global.strapi = { | ||||||
|  |         entityService: { | ||||||
|  |           findOne: jest.fn(() => ({ path: '/parent-path' })), | ||||||
|  |         }, | ||||||
|  |       }; | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     test.each([ | ||||||
|  |       [{ parent: 1, name: 'myFile.txt' }, '/parent-path/myFile.txt'], | ||||||
|  |       [{ name: 'myFile.txt' }, '/myFile.txt'], | ||||||
|  |       [{ parent: null, name: 'myFile.txt' }, '/myFile.txt'], | ||||||
|  |     ])('inputs %s', async (folder, expectedPath) => { | ||||||
|  |       const clonedFolder = { ...folder }; | ||||||
|  |       const result = await setPathAndUID(clonedFolder); | ||||||
|  | 
 | ||||||
|  |       expect(result).toBe(clonedFolder); | ||||||
|  |       expect(result).toMatchObject({ | ||||||
|  |         ...folder, | ||||||
|  |         uid: expect.stringMatching(uuidRegex), | ||||||
|  |         path: expectedPath, | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
| @ -4,14 +4,14 @@ const uploadService = require('../upload')({}); | |||||||
| 
 | 
 | ||||||
| describe('Upload service', () => { | describe('Upload service', () => { | ||||||
|   describe('formatFileInfo', () => { |   describe('formatFileInfo', () => { | ||||||
|     test('Generates hash', () => { |     test('Generates hash', async () => { | ||||||
|       const fileData = { |       const fileData = { | ||||||
|         filename: 'File Name.png', |         filename: 'File Name.png', | ||||||
|         type: 'image/png', |         type: 'image/png', | ||||||
|         size: 1000 * 1000, |         size: 1000 * 1000, | ||||||
|       }; |       }; | ||||||
| 
 | 
 | ||||||
|       expect(uploadService.formatFileInfo(fileData)).toMatchObject({ |       expect(await uploadService.formatFileInfo(fileData)).toMatchObject({ | ||||||
|         name: 'File Name.png', |         name: 'File Name.png', | ||||||
|         hash: expect.stringContaining('File_Name'), |         hash: expect.stringContaining('File_Name'), | ||||||
|         ext: '.png', |         ext: '.png', | ||||||
| @ -20,14 +20,14 @@ describe('Upload service', () => { | |||||||
|       }); |       }); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     test('Replaces reserved and unsafe characters for URLs and files in hash', () => { |     test('Replaces reserved and unsafe characters for URLs and files in hash', async () => { | ||||||
|       const fileData = { |       const fileData = { | ||||||
|         filename: 'File%&Näme<>:"|?*.png', |         filename: 'File%&Näme<>:"|?*.png', | ||||||
|         type: 'image/png', |         type: 'image/png', | ||||||
|         size: 1000 * 1000, |         size: 1000 * 1000, | ||||||
|       }; |       }; | ||||||
| 
 | 
 | ||||||
|       expect(uploadService.formatFileInfo(fileData)).toMatchObject({ |       expect(await uploadService.formatFileInfo(fileData)).toMatchObject({ | ||||||
|         name: 'File%&Näme<>:"|?*.png', |         name: 'File%&Näme<>:"|?*.png', | ||||||
|         hash: expect.stringContaining('File_and_Naeme'), |         hash: expect.stringContaining('File_and_Naeme'), | ||||||
|         ext: '.png', |         ext: '.png', | ||||||
| @ -36,7 +36,7 @@ describe('Upload service', () => { | |||||||
|       }); |       }); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     test('Overrides name with fileInfo', () => { |     test('Overrides name with fileInfo', async () => { | ||||||
|       const fileData = { |       const fileData = { | ||||||
|         filename: 'File Name.png', |         filename: 'File Name.png', | ||||||
|         type: 'image/png', |         type: 'image/png', | ||||||
| @ -47,7 +47,7 @@ describe('Upload service', () => { | |||||||
|         name: 'Custom File Name.png', |         name: 'Custom File Name.png', | ||||||
|       }; |       }; | ||||||
| 
 | 
 | ||||||
|       expect(uploadService.formatFileInfo(fileData, fileInfo)).toMatchObject({ |       expect(await uploadService.formatFileInfo(fileData, fileInfo)).toMatchObject({ | ||||||
|         name: fileInfo.name, |         name: fileInfo.name, | ||||||
|         hash: expect.stringContaining('Custom_File_Name'), |         hash: expect.stringContaining('Custom_File_Name'), | ||||||
|         ext: '.png', |         ext: '.png', | ||||||
| @ -56,7 +56,7 @@ describe('Upload service', () => { | |||||||
|       }); |       }); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     test('Sets alternativeText and caption', () => { |     test('Sets alternativeText and caption', async () => { | ||||||
|       const fileData = { |       const fileData = { | ||||||
|         filename: 'File Name.png', |         filename: 'File Name.png', | ||||||
|         type: 'image/png', |         type: 'image/png', | ||||||
| @ -68,7 +68,7 @@ describe('Upload service', () => { | |||||||
|         caption: 'caption this', |         caption: 'caption this', | ||||||
|       }; |       }; | ||||||
| 
 | 
 | ||||||
|       expect(uploadService.formatFileInfo(fileData, fileInfo)).toMatchObject({ |       expect(await uploadService.formatFileInfo(fileData, fileInfo)).toMatchObject({ | ||||||
|         name: 'File Name.png', |         name: 'File Name.png', | ||||||
|         caption: fileInfo.caption, |         caption: fileInfo.caption, | ||||||
|         alternativeText: fileInfo.alternativeText, |         alternativeText: fileInfo.alternativeText, | ||||||
| @ -79,7 +79,7 @@ describe('Upload service', () => { | |||||||
|       }); |       }); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     test('Set a path folder', () => { |     test('Set a path folder', async () => { | ||||||
|       const fileData = { |       const fileData = { | ||||||
|         filename: 'File Name.png', |         filename: 'File Name.png', | ||||||
|         type: 'image/png', |         type: 'image/png', | ||||||
| @ -90,7 +90,7 @@ describe('Upload service', () => { | |||||||
|         path: 'folder', |         path: 'folder', | ||||||
|       }; |       }; | ||||||
| 
 | 
 | ||||||
|       expect(uploadService.formatFileInfo(fileData, {}, fileMetas)).toMatchObject({ |       expect(await uploadService.formatFileInfo(fileData, {}, fileMetas)).toMatchObject({ | ||||||
|         name: 'File Name.png', |         name: 'File Name.png', | ||||||
|         ext: '.png', |         ext: '.png', | ||||||
|         mime: 'image/png', |         mime: 'image/png', | ||||||
|  | |||||||
							
								
								
									
										32
									
								
								packages/core/upload/server/services/file.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								packages/core/upload/server/services/file.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | |||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | const { trimChars, trimCharsEnd, trimCharsStart } = require('lodash/fp'); | ||||||
|  | 
 | ||||||
|  | // TODO: to use once https://github.com/strapi/strapi/pull/12534 is merged
 | ||||||
|  | // const { joinBy } = require('@strapi/utils');
 | ||||||
|  | 
 | ||||||
|  | const folderModel = 'plugin::upload.folder'; | ||||||
|  | 
 | ||||||
|  | const joinBy = (joint, ...args) => { | ||||||
|  |   const trim = trimChars(joint); | ||||||
|  |   const trimEnd = trimCharsEnd(joint); | ||||||
|  |   const trimStart = trimCharsStart(joint); | ||||||
|  | 
 | ||||||
|  |   return args.reduce((url, path, index) => { | ||||||
|  |     if (args.length === 1) return path; | ||||||
|  |     if (index === 0) return trimEnd(path); | ||||||
|  |     if (index === args.length - 1) return url + joint + trimStart(path); | ||||||
|  |     return url + joint + trim(path); | ||||||
|  |   }, ''); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const getPath = async (folderId, fileName) => { | ||||||
|  |   if (!folderId) return joinBy('/', '/', fileName); | ||||||
|  | 
 | ||||||
|  |   const parentFolder = await strapi.entityService.findOne(folderModel, folderId); | ||||||
|  |   return joinBy('/', parentFolder.path, fileName); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | module.exports = { | ||||||
|  |   getPath, | ||||||
|  | }; | ||||||
| @ -37,6 +37,5 @@ const setPathAndUID = async folder => { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| module.exports = { | module.exports = { | ||||||
|   generateUID, |  | ||||||
|   setPathAndUID, |   setPathAndUID, | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -4,10 +4,12 @@ const provider = require('./provider'); | |||||||
| const upload = require('./upload'); | const upload = require('./upload'); | ||||||
| const imageManipulation = require('./image-manipulation'); | const imageManipulation = require('./image-manipulation'); | ||||||
| const folder = require('./folder'); | const folder = require('./folder'); | ||||||
|  | const file = require('./file'); | ||||||
| 
 | 
 | ||||||
| module.exports = { | module.exports = { | ||||||
|   provider, |   provider, | ||||||
|   upload, |   upload, | ||||||
|   folder, |   folder, | ||||||
|  |   file, | ||||||
|   'image-manipulation': imageManipulation, |   'image-manipulation': imageManipulation, | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -63,16 +63,19 @@ module.exports = ({ strapi }) => ({ | |||||||
|     strapi.eventHub.emit(event, { media: sanitizedData }); |     strapi.eventHub.emit(event, { media: sanitizedData }); | ||||||
|   }, |   }, | ||||||
| 
 | 
 | ||||||
|   formatFileInfo({ filename, type, size }, fileInfo = {}, metas = {}) { |   async formatFileInfo({ filename, type, size }, fileInfo = {}, metas = {}) { | ||||||
|  |     const fileService = getService('file'); | ||||||
|  | 
 | ||||||
|     const ext = path.extname(filename); |     const ext = path.extname(filename); | ||||||
|     const basename = path.basename(fileInfo.name || filename, ext); |     const basename = path.basename(fileInfo.name || filename, ext); | ||||||
| 
 |  | ||||||
|     const usedName = fileInfo.name || filename; |     const usedName = fileInfo.name || filename; | ||||||
| 
 | 
 | ||||||
|     const entity = { |     const entity = { | ||||||
|       name: usedName, |       name: usedName, | ||||||
|       alternativeText: fileInfo.alternativeText, |       alternativeText: fileInfo.alternativeText, | ||||||
|       caption: fileInfo.caption, |       caption: fileInfo.caption, | ||||||
|  |       folder: fileInfo.folder, | ||||||
|  |       path: await fileService.getPath(fileInfo.folder, usedName), | ||||||
|       hash: generateFileName(basename), |       hash: generateFileName(basename), | ||||||
|       ext, |       ext, | ||||||
|       mime: type, |       mime: type, | ||||||
| @ -103,7 +106,7 @@ module.exports = ({ strapi }) => ({ | |||||||
|   }, |   }, | ||||||
| 
 | 
 | ||||||
|   async enhanceFile(file, fileInfo = {}, metas = {}) { |   async enhanceFile(file, fileInfo = {}, metas = {}) { | ||||||
|     const currentFile = this.formatFileInfo( |     const currentFile = await this.formatFileInfo( | ||||||
|       { |       { | ||||||
|         filename: file.name, |         filename: file.name, | ||||||
|         type: file.type, |         type: file.type, | ||||||
| @ -198,17 +201,22 @@ module.exports = ({ strapi }) => ({ | |||||||
|     return this.add(fileData, { user }); |     return this.add(fileData, { user }); | ||||||
|   }, |   }, | ||||||
| 
 | 
 | ||||||
|   async updateFileInfo(id, { name, alternativeText, caption }, { user } = {}) { |   async updateFileInfo(id, { name, alternativeText, caption, folder }, { user } = {}) { | ||||||
|     const dbFile = await this.findOne(id); |     const dbFile = await this.findOne(id); | ||||||
| 
 | 
 | ||||||
|     if (!dbFile) { |     if (!dbFile) { | ||||||
|       throw new NotFoundError(); |       throw new NotFoundError(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     const fileService = getService('file'); | ||||||
|  | 
 | ||||||
|  |     const newName = _.isNil(name) ? dbFile.name : name; | ||||||
|     const newInfos = { |     const newInfos = { | ||||||
|       name: _.isNil(name) ? dbFile.name : name, |       name: newName, | ||||||
|       alternativeText: _.isNil(alternativeText) ? dbFile.alternativeText : alternativeText, |       alternativeText: _.isNil(alternativeText) ? dbFile.alternativeText : alternativeText, | ||||||
|       caption: _.isNil(caption) ? dbFile.caption : caption, |       caption: _.isNil(caption) ? dbFile.caption : caption, | ||||||
|  |       folder: _.isUndefined(folder) ? dbFile.folder : folder, | ||||||
|  |       path: _.isUndefined(folder) ? dbFile.path : await fileService.getPath(folder, newName), | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     return this.update(id, newInfos, { user }); |     return this.update(id, newInfos, { user }); | ||||||
| @ -222,7 +230,6 @@ module.exports = ({ strapi }) => ({ | |||||||
|     ); |     ); | ||||||
| 
 | 
 | ||||||
|     const dbFile = await this.findOne(id); |     const dbFile = await this.findOne(id); | ||||||
| 
 |  | ||||||
|     if (!dbFile) { |     if (!dbFile) { | ||||||
|       throw new NotFoundError(); |       throw new NotFoundError(); | ||||||
|     } |     } | ||||||
| @ -236,7 +243,7 @@ module.exports = ({ strapi }) => ({ | |||||||
|       const { fileInfo } = data; |       const { fileInfo } = data; | ||||||
|       fileData = await this.enhanceFile(file, fileInfo); |       fileData = await this.enhanceFile(file, fileInfo); | ||||||
| 
 | 
 | ||||||
|       // keep a constant hash
 |       // keep a constant hash and extension so the file url doesn't change when the file is replaced
 | ||||||
|       _.assign(fileData, { |       _.assign(fileData, { | ||||||
|         hash: dbFile.hash, |         hash: dbFile.hash, | ||||||
|         ext: dbFile.ext, |         ext: dbFile.ext, | ||||||
|  | |||||||
							
								
								
									
										330
									
								
								packages/core/upload/tests/admin/file.test.e2e.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										330
									
								
								packages/core/upload/tests/admin/file.test.e2e.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,330 @@ | |||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | const fs = require('fs'); | ||||||
|  | const path = require('path'); | ||||||
|  | 
 | ||||||
|  | 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: [], | ||||||
|  |   files: [], | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | describe('File', () => { | ||||||
|  |   const builder = createTestBuilder(); | ||||||
|  | 
 | ||||||
|  |   beforeAll(async () => { | ||||||
|  |     strapi = await createStrapiInstance(); | ||||||
|  |     rq = await createAuthRequest({ strapi }); | ||||||
|  | 
 | ||||||
|  |     // create 2 folders
 | ||||||
|  |     for (let i = 1; i <= 2; i += 1) { | ||||||
|  |       const folderRes = await rq({ | ||||||
|  |         method: 'POST', | ||||||
|  |         url: '/upload/folders', | ||||||
|  |         body: { name: `folder ${i}` }, | ||||||
|  |       }); | ||||||
|  |       data.folders.push(folderRes.body.data); | ||||||
|  |     } | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   afterAll(async () => { | ||||||
|  |     await strapi.destroy(); | ||||||
|  |     await builder.cleanup(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   describe('create', () => { | ||||||
|  |     test('Can create a file at root level', async () => { | ||||||
|  |       const res = await rq({ | ||||||
|  |         method: 'POST', | ||||||
|  |         url: '/upload', | ||||||
|  |         formData: { | ||||||
|  |           files: fs.createReadStream(path.join(__dirname, '../utils/rec.jpg')), | ||||||
|  |         }, | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect(res.statusCode).toBe(200); | ||||||
|  |       expect(Array.isArray(res.body)).toBe(true); | ||||||
|  |       expect(res.body.length).toBe(1); | ||||||
|  | 
 | ||||||
|  |       const { body: file } = await rq({ | ||||||
|  |         method: 'GET', | ||||||
|  |         url: `/upload/files/${res.body[0].id}`, | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect(file).toMatchObject({ | ||||||
|  |         id: expect.anything(), | ||||||
|  |         name: 'rec.jpg', | ||||||
|  |         ext: '.jpg', | ||||||
|  |         mime: 'image/jpeg', | ||||||
|  |         hash: expect.any(String), | ||||||
|  |         size: expect.any(Number), | ||||||
|  |         width: expect.any(Number), | ||||||
|  |         height: expect.any(Number), | ||||||
|  |         url: expect.any(String), | ||||||
|  |         provider: 'local', | ||||||
|  |         path: '/rec.jpg', | ||||||
|  |         folder: null, | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       data.files.push(file); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     test('Can create a file inside a folder', async () => { | ||||||
|  |       const res = await rq({ | ||||||
|  |         method: 'POST', | ||||||
|  |         url: '/upload', | ||||||
|  |         formData: { | ||||||
|  |           files: fs.createReadStream(path.join(__dirname, '../utils/rec.jpg')), | ||||||
|  |           fileInfo: JSON.stringify({ | ||||||
|  |             folder: data.folders[0].id, | ||||||
|  |           }), | ||||||
|  |         }, | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect(res.statusCode).toBe(200); | ||||||
|  |       expect(Array.isArray(res.body)).toBe(true); | ||||||
|  |       expect(res.body.length).toBe(1); | ||||||
|  | 
 | ||||||
|  |       const { body: file } = await rq({ | ||||||
|  |         method: 'GET', | ||||||
|  |         url: `/upload/files/${res.body[0].id}`, | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect(file).toMatchObject({ | ||||||
|  |         id: expect.anything(), | ||||||
|  |         name: 'rec.jpg', | ||||||
|  |         ext: '.jpg', | ||||||
|  |         mime: 'image/jpeg', | ||||||
|  |         hash: expect.any(String), | ||||||
|  |         size: expect.any(Number), | ||||||
|  |         width: expect.any(Number), | ||||||
|  |         height: expect.any(Number), | ||||||
|  |         url: expect.any(String), | ||||||
|  |         provider: 'local', | ||||||
|  |         path: '/folder 1/rec.jpg', | ||||||
|  |         folder: { id: 1 }, | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       data.files.push(file); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   describe('Update info', () => { | ||||||
|  |     describe('Move a file from a folder to another folder', () => { | ||||||
|  |       test('when replacing the file', async () => { | ||||||
|  |         const res = await rq({ | ||||||
|  |           method: 'POST', | ||||||
|  |           url: `/upload?id=${data.files[1].id}`, | ||||||
|  |           formData: { | ||||||
|  |             files: fs.createReadStream(path.join(__dirname, '../utils/rec.pdf')), | ||||||
|  |             fileInfo: JSON.stringify({ folder: data.folders[1].id }), | ||||||
|  |           }, | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         expect(res.statusCode).toBe(200); | ||||||
|  |         expect(res.body).toMatchObject({ id: data.files[1].id }); | ||||||
|  | 
 | ||||||
|  |         const { body: file } = await rq({ | ||||||
|  |           method: 'GET', | ||||||
|  |           url: `/upload/files/${res.body.id}`, | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         expect(file).toMatchObject({ | ||||||
|  |           id: expect.anything(), | ||||||
|  |           name: 'rec.pdf', | ||||||
|  |           ext: '.jpg', | ||||||
|  |           mime: 'application/pdf', | ||||||
|  |           hash: expect.any(String), | ||||||
|  |           size: expect.any(Number), | ||||||
|  |           width: expect.any(Number), | ||||||
|  |           height: expect.any(Number), | ||||||
|  |           url: expect.any(String), | ||||||
|  |           provider: 'local', | ||||||
|  |           path: '/folder 2/rec.pdf', | ||||||
|  |           folder: { id: data.folders[1].id }, | ||||||
|  |         }); | ||||||
|  |         data.files[1] = file; | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       test('without replacing the file', async () => { | ||||||
|  |         const res = await rq({ | ||||||
|  |           method: 'POST', | ||||||
|  |           url: `/upload?id=${data.files[1].id}`, | ||||||
|  |           formData: { | ||||||
|  |             fileInfo: JSON.stringify({ folder: data.folders[0].id }), | ||||||
|  |           }, | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         expect(res.statusCode).toBe(200); | ||||||
|  |         expect(res.body).toMatchObject({ id: data.files[1].id }); | ||||||
|  | 
 | ||||||
|  |         const { body: file } = await rq({ | ||||||
|  |           method: 'GET', | ||||||
|  |           url: `/upload/files/${res.body.id}`, | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         expect(file).toMatchObject({ | ||||||
|  |           id: expect.anything(), | ||||||
|  |           name: 'rec.pdf', | ||||||
|  |           ext: '.jpg', | ||||||
|  |           mime: 'application/pdf', | ||||||
|  |           hash: expect.any(String), | ||||||
|  |           size: expect.any(Number), | ||||||
|  |           width: expect.any(Number), | ||||||
|  |           height: expect.any(Number), | ||||||
|  |           url: expect.any(String), | ||||||
|  |           provider: 'local', | ||||||
|  |           path: '/folder 1/rec.pdf', | ||||||
|  |           folder: { id: data.folders[0].id }, | ||||||
|  |         }); | ||||||
|  |         data.files[1] = file; | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  |     describe('Move a file from root level to a folder', () => { | ||||||
|  |       test('when replacing the file', async () => { | ||||||
|  |         const res = await rq({ | ||||||
|  |           method: 'POST', | ||||||
|  |           url: `/upload?id=${data.files[0].id}`, | ||||||
|  |           formData: { | ||||||
|  |             files: fs.createReadStream(path.join(__dirname, '../utils/rec.pdf')), | ||||||
|  |             fileInfo: JSON.stringify({ folder: data.folders[0].id }), | ||||||
|  |           }, | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         expect(res.statusCode).toBe(200); | ||||||
|  |         expect(res.body).toMatchObject({ id: data.files[0].id }); | ||||||
|  | 
 | ||||||
|  |         const { body: file } = await rq({ | ||||||
|  |           method: 'GET', | ||||||
|  |           url: `/upload/files/${res.body.id}`, | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         expect(file).toMatchObject({ | ||||||
|  |           id: expect.anything(), | ||||||
|  |           name: 'rec.pdf', | ||||||
|  |           ext: '.jpg', | ||||||
|  |           mime: 'application/pdf', | ||||||
|  |           hash: expect.any(String), | ||||||
|  |           size: expect.any(Number), | ||||||
|  |           width: expect.any(Number), | ||||||
|  |           height: expect.any(Number), | ||||||
|  |           url: expect.any(String), | ||||||
|  |           provider: 'local', | ||||||
|  |           path: '/folder 1/rec.pdf', | ||||||
|  |           folder: { id: data.folders[0].id }, | ||||||
|  |         }); | ||||||
|  |         data.files[0] = file; | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       test('without replacing the file', async () => { | ||||||
|  |         const res = await rq({ | ||||||
|  |           method: 'POST', | ||||||
|  |           url: `/upload?id=${data.files[1].id}`, | ||||||
|  |           formData: { | ||||||
|  |             fileInfo: JSON.stringify({ folder: data.folders[1].id }), | ||||||
|  |           }, | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         expect(res.statusCode).toBe(200); | ||||||
|  |         expect(res.body).toMatchObject({ id: data.files[1].id }); | ||||||
|  | 
 | ||||||
|  |         const { body: file } = await rq({ | ||||||
|  |           method: 'GET', | ||||||
|  |           url: `/upload/files/${res.body.id}`, | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         expect(file).toMatchObject({ | ||||||
|  |           id: expect.anything(), | ||||||
|  |           name: 'rec.pdf', | ||||||
|  |           ext: '.jpg', | ||||||
|  |           mime: 'application/pdf', | ||||||
|  |           hash: expect.any(String), | ||||||
|  |           size: expect.any(Number), | ||||||
|  |           width: expect.any(Number), | ||||||
|  |           height: expect.any(Number), | ||||||
|  |           url: expect.any(String), | ||||||
|  |           provider: 'local', | ||||||
|  |           path: '/folder 2/rec.pdf', | ||||||
|  |           folder: { id: data.folders[1].id }, | ||||||
|  |         }); | ||||||
|  |         data.files[1] = file; | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     describe('Move a file from folder to the root level', () => { | ||||||
|  |       test('when replacing the file', async () => { | ||||||
|  |         const res = await rq({ | ||||||
|  |           method: 'POST', | ||||||
|  |           url: `/upload?id=${data.files[0].id}`, | ||||||
|  |           formData: { | ||||||
|  |             files: fs.createReadStream(path.join(__dirname, '../utils/rec.jpg')), | ||||||
|  |             fileInfo: JSON.stringify({ folder: null }), | ||||||
|  |           }, | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         expect(res.statusCode).toBe(200); | ||||||
|  |         expect(res.body).toMatchObject({ id: data.files[0].id }); | ||||||
|  | 
 | ||||||
|  |         const { body: file } = await rq({ | ||||||
|  |           method: 'GET', | ||||||
|  |           url: `/upload/files/${res.body.id}`, | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         expect(file).toMatchObject({ | ||||||
|  |           id: expect.anything(), | ||||||
|  |           name: 'rec.jpg', | ||||||
|  |           ext: '.jpg', | ||||||
|  |           mime: 'image/jpeg', | ||||||
|  |           hash: expect.any(String), | ||||||
|  |           size: expect.any(Number), | ||||||
|  |           width: expect.any(Number), | ||||||
|  |           height: expect.any(Number), | ||||||
|  |           url: expect.any(String), | ||||||
|  |           provider: 'local', | ||||||
|  |           path: '/rec.jpg', | ||||||
|  |           folder: null, | ||||||
|  |         }); | ||||||
|  |         data.files[0] = file; | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       test('without replacing the file', async () => { | ||||||
|  |         const res = await rq({ | ||||||
|  |           method: 'POST', | ||||||
|  |           url: `/upload?id=${data.files[1].id}`, | ||||||
|  |           formData: { | ||||||
|  |             fileInfo: JSON.stringify({ folder: null }), | ||||||
|  |           }, | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         expect(res.statusCode).toBe(200); | ||||||
|  |         expect(res.body).toMatchObject({ id: data.files[1].id }); | ||||||
|  | 
 | ||||||
|  |         const { body: file } = await rq({ | ||||||
|  |           method: 'GET', | ||||||
|  |           url: `/upload/files/${res.body.id}`, | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         expect(file).toMatchObject({ | ||||||
|  |           id: expect.anything(), | ||||||
|  |           name: 'rec.pdf', | ||||||
|  |           ext: '.jpg', | ||||||
|  |           mime: 'application/pdf', | ||||||
|  |           hash: expect.any(String), | ||||||
|  |           size: expect.any(Number), | ||||||
|  |           width: expect.any(Number), | ||||||
|  |           height: expect.any(Number), | ||||||
|  |           url: expect.any(String), | ||||||
|  |           provider: 'local', | ||||||
|  |           path: '/rec.pdf', | ||||||
|  |           folder: null, | ||||||
|  |         }); | ||||||
|  |         data.files[1] = file; | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
| @ -45,7 +45,7 @@ describe('Upload plugin end to end tests', () => { | |||||||
|       map: JSON.stringify({ |       map: JSON.stringify({ | ||||||
|         nFile1: ['variables.file'], |         nFile1: ['variables.file'], | ||||||
|       }), |       }), | ||||||
|       nFile1: fs.createReadStream(path.join(__dirname, '/rec.jpg')), |       nFile1: fs.createReadStream(path.join(__dirname, '../utils/rec.jpg')), | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     const res = await rq({ method: 'POST', url: '/graphql', formData }); |     const res = await rq({ method: 'POST', url: '/graphql', formData }); | ||||||
| @ -94,8 +94,8 @@ describe('Upload plugin end to end tests', () => { | |||||||
|         nFile0: ['variables.files.0'], |         nFile0: ['variables.files.0'], | ||||||
|         nFile1: ['variables.files.1'], |         nFile1: ['variables.files.1'], | ||||||
|       }), |       }), | ||||||
|       nFile0: fs.createReadStream(path.join(__dirname, '/rec.jpg')), |       nFile0: fs.createReadStream(path.join(__dirname, '../utils/rec.jpg')), | ||||||
|       nFile1: fs.createReadStream(path.join(__dirname, '/rec.jpg')), |       nFile1: fs.createReadStream(path.join(__dirname, '../utils/rec.jpg')), | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     const res = await rq({ method: 'POST', url: '/graphql', formData }); |     const res = await rq({ method: 'POST', url: '/graphql', formData }); | ||||||
| @ -144,7 +144,7 @@ describe('Upload plugin end to end tests', () => { | |||||||
|       map: JSON.stringify({ |       map: JSON.stringify({ | ||||||
|         nFile1: ['variables.file'], |         nFile1: ['variables.file'], | ||||||
|       }), |       }), | ||||||
|       nFile1: fs.createReadStream(path.join(__dirname, '/rec.pdf')), |       nFile1: fs.createReadStream(path.join(__dirname, '../utils/rec.pdf')), | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     const res = await rq({ method: 'POST', url: '/graphql', formData }); |     const res = await rq({ method: 'POST', url: '/graphql', formData }); | ||||||
| @ -193,8 +193,8 @@ describe('Upload plugin end to end tests', () => { | |||||||
|         nFile0: ['variables.files.0'], |         nFile0: ['variables.files.0'], | ||||||
|         nFile1: ['variables.files.1'], |         nFile1: ['variables.files.1'], | ||||||
|       }), |       }), | ||||||
|       nFile0: fs.createReadStream(path.join(__dirname, '/rec.pdf')), |       nFile0: fs.createReadStream(path.join(__dirname, '../utils/rec.pdf')), | ||||||
|       nFile1: fs.createReadStream(path.join(__dirname, '/rec.pdf')), |       nFile1: fs.createReadStream(path.join(__dirname, '../utils/rec.pdf')), | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     const res = await rq({ method: 'POST', url: '/graphql', formData }); |     const res = await rq({ method: 'POST', url: '/graphql', formData }); | ||||||
| @ -354,7 +354,7 @@ describe('Upload plugin end to end tests', () => { | |||||||
|       map: JSON.stringify({ |       map: JSON.stringify({ | ||||||
|         nFile1: ['variables.file'], |         nFile1: ['variables.file'], | ||||||
|       }), |       }), | ||||||
|       nFile1: fs.createReadStream(path.join(__dirname, '/rec.jpg')), |       nFile1: fs.createReadStream(path.join(__dirname, '../utils/rec.jpg')), | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     const res = await rq({ method: 'POST', url: '/graphql', formData }); |     const res = await rq({ method: 'POST', url: '/graphql', formData }); | ||||||
| @ -404,7 +404,7 @@ describe('Upload plugin end to end tests', () => { | |||||||
|       map: JSON.stringify({ |       map: JSON.stringify({ | ||||||
|         nFile1: ['variables.file'], |         nFile1: ['variables.file'], | ||||||
|       }), |       }), | ||||||
|       nFile1: fs.createReadStream(path.join(__dirname, '/rec.pdf')), |       nFile1: fs.createReadStream(path.join(__dirname, '../utils/rec.pdf')), | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     const res = await rq({ method: 'POST', url: '/graphql', formData }); |     const res = await rq({ method: 'POST', url: '/graphql', formData }); | ||||||
|  | |||||||
| @ -6,7 +6,7 @@ const path = require('path'); | |||||||
| // Helpers.
 | // Helpers.
 | ||||||
| const { createTestBuilder } = require('../../../../../test/helpers/builder'); | const { createTestBuilder } = require('../../../../../test/helpers/builder'); | ||||||
| const { createStrapiInstance } = require('../../../../../test/helpers/strapi'); | const { createStrapiInstance } = require('../../../../../test/helpers/strapi'); | ||||||
| const { createAuthRequest } = require('../../../../../test/helpers/request'); | const { createContentAPIRequest } = require('../../../../../test/helpers/request'); | ||||||
| 
 | 
 | ||||||
| const builder = createTestBuilder(); | const builder = createTestBuilder(); | ||||||
| let strapi; | let strapi; | ||||||
| @ -28,7 +28,7 @@ describe('Upload plugin end to end tests', () => { | |||||||
|   beforeAll(async () => { |   beforeAll(async () => { | ||||||
|     await builder.addContentType(dogModel).build(); |     await builder.addContentType(dogModel).build(); | ||||||
|     strapi = await createStrapiInstance(); |     strapi = await createStrapiInstance(); | ||||||
|     rq = await createAuthRequest({ strapi }); |     rq = await createContentAPIRequest({ strapi }); | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|   afterAll(async () => { |   afterAll(async () => { | ||||||
| @ -88,7 +88,7 @@ describe('Upload plugin end to end tests', () => { | |||||||
|         method: 'POST', |         method: 'POST', | ||||||
|         url: '/upload', |         url: '/upload', | ||||||
|         formData: { |         formData: { | ||||||
|           files: fs.createReadStream(path.join(__dirname, 'rec.jpg')), |           files: fs.createReadStream(path.join(__dirname, '../utils/rec.jpg')), | ||||||
|         }, |         }, | ||||||
|       }); |       }); | ||||||
| 
 | 
 | ||||||
| @ -121,7 +121,7 @@ describe('Upload plugin end to end tests', () => { | |||||||
|         method: 'POST', |         method: 'POST', | ||||||
|         url: '/upload', |         url: '/upload', | ||||||
|         formData: { |         formData: { | ||||||
|           files: fs.createReadStream(path.join(__dirname, 'thumbnail_target.png')), |           files: fs.createReadStream(path.join(__dirname, '../utils/thumbnail_target.png')), | ||||||
|         }, |         }, | ||||||
|       }); |       }); | ||||||
| 
 | 
 | ||||||
| @ -185,7 +185,7 @@ describe('Upload plugin end to end tests', () => { | |||||||
|         url: '/api/dogs?populate=*', |         url: '/api/dogs?populate=*', | ||||||
|         formData: { |         formData: { | ||||||
|           data: '{}', |           data: '{}', | ||||||
|           'files.profilePicture': fs.createReadStream(path.join(__dirname, 'rec.jpg')), |           'files.profilePicture': fs.createReadStream(path.join(__dirname, '../utils/rec.jpg')), | ||||||
|         }, |         }, | ||||||
|       }); |       }); | ||||||
| 
 | 
 | ||||||
| @ -213,7 +213,7 @@ describe('Upload plugin end to end tests', () => { | |||||||
|         url: '/api/dogs?populate=*', |         url: '/api/dogs?populate=*', | ||||||
|         formData: { |         formData: { | ||||||
|           data: '{}', |           data: '{}', | ||||||
|           'files.profilePicture': fs.createReadStream(path.join(__dirname, 'rec.pdf')), |           'files.profilePicture': fs.createReadStream(path.join(__dirname, '../utils/rec.pdf')), | ||||||
|         }, |         }, | ||||||
|       }); |       }); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| Before Width: | Height: | Size: 787 B After Width: | Height: | Size: 787 B | 
| Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB | 
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Pierre Noël
						Pierre Noël