Skip to content
Permalink
Browse files
completed unit tests for module
  • Loading branch information
aa7401 committed Sep 15, 2019
1 parent cada045 commit 3749913d5182a9558d7827a314372232680709b4
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 74 deletions.
@@ -2,6 +2,13 @@
{
"version": "0.2.0",
"configurations": [

{
"type": "node",
"request": "attach",
"name": "Attach by Process ID",
"processId": "${command:PickProcess}"
},
{
"type": "node",
"request": "launch",
@@ -11,6 +18,7 @@
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"disableOptimisticBPs": true,
"protocol": "inspector",
"windows": {
"program": "${workspaceFolder}/node_modules/jest/bin/jest",
}
@@ -7,6 +7,7 @@
'use strict'

/* MODULE IMPORTS */
const bcrypt = require('bcrypt-promise')
const Koa = require('koa')
const Router = require('koa-router')
const views = require('koa-views')
@@ -15,13 +16,12 @@ const bodyParser = require('koa-bodyparser')
const koaBody = require('koa-body')({multipart: true, uploadDir: '.'})
const session = require('koa-session')
const sqlite = require('sqlite-async')
const bcrypt = require('bcrypt-promise')
const fs = require('fs-extra')
const mime = require('mime-types')
//const jimp = require('jimp')

/* IMPORT CUSTOM MODULES */
const accounts = require('./modules/accounts')
const User = require('./modules/user')

const app = new Koa()
const router = new Router()
@@ -35,6 +35,7 @@ app.use(views(`${__dirname}/views`, { extension: 'handlebars' }, {map: { handleb

const defaultPort = 8080
const port = process.env.PORT || defaultPort
const dbName = 'website.db'
const saltRounds = 10

/**
@@ -71,24 +72,15 @@ router.get('/register', async ctx => await ctx.render('register'))
*/
router.post('/register', koaBody, async ctx => {
try {
// extract the data from the request
const body = ctx.request.body
console.log(body)
// PROCESSING FILE
const {path, type} = ctx.request.files.avatar
const fileExtension = mime.extension(type)
console.log(`path: ${path}`)
console.log(`type: ${type}`)
console.log(`fileExtension: ${fileExtension}`)
await fs.copy(path, 'public/avatars/avatar.png')
// ENCRYPTING PASSWORD AND BUILDING SQL
body.pass = await bcrypt.hash(body.pass, saltRounds)
const sql = `INSERT INTO users(user, pass) VALUES("${body.user}", "${body.pass}")`
console.log(sql)
// DATABASE COMMANDS
const db = await sqlite.open('./website.db')
await db.run(sql)
await db.close()
// REDIRECTING USER TO HOME PAGE
// call the functions in the module
const user = await new User(dbName)
await user.register(body.user, body.pass)
// await user.uploadPicture(path, type)
// redirect to the home page
ctx.redirect(`/?msg=new user "${body.name}" added`)
} catch(err) {
await ctx.render('error', {message: err.message})
@@ -99,50 +91,25 @@ router.get('/login', async ctx => {
const data = {}
if(ctx.query.msg) data.msg = ctx.query.msg
if(ctx.query.user) data.user = ctx.query.user
await ctx.render('login', data)
await ctx.render('login', data)
})

router.post('/login', async ctx => {
try {
const body = ctx.request.body
const db = await sqlite.open('./website.db')
// DOES THE USERNAME EXIST?
const records = await db.get(`SELECT count(id) AS count FROM users WHERE user="${body.user}";`)
if(!records.count) return ctx.redirect('/login?msg=invalid%20username')
const record = await db.get(`SELECT pass FROM users WHERE user = "${body.user}";`)
await db.close()
// DOES THE PASSWORD MATCH?
const valid = await bcrypt.compare(body.pass, record.pass)
if(valid == false) return ctx.redirect(`/login?user=${body.user}&msg=invalid%20password`)
// WE HAVE A VALID USERNAME AND PASSWORD
const user = await new User(dbName)
await user.login(body.user, body.pass)
ctx.session.authorised = true
return ctx.redirect('/?msg=you are now logged in...')
} catch(err) {
await ctx.render('error', {message: err.message})
}
})

// router.post('/login', async ctx => { // 19 lines reduced to 10!
// const body = ctx.request.body
// try {
// await accounts.checkCredentials(body.user, body.pass)
// ctx.session.authorised = true
// return ctx.redirect('/?msg=you are now logged in...')
// } catch(err) {
// return ctx.redirect(`/login?user=${body.user}&msg=${err.message}`)
// }
// })

router.get('/logout', async ctx => {
ctx.session.authorised = null;
ctx.redirect('/')
ctx.session.authorised = null
ctx.redirect('/?msg=you are now logged out')
})

app.use(router.routes())
module.exports = app.listen(port, async() => {
// MAKE SURE WE HAVE A DATABASE WITH THE CORRECT SCHEMA
const db = await sqlite.open('./website.db')
await db.run('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, user TEXT, pass TEXT);')
await db.close()
console.log(`listening on port ${port}`)
})
module.exports = app.listen(port, async() => console.log(`listening on port ${port}`))
@@ -1,6 +1,7 @@

'use strict'

const bcrypt = require('bcrypt-promise')
const fs = require('fs-extra')
const mime = require('mime-types')
const sqlite = require('sqlite-async')
@@ -18,24 +19,42 @@ module.exports = class User {
})()
}

async register(username, password, filename, filetype) {
const fileExtension = mime.extension(filetype)
await fs.copy(path, `public/avatars/${username}.${fileExtension}`)
password = await bcrypt.hash(password, saltRounds)
const sql = `INSERT INTO users(user, pass) VALUES("${username}", "${password}")`
await this.db.run(sql)
return true
async register(user, pass) {
try {
if(user.length === 0) throw new Error('missing username')
if(pass.length === 0) throw new Error('missing password')
let sql = `SELECT COUNT(id) as records FROM users WHERE user="${user}";`
const data = await this.db.get(sql)
if(data.records !== 0) throw new Error(`username "${user}" already in use`)
pass = await bcrypt.hash(pass, saltRounds)
sql = `INSERT INTO users(user, pass) VALUES("${user}", "${pass}")`
await this.db.run(sql)
return true
} catch(err) {
throw err
}
}

async uploadPicture(path, mimeType) {
const extension = mime.extension(mimeType)
console.log(`path: ${path}`)
console.log(`extension: ${extension}`)
//await fs.copy(path, `public/avatars/${username}.${fileExtension}`)
}

async login(username, password) {
let sql = `SELECT count(id) AS count FROM users WHERE user="${body.user}";`
const records = await this.db.get(sql)
if(!records.count) throw new Error(`username "${username}" not found`)
sql = `SELECT pass FROM users WHERE user = "${body.user}";`
const record = await db.get(sql)
const valid = await bcrypt.compare(body.pass, record.pass)
if(valid == false) throw new Error(`invalid password for account "${username}"`)
return true
try {
let sql = `SELECT count(id) AS count FROM users WHERE user="${username}";`
const records = await this.db.get(sql)
if(!records.count) throw new Error(`username "${username}" not found`)
sql = `SELECT pass FROM users WHERE user = "${username}";`
const record = await this.db.get(sql)
const valid = await bcrypt.compare(password, record.pass)
if(valid === false) throw new Error(`invalid password for account "${username}"`)
return true
} catch(err) {
throw err
}
}

}
@@ -1,32 +1,81 @@

'use strict'

const Accounts = require('../modules/accounts.js')
const Accounts = require('../modules/user.js')

describe('register()', () => {

test('register a valid account', async done => {
expect.assertions(1)
try {
const account = await new Accounts()
// test goes here
const register = await account.register('doej', 'password')
expect(register).toBe(true)
} catch(err) {
done.fail(err)
} finally {
done()
}
})

test('register a duplicate username', async done => {
expect.assertions(1)
const account = await new Accounts()
await account.register('doej', 'password')
await expect( account.register('doej', 'password') )
.rejects.toEqual( Error('username "doej" already in use') )
done()
})

test('error if blank username', async done => {
expect.assertions(1)
const account = await new Accounts()
await expect( account.register('', 'password') )
.rejects.toEqual( Error('missing username') )
done()
})

test('error if blank password', async done => {
expect.assertions(1)
const account = await new Accounts()
await expect( account.register('doej', '') )
.rejects.toEqual( Error('missing password') )
done()
})

})

describe('uploadPicture()', () => {
// this would have to be done by mocking the file system
// perhaps using mock-fs?
})

describe('login()', () => {
test('log in with valid credentials', done => {
test('log in with valid credentials', async done => {
expect.assertions(1)
try {
const account = await new Accounts()
// test goes here
} catch(err) {
done.fail(err)
} finally {
done()
}
const account = await new Accounts()
await account.register('doej', 'password')
const valid = await account.login('doej', 'password')
expect(valid).toBe(true)
done()
})

test('invalid username', async done => {
expect.assertions(1)
const account = await new Accounts()
await account.register('doej', 'password')
await expect( account.login('roej', 'password') )
.rejects.toEqual( Error('username "roej" not found') )
done()
})

test('invalid password', async done => {
expect.assertions(1)
const account = await new Accounts()
await account.register('doej', 'password')
await expect( account.login('doej', 'bad') )
.rejects.toEqual( Error('invalid password for account "doej"') )
done()
})

})

0 comments on commit 3749913

Please sign in to comment.