From 65852c25cedafde277e559415c3e2cbdcbb7c64d Mon Sep 17 00:00:00 2001 From: Basar Buyukkahraman Date: Mon, 10 Aug 2020 23:26:43 +0300 Subject: [PATCH] 1703-storing-attached-file --- __tests__/FileUpload.spec.js | 11 ++++ package-lock.json | 108 ++++++++++++++++++++++++++++++++++- package.json | 1 + src/file/FileRouter.js | 7 ++- src/file/FileService.js | 6 +- test-cleanup.js | 16 ++++-- 6 files changed, 138 insertions(+), 11 deletions(-) diff --git a/__tests__/FileUpload.spec.js b/__tests__/FileUpload.spec.js index 13c58c4..660b4a1 100644 --- a/__tests__/FileUpload.spec.js +++ b/__tests__/FileUpload.spec.js @@ -3,6 +3,10 @@ const app = require('../src/app'); const path = require('path'); const FileAttachment = require('../src/file/FileAttachment'); const sequelize = require('../src/config/database'); +const fs = require('fs'); +const config = require('config'); + +const { uploadDir, attachmentDir } = config; beforeAll(async () => { if (process.env.NODE_ENV === 'test') { @@ -33,4 +37,11 @@ describe('Upload File for Hoax', () => { expect(attachment.filename).not.toBe('test-png.png'); expect(attachment.uploadDate.getTime()).toBeGreaterThan(beforeSubmit); }); + it('saves file to attachment folder', async () => { + await uploadFile(); + const attachments = await FileAttachment.findAll(); + const attachment = attachments[0]; + const filePath = path.join('.', uploadDir, attachmentDir, attachment.filename); + expect(fs.existsSync(filePath)).toBe(true); + }); }); diff --git a/package-lock.json b/package-lock.json index 3e9e193..c7be1d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -976,6 +976,11 @@ "picomatch": "^2.0.4" } }, + "append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY=" + }, "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", @@ -1369,14 +1374,45 @@ "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, "buffer-writer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==" }, + "busboy": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", + "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", + "requires": { + "dicer": "0.2.5", + "readable-stream": "1.1.x" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", @@ -1712,6 +1748,17 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, "config": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/config/-/config-3.3.1.tgz", @@ -2058,6 +2105,38 @@ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true }, + "dicer": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", + "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", + "requires": { + "readable-stream": "1.1.x", + "streamsearch": "0.1.2" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, "diff-sequences": { "version": "26.0.0", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", @@ -4747,6 +4826,21 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "multer": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.2.tgz", + "integrity": "sha512-xY8pX7V+ybyUpbYMxtjM9KAiD9ixtg5/JkeKUTD6xilfDv0vzzOFcCp4Ljb1UU3tSOM3VTZtKo63OmzOrGi3Cg==", + "requires": { + "append-field": "^1.0.0", + "busboy": "^0.2.11", + "concat-stream": "^1.5.2", + "mkdirp": "^0.5.1", + "object-assign": "^4.1.1", + "on-finished": "^2.3.0", + "type-is": "^1.6.4", + "xtend": "^4.0.0" + } + }, "mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", @@ -6768,6 +6862,11 @@ "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", "dev": true }, + "streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" + }, "string-length": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz", @@ -7211,6 +7310,11 @@ "mime-types": "~2.1.24" } }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, "typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", diff --git a/package.json b/package.json index 07b6400..dc012dd 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "i18next": "^19.4.5", "i18next-fs-backend": "^1.0.6", "i18next-http-middleware": "^2.1.2", + "multer": "^1.4.2", "nodemailer": "^6.4.8", "pg": "^8.3.0", "pg-hstore": "^2.3.3", diff --git a/src/file/FileRouter.js b/src/file/FileRouter.js index bf8359e..9d0ae91 100644 --- a/src/file/FileRouter.js +++ b/src/file/FileRouter.js @@ -1,9 +1,12 @@ const express = require('express'); const router = express.Router(); const FileService = require('./FileService'); +const multer = require('multer'); -router.post('/api/1.0/hoaxes/attachments', async (req, res) => { - await FileService.saveAttachment(); +const upload = multer(); + +router.post('/api/1.0/hoaxes/attachments', upload.single('file'), async (req, res) => { + await FileService.saveAttachment(req.file); res.send(); }); diff --git a/src/file/FileService.js b/src/file/FileService.js index 925eec9..d6d4f53 100644 --- a/src/file/FileService.js +++ b/src/file/FileService.js @@ -42,9 +42,11 @@ const isSupportedFileType = async (buffer) => { return !type ? false : type.mime === 'image/png' || type.mime === 'image/jpeg'; }; -const saveAttachment = async () => { +const saveAttachment = async (file) => { + const filename = randomString(32); + await fs.promises.writeFile(path.join(attachmentFolder, filename), file.buffer); await FileAttachment.create({ - filename: randomString(32), + filename, uploadDate: new Date(), }); }; diff --git a/test-cleanup.js b/test-cleanup.js index 396e749..ed8700e 100644 --- a/test-cleanup.js +++ b/test-cleanup.js @@ -2,10 +2,16 @@ const fs = require('fs'); const path = require('path'); const config = require('config'); -const { uploadDir, profileDir } = config; +const { uploadDir, profileDir, attachmentDir } = config; const profileDirectory = path.join('.', uploadDir, profileDir); +const attachmentDirectory = path.join('.', uploadDir, attachmentDir); -const files = fs.readdirSync(profileDirectory); -for (const file of files) { - fs.unlinkSync(path.join(profileDirectory, file)); -} +const clearFolders = (folder) => { + const files = fs.readdirSync(folder); + for (const file of files) { + fs.unlinkSync(path.join(folder, file)); + } +}; + +clearFolders(profileDirectory); +clearFolders(attachmentDirectory);