From 11275d6809ee0f61106684ba311d3db1a0cd1005 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Fri, 11 Feb 2022 13:23:12 -0500 Subject: [PATCH] test: testing user upload methods, already fixed one bug --- src/user/uploads.js | 2 +- test/user/uploads.js | 111 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 test/user/uploads.js diff --git a/src/user/uploads.js b/src/user/uploads.js index fdc71729cd..3899c1d66f 100644 --- a/src/user/uploads.js +++ b/src/user/uploads.js @@ -31,7 +31,7 @@ module.exports = function (User) { await _validatePath(relativePath); await Promise.all([ db.sortedSetAdd(`uid:${uid}:uploads`, Date.now(), relativePath), - db.setObjectField(`upload:${md5(relativePath)}:uid`, uid), + db.setObjectField(`upload:${md5(relativePath)}`, 'uid', uid), ]); }; diff --git a/test/user/uploads.js b/test/user/uploads.js new file mode 100644 index 0000000000..8aae511324 --- /dev/null +++ b/test/user/uploads.js @@ -0,0 +1,111 @@ +'use strict'; + +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); +const crypto = require('crypto'); + +const nconf = require('nconf'); +const db = require('../mocks/databasemock'); + +const user = require('../../src/user'); +const utils = require('../../public/src/utils'); + +const md5 = filename => crypto.createHash('md5').update(filename).digest('hex'); + +describe('uploads.js', () => { + describe('.associateUpload()', () => { + let uid; + let relativePath; + + beforeEach(async () => { + uid = await user.create({ + username: utils.generateUUID(), + password: utils.generateUUID(), + gdpr_consent: 1, + }); + relativePath = `files/${utils.generateUUID()}`; + + fs.closeSync(fs.openSync(path.join(nconf.get('upload_path'), relativePath), 'w')); + }); + + it('should associate an uploaded file to a user', async () => { + await user.associateUpload(uid, relativePath); + const uploads = await db.getSortedSetMembers(`uid:${uid}:uploads`); + const uploadObj = await db.getObject(`upload:${md5(relativePath)}`); + + assert.strictEqual(uploads.length, 1); + assert.deepStrictEqual(uploads, [relativePath]); + assert.strictEqual(parseInt(uploadObj.uid, 10), uid); + }); + + it('should throw an error if the path is invalid', async () => { + try { + await user.associateUpload(uid, `${relativePath}suffix`); + } catch (e) { + assert(e); + assert.strictEqual(e.message, '[[error:invalid-path]]'); + } + + const uploads = await db.getSortedSetMembers(`uid:${uid}:uploads`); + + assert.strictEqual(uploads.length, 0); + assert.deepStrictEqual(uploads, []); + }); + + it('should guard against path traversal', async () => { + try { + await user.associateUpload(uid, `../../config.json`); + } catch (e) { + assert(e); + assert.strictEqual(e.message, '[[error:invalid-path]]'); + } + + const uploads = await db.getSortedSetMembers(`uid:${uid}:uploads`); + + assert.strictEqual(uploads.length, 0); + assert.deepStrictEqual(uploads, []); + }); + }); + + describe('.deleteUpload', () => { + let uid; + let relativePath; + + beforeEach(async () => { + uid = await user.create({ + username: utils.generateUUID(), + password: utils.generateUUID(), + gdpr_consent: 1, + }); + relativePath = `files/${utils.generateUUID()}`; + + fs.closeSync(fs.openSync(path.join(nconf.get('upload_path'), relativePath), 'w')); + await user.associateUpload(uid, relativePath); + }); + + it('should remove the upload from the user\'s uploads zset', async () => { + + }); + + it('should delete the file from disk', async () => { + + }); + + it('should clean up references to it from the database', async () => { + + }); + + it('should accept multiple paths', async () => { + + }); + + it('should throw an error on a non-existant file', async () => { + + }); + + it('should guard against path traversal', async () => { + + }); + }); +});