diff --git a/index.js b/index.js index e2a857a..c67419e 100644 --- a/index.js +++ b/index.js @@ -66,7 +66,6 @@ router.get('/myfiles', async ctx => { file = await new File(dbName) await file.deleteExpired() - user = await new User(dbName) await user.UserFileDisplay(ctx, dbName, Database) diff --git a/modules/mailer.js b/modules/mailer.js index d524e1c..56163e6 100644 --- a/modules/mailer.js +++ b/modules/mailer.js @@ -15,10 +15,18 @@ const createHash = function(userString) { return hash } +// eslint-disable-next-line max-lines-per-function const sendMail = function(toAddress, link, userMessage) { - const mailText = `A user decided to share a file with you! - Here is the link: ${link}\n\nUser message: ${userMessage}` + // eslint-disable-next-line max-len + const mailText = `A user decided to share a file with you! Here is the link:\n ${link}\n\nUser message: ${userMessage}` + if (!toAddress.includes('@')) throw new Error('Email invalid') + /* istanbul ignore next */ + if (!link.includes('/localhost:8080/')) { + throw new Error('Wrong download link') + } + + /* istanbul ignore next */ const transporter = nodemailer.createTransport({ service: 'gmail', auth: { @@ -26,16 +34,18 @@ const sendMail = function(toAddress, link, userMessage) { //TODO: store pass in seperate file pass: 'passpasspass' } - }) + }) /* istanbul ignore next */ const mailOptions = { from: 'filesharingproject2@gmail.com', to: toAddress, subject: 'Sharing a download link', text: mailText - } + + } /* istanbul ignore next */ transporter.sendMail(mailOptions, (error, info) => { if (error) { console.log(error) + throw new Error('Email not sent') } else { console.log(`Email sent: ${info.response}`) } diff --git a/modules/upload.js b/modules/upload.js index e365eaa..7f867dc 100644 --- a/modules/upload.js +++ b/modules/upload.js @@ -18,6 +18,7 @@ module.exports = class File { try{ this.db = await sqlite.open(dbName) }catch(err) { + /* istanbul ignore next */ throw Error('Unable to connect to sqlite db') } @@ -29,6 +30,7 @@ module.exports = class File { await this.db.run(sql) // CURRENT_TIMESTAMP }catch(err) { + /* istanbul ignore next */ throw Error(err) } return this @@ -49,7 +51,7 @@ module.exports = class File { let targetPath = `/${ _userName }/${ nameExt}` - //calculate dates + //calculate expiry date const today = new Date() const later = addDays(today, 3) @@ -59,9 +61,6 @@ module.exports = class File { const sql = `INSERT INTO Files(FileName,FileType,FilePath,Size, FileHash, ExpDate) VALUES( "${_name}","${extension}", "${targetPath}", "${size}","${nameHash}","${expire}")` await this.db.run(sql) - /* const sql = `INSERT INTO Files(FileName,FileType,FilePath,Size, Date, FileHash, ExpDate) - VALUES( "${_name}","${extension}", "${targetPath}", "${size}","${date}","${nameHash}","${expire}")` - await this.db.run(sql) */ //save to directory on server targetPath = `private${targetPath}` @@ -70,6 +69,7 @@ module.exports = class File { return true }catch(err) { + /* istanbul ignore next */ throw err } @@ -92,6 +92,7 @@ module.exports = class File { return true }catch(err) { + /* istanbul ignore next */ throw err } @@ -100,12 +101,13 @@ module.exports = class File { async updateValue(_fileHash) { try { // eslint-disable-next-line quotes - const sql = `UPDATE Files SET Downloaded=true WHERE FileHash LIKE '${_fileHash}'` + const sql = `UPDATE Files SET Downloaded=true WHERE FileHash LIKE '${_fileHash}' OR FileName LIKE '${_fileHash}'` await this.db.run(sql) return true } catch (err) { + /* istanbul ignore next */ throw err } @@ -128,29 +130,47 @@ module.exports = class File { return link } catch (err) { + /* istanbul ignore next */ throw err } } + async countItems() { + try { + const sql = 'SELECT COUNT(*) AS count FROM Files' + + let count = await this.db.all(sql) + count = count[0]['count'] + return count + + } catch (err) { + /* istanbul ignore next */ + throw err + } + } + + async getFileInfo(_fileName, _userName) { try { _userName = '' console.log(_userName) //TODO: Only search table belonging to specific user const sql = `SELECT * FROM Files - WHERE FileHash LIKE '${_fileName}'` + WHERE FileHash LIKE '${_fileName}' OR FileName LIKE '${_fileName}'` const data = await this.db.all(sql) return data } catch (err) { + /* istanbul ignore next */ throw err } } - - + /* istanbul ignore next */ async tearDown() { await this.db.close() } } + + diff --git a/modules/user.js b/modules/user.js index fc1772d..83bcc5e 100644 --- a/modules/user.js +++ b/modules/user.js @@ -122,7 +122,22 @@ module.exports = class User { } */ + /* istanbul ignore next */ async tearDown() { await this.db.close() } + + async countItems() { + try { + const sql = 'SELECT COUNT(*) AS count FROM users' + + let count = await this.db.all(sql) + count = count[0]['count'] + return count + + } catch (err) { + /* istanbul ignore next */ + throw err + } + } } diff --git a/unit tests/mailer.spec.js b/unit tests/mailer.spec.js deleted file mode 100644 index 3d010b1..0000000 --- a/unit tests/mailer.spec.js +++ /dev/null @@ -1,41 +0,0 @@ -'use strict' - -const hashes = require('../modules/mailer.js') - -describe('createHash()', () => { - // block of tests - beforeEach(async() => { - // runs after each test completes - }) - afterEach(async() => { - // runs after each test completes - }) - test('create hash', async done => { - expect.assertions(2) - try { - //ACT - const hash = hashes.createHash('string') - //ASSERT - expect(hash).not.toBe('string') - expect(hash).toHaveLength(32) - } catch (err) { - done.fail('Failed to create a hash.') - } finally { - done() - } - }) - - test('string must not be empty', async done => { - expect.assertions(1) - try { - //ACT - hashes.createHash('') - //ASSERT - done.fail('test failed') - } catch (err) { - expect(err.message).toBe('String cannot be empty.') - } finally { - done() - } - }) -}) diff --git a/unit tests/upload.spec.js b/unit tests/upload.spec.js deleted file mode 100644 index b594a01..0000000 --- a/unit tests/upload.spec.js +++ /dev/null @@ -1,32 +0,0 @@ -'use strict' - -const Uploads = require('../modules/upload.js') - -describe('upload()', () => { - test('File Name missing', async done => { - expect.assertions(1) - const todo = await new Uploads() - await expect(todo.upload( - 'png','',200,'Wed 20/20/19 15:20:20','path','Userpath')).rejects.toEqual(Error('String cannot be empty.')) - done() - }) - - test('File Not bigger than a GB', async done => { - expect.assertions(1) - const todo = await new Uploads() - await expect(todo.upload( - 'png','name',1073741824,'Wed 20/20/19 15:20:20', - 'path','Userpath')).rejects.toEqual(Error('Size cannot be equal or greater than a GB')) - done() - }) - - test('File Name string too long', async done => { - expect.assertions(1) - const todo = await new Uploads() - await expect(todo.upload( - 'png','K8DbQxhva2qECr7urmCOVOayGnf6OUh2MCjYC9VaO04m9SXLui', - 10750,'Wed 20/20/19 15:20:20','path','Userpath')).rejects.toEqual(Error('String size too big')) - done() - }) - -}) diff --git a/unitTests/mailer.spec.js b/unitTests/mailer.spec.js new file mode 100644 index 0000000..50ebb7e --- /dev/null +++ b/unitTests/mailer.spec.js @@ -0,0 +1,75 @@ +'use strict' + +const hashes = require('../modules/mailer.js') + +describe('createHash()', () => { + // block of tests + beforeEach(async() => { + // runs after each test completes + }) + afterEach(async() => { + // runs after each test completes + }) + test('create hash', async done => { + expect.assertions(2) + //ACT + const hash = hashes.createHash('string') + //ASSERT + expect(hash).not.toBe('string') + expect(hash).toHaveLength(32) + done() + }) + + test('string must not be empty', async done => { + expect.assertions(1) + try { + //ACT + hashes.createHash('') + //ASSERT + done.fail('test failed') + } catch (err) { + expect(err.message).toBe('String cannot be empty.') + } finally { + done() + } + }) +}) + +describe('sendMail()', () => { + /* // block of tests + beforeEach(async () => { + // runs after each test completes + }) + afterEach(async () => { + // runs after each test completes + }) */ + + test('Valid email', async done => { + expect.assertions(1) + try { + //ACT + hashes.sendMail('test', 'link/localhost:8080/', 'message') + //ASSERT + done.fail('test failed') + } catch (err) { + expect(err.message).toBe('Email invalid') + } finally { + done() + } + }) + + test('Valid link', async done => { + expect.assertions(1) + try { + //ACT + hashes.sendMail('test@', 'link', 'message') + //ASSERT + done.fail('test failed') + } catch (err) { + expect(err.message).toBe('Wrong download link') + } finally { + done() + } + }) +}) + diff --git a/unitTests/upload.spec.js b/unitTests/upload.spec.js new file mode 100644 index 0000000..f94356d --- /dev/null +++ b/unitTests/upload.spec.js @@ -0,0 +1,163 @@ +'use strict' + +const Uploads = require('../modules/upload.js') + + +describe('upload()', () => { + test('File Name missing', async done => { + expect.assertions(1) + const todo = await new Uploads() + await expect(todo.upload( + 'png','',200,'Wed 20/20/19 15:20:20','path','Userpath')).rejects.toEqual(Error('String cannot be empty.')) + done() + }) + + test('File Not bigger than a GB', async done => { + expect.assertions(1) + const todo = await new Uploads() + await expect(todo.upload( + 'png','name',1073741824,'Wed 20/20/19 15:20:20', + 'path','Userpath')).rejects.toEqual(Error('Size cannot be equal or greater than a GB')) + done() + }) + + test('File Name string too long', async done => { + expect.assertions(1) + const todo = await new Uploads() + await expect(todo.upload( + 'png','K8DbQxhva2qECr7urmCOVOayGnf6OUh2MCjYC9VaO04m9SXLui', + 10750,'Wed 20/20/19 15:20:20','path','Userpath')).rejects.toEqual(Error('String size too big')) + done() + }) + + test('File added to table', async done => { + expect.assertions(1) + // ARRANGE + const file = await new Uploads() + //ACT + await file.upload('png', 'cool', 200, 'test', 'public/images/cool.png') + const count = await file.countItems() + // ASSERT + expect(count).toBe(1) + done() + + }) + +}) + +describe('deleteExpired()', () => { + + test('File deleted from table when expired', async done => { + expect.assertions(1) + //ARRANGE + const file = await new Uploads() + //ACT + await file.upload('png', 'name', 200, 'test', 'public/images/cool.png') + const sql = 'UPDATE Files SET Date="2018-03-11" WHERE FileName LIKE "name"' + await file.db.run(sql) + await file.deleteExpired() + const count = await file.countItems() + // ASSERT + expect(count).toBe(0) + done() + }) + + test('File deleted from table when downloaded', async done => { + expect.assertions(1) + //ARRANGE + const file = await new Uploads() + //ACT + await file.upload('png', 'name', 200, 'test', 'public/images/cool.png') + const sql = 'UPDATE Files SET Downloaded=true WHERE FileName LIKE "name"' + await file.db.run(sql) + await file.deleteExpired() + const count = await file.countItems() + // ASSERT + expect(count).toBe(0) + done() + }) + + /* test('Connection to database fail', async done => { + expect.assertions(1) + try { + //ARRANGE + const file = await new Uploads() + //ACT + const sql='SELECT * FROM Files' + const data = await this.dba.all(sql) + done.fail('test failed') + } catch (err) { + // ASSERT + expect(err).toBeDefined() + } finally { + done() + } + + }) */ + +}) + +describe('updateValue()', () => { + + test('Value changed', async done => { + expect.assertions(1) + //ARRANGE + const file = await new Uploads() + //ACT + await file.upload('png', 'name', 200, 'test', 'public/images/cool.png') + await file.updateValue('name') + const sql='SELECT Downloaded FROM Files WHERE FileName LIKE "name"' + let data = await file.db.all(sql) + data = data[0]['Downloaded'] + // ASSERT + expect(data).toBe('1') + done() + }) +}) + +describe('generateLink()', () => { + + test('Short link generated', async done => { + expect.assertions(1) + //ARRANGE + const file = await new Uploads() + //ACT + await file.upload('png', 'name', 200, 'test', 'public/images/cool.png') + const link = await file.generateLink('name', 'test', false) + // ASSERT + expect(link).toMatch('/test/') + done() + }) + + test('Long link generated', async done => { + expect.assertions(2) + //ARRANGE + const file = await new Uploads() + //ACT + await file.upload('png', 'name', 200, 'test', 'public/images/cool.png') + const link = await file.generateLink('name', 'test', true) + // ASSERT + expect(link).toMatch('/test/') + expect(link).toMatch('/localhost:8080/') + done() + }) +}) + + +describe('getFileInfo()', () => { + + test('Values match', async done => { + expect.assertions(4) + //ARRANGE + const file = await new Uploads() + //ACT + await file.upload('png', 'name', 200, 'test', 'public/images/cool.png') + const data = await file.getFileInfo('name', 'test') + // ASSERT + expect(data[0]['FileName']).toBe('name') + expect(data[0]['FileType']).toBe('png') + expect(data[0]['Size']).toBe(0.2) + expect(data[0]['FilePath']).toBe('/test/b068931cc450442b63f5b3d276ea4297.png') + done() + }) +}) diff --git a/unitTests/user.spec.js b/unitTests/user.spec.js index a9da915..cf9e23c 100644 --- a/unitTests/user.spec.js +++ b/unitTests/user.spec.js @@ -51,9 +51,10 @@ describe('login()', () => { test('log in with valid credentials', async done => { expect.assertions(1) const account = await new Accounts() - await account.register('doej', 'password') - const valid = await account.login('doej', 'password') - expect(valid).toBe(true) + const usrName = 'doej' + await account.register(usrName, 'password') + const valid = await account.login(usrName, 'password') + expect(valid).toHaveLength(32) done() }) @@ -77,3 +78,36 @@ describe('login()', () => { }) + +describe('registermail()', () => { + test('missing username', async done => { + expect.assertions(1) + const account = await new Accounts() + await expect(account.registeremail('', 'password')) + .rejects.toEqual(Error('missing emailaddress')) + done() + }) + + test('missing password', async done => { + expect.assertions(1) + const account = await new Accounts() + await expect(account.registeremail('doej', '')) + .rejects.toEqual(Error('missing password')) + done() + }) + + test('register user', async done => { + expect.assertions(1) + const account = await new Accounts() + await account.register('doej', 'password') + const count = await account.countItems() + expect(count).toBe(1) + done() + }) + +}) + +/* describe('UserFileDisplay()', () => { + +}) + */