From a472bf245b881d2dd5aed24fda24ffc3e3672e46 Mon Sep 17 00:00:00 2001 From: Mark Tyers Date: Wed, 20 Mar 2019 17:38:33 +0000 Subject: [PATCH] added unit tests --- .eslintrc.json | 5 +- .../__mocks__/sqlite-async-old.js | 51 ++++++++++++++ .../07_forms_auth/__mocks__/sqlite-async-x.js | 22 +++++++ exercises/07_forms_auth/modules/accounts.js | 1 + exercises/07_forms_auth/package.json | 21 +++++- .../07_forms_auth/public/avatars/avatar.png | Bin 0 -> 56968 bytes exercises/07_forms_auth/temp.js | 29 ++++++++ exercises/07_forms_auth/test.sh | 2 +- .../tests/{ => acceptance}/auth.spec.js | 0 .../07_forms_auth/tests/accounts.spec.js | 0 exercises/07_forms_auth/tests/index.spec.js | 0 .../07_forms_auth/tests/unit/accounts.spec.js | 62 ++++++++++++++++++ .../07_forms_auth/tests/unit/index.specx.js | 33 ++++++++++ 13 files changed, 220 insertions(+), 6 deletions(-) create mode 100644 exercises/07_forms_auth/__mocks__/sqlite-async-old.js create mode 100644 exercises/07_forms_auth/__mocks__/sqlite-async-x.js create mode 100644 exercises/07_forms_auth/temp.js rename exercises/07_forms_auth/tests/{ => acceptance}/auth.spec.js (100%) delete mode 100644 exercises/07_forms_auth/tests/accounts.spec.js delete mode 100644 exercises/07_forms_auth/tests/index.spec.js create mode 100644 exercises/07_forms_auth/tests/unit/accounts.spec.js create mode 100644 exercises/07_forms_auth/tests/unit/index.specx.js diff --git a/.eslintrc.json b/.eslintrc.json index 8a289d4..e660b59 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -55,14 +55,15 @@ "prefer-const": 2, "quotes": [1, "single"], "semi": [1, "never"], - "space-before-blocks": ["error", "never"], + "space-before-blocks": ["error", { "functions": "always", "keywords": "always", "classes": "never" }], "space-before-function-paren": [2, "never"], "strict": [2, "global"], "yoda": 2 }, "overrides": [{ - "files": [ "*.test.js", "*.spec.js" ], + "files": [ "*.test.js", "*.spec.js", "sqlite-async.js" ], "rules": { + "global-require": "off", "max-lines-per-function": "off", "max-lines": "off", "max-statements": "off", diff --git a/exercises/07_forms_auth/__mocks__/sqlite-async-old.js b/exercises/07_forms_auth/__mocks__/sqlite-async-old.js new file mode 100644 index 0000000..46d7b6f --- /dev/null +++ b/exercises/07_forms_auth/__mocks__/sqlite-async-old.js @@ -0,0 +1,51 @@ + +'use strict' + +const records = [ + { + id: 0, + user: 'jdoe', + pass: '$2b$10$vPqO/uGlKchrQCqyBIKdb.8hLEJgaC4aAg4fpre5rausycX1XmkWy' + } +] + +module.exports.open = function() { + return { + all: async sql => { + console.log(`MOCK ${sql}`) + let field = sql.match(/(?<=SELECT\s+).*?(?=\s+FROM)/g)[0] + const condition = sql.match(/\bWHERE\s+(.*)$/g)[0].replace('WHERE ', '').replace(';', '') + const key = condition.split('=')[0].trim() + const val = condition.split('=')[1].replace(/"/g, '').trim() + console.log(`field: "${field}", condition: "${condition}", key: "${key}", val: "${val}"`) + if(field === 'count(id) AS count') field = 'id' + console.log(`field: "${field}"`) + let data = [] + console.log(`${field} : ${key} : ${val}`) + for(const record of records) { + //console.log(record) + console.log(record[field]) + console.log(`"${record[field]}" : "${val}"`) + if(record[field] == val) { + console.log('matching record') + data.push(record) + } + } + console.log(data) + let result = {} + console.log(`field ${field} length: ${field.length}`) + if(field === 'id') { + console.log('need count...') + result.count = data.length + } else { + console.log('need data...') + result[field] = records[0][field] + } + console.log(result) + return result + }, + run: async() => true, // we can just ignore these. + close: async() => true // pretend to close the database. + } +} + diff --git a/exercises/07_forms_auth/__mocks__/sqlite-async-x.js b/exercises/07_forms_auth/__mocks__/sqlite-async-x.js new file mode 100644 index 0000000..98b3969 --- /dev/null +++ b/exercises/07_forms_auth/__mocks__/sqlite-async-x.js @@ -0,0 +1,22 @@ + +'use strict' + +const sqlite = require('sqlite-async') + +module.exports.open = function() { + return { + all: async sql => { + console.log(`MOCK ${sql}`) + const db = await sqlite.open(':memory:') + await db.run('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, user TEXT, pass TEXT);') + const user = 'jdoe' + const pass = '$2b$10$vPqO/uGlKchrQCqyBIKdb.8hLEJgaC4aAg4fpre5rausycX1XmkWy' + await db.run(`INSERT INTO URLSearchParams(user, pass) VALUES("${user}", "${pass}");`) + const data = await db.all(sql) + await db.close() + return data + }, + run: async() => true, // we can just ignore these. + close: async() => true // pretend to close the database. + } +} diff --git a/exercises/07_forms_auth/modules/accounts.js b/exercises/07_forms_auth/modules/accounts.js index f944b6b..5bcd759 100644 --- a/exercises/07_forms_auth/modules/accounts.js +++ b/exercises/07_forms_auth/modules/accounts.js @@ -18,6 +18,7 @@ let bcrypt = require('bcrypt-promise'); */ async function runSQL(query) { try { + console.log(query) let DBName = "./website.db"; const db = await sqlite.open(DBName); const data = await db.all(query); diff --git a/exercises/07_forms_auth/package.json b/exercises/07_forms_auth/package.json index 8f7f282..7e0b8cf 100644 --- a/exercises/07_forms_auth/package.json +++ b/exercises/07_forms_auth/package.json @@ -4,12 +4,25 @@ "description": "", "main": "index.js", "scripts": { + "acceptance": "jest --coverage --detectOpenHandles", "jsdoc": "node_modules/.bin/jsdoc -c jsdoc.conf", "linter": "node_modules/.bin/eslint .", - "test": "jest --coverage --detectOpenHandles" + "test": "jest --coverage --detectOpenHandles", + "unit": "node_modules/.bin/jest --coverage --runInBand tests/unit/" }, "jest": { - "testEnvironment": "node" + "testEnvironment": "node", + "verbose": true, + "collectCoverage": true, + "coverageDirectory": "docs/coverage/", + "coverageThreshold": { + "global": { + "branches": 0, + "functions": 0, + "lines":0, + "statements": 0 + } + } }, "author": "", "license": "ISC", @@ -31,9 +44,11 @@ }, "devDependencies": { "eslint": "^5.15.2", + "http-status-codes": "^1.3.2", "jest": "^24.1.0", "jsdoc": "^3.5.5", "jsdoc-route-plugin": "^0.1.0", - "puppeteer": "^1.12.2" + "puppeteer": "^1.12.2", + "supertest": "^4.0.2" } } diff --git a/exercises/07_forms_auth/public/avatars/avatar.png b/exercises/07_forms_auth/public/avatars/avatar.png index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..125a38930a39455cbb6b1873b696050a6ca232c9 100644 GIT binary patch literal 56968 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 T#XL}^TZE;ds;g3^WE=560vv@b literal 0 HcmV?d00001 diff --git a/exercises/07_forms_auth/temp.js b/exercises/07_forms_auth/temp.js new file mode 100644 index 0000000..ea10ade --- /dev/null +++ b/exercises/07_forms_auth/temp.js @@ -0,0 +1,29 @@ + +'use strict' + +const records = [ + { + user: 'jdoe', + pass: '$2b$10$vPqO/uGlKchrQCqyBIKdb.8hLEJgaC4aAg4fpre5rausycX1XmkWy' + } +] + +//const sql = 'SELECT count(id) AS count FROM users WHERE user="jdoe";' +const sql = 'SELECT user FROM users WHERE user="jdoe"' +const field = sql.match(/(?<=SELECT\s+).*?(?=\s+FROM)/g)[0] +const condition = sql.match(/\bWHERE\s+(.*)$/g)[0].replace('WHERE ', '').replace(';', '') +const key = condition.split('=')[0] +const val = condition.split('=')[1].replace(/"/g, '') +console.log(field) +console.log(key) +console.log(val) + +let data = [] +for(const record of records) if(record[key] == val) data.push(record[key]) +let result = {} +if(field === 'count(id) AS count') { + result.count = data.length +} else { + result[field] = val +} +console.log(result) \ No newline at end of file diff --git a/exercises/07_forms_auth/test.sh b/exercises/07_forms_auth/test.sh index 57d20b9..f6c4ea0 100755 --- a/exercises/07_forms_auth/test.sh +++ b/exercises/07_forms_auth/test.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash node index.js& -npm run test +node_modules/.bin/jest --detectOpenHandles tests/acceptance/ kill %1 diff --git a/exercises/07_forms_auth/tests/auth.spec.js b/exercises/07_forms_auth/tests/acceptance/auth.spec.js similarity index 100% rename from exercises/07_forms_auth/tests/auth.spec.js rename to exercises/07_forms_auth/tests/acceptance/auth.spec.js diff --git a/exercises/07_forms_auth/tests/accounts.spec.js b/exercises/07_forms_auth/tests/accounts.spec.js deleted file mode 100644 index e69de29..0000000 diff --git a/exercises/07_forms_auth/tests/index.spec.js b/exercises/07_forms_auth/tests/index.spec.js deleted file mode 100644 index e69de29..0000000 diff --git a/exercises/07_forms_auth/tests/unit/accounts.spec.js b/exercises/07_forms_auth/tests/unit/accounts.spec.js new file mode 100644 index 0000000..ac9ff3a --- /dev/null +++ b/exercises/07_forms_auth/tests/unit/accounts.spec.js @@ -0,0 +1,62 @@ + +'use strict' + +const accounts = require('../../modules/accounts.js') +//jest.mock('sqlite-async') + +beforeAll( async() => { + console.log('Jest starting!') + // we insert a single user into the database + const sqlite = require('sqlite-async') + const bcrypt = require('bcrypt-promise') + const pass = await bcrypt.hash('goodPassword', 10) + const db = await sqlite.open('./website.db') + await db.run('DROP TABLE IF EXISTS users;') + await db.run('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, user TEXT, pass TEXT);') + console.log(`INSERT INTO users(user, pass) VALUES("jdoe", "${pass}"`) + await db.run(`INSERT INTO users(user, pass) VALUES("jdoe", "${pass}")`) + await db.close() + console.log('database built') +}) + +describe('checkCredentials()', () => { + test('returns true if valid username and password', async done => { + expect.assertions(1) + try { + const result = await accounts.checkCredentials('jdoe', 'goodPassword') + expect(result).toBe(true) + } catch(err) { + console.log(`ERROR: ${err.message}`) + } finally { + done() + } + }) + + test('throws error if invalid username', async done => { + expect.assertions(1) + try { + await accounts.checkCredentials('johndoe', 'goodPassword') + //expect(result).toBe(true) + } catch(err) { + expect(err.message).toBe('invalid username') + } finally { + done() + } + }) + + test('throws error if invalid password', async done => { + expect.assertions(1) + try { + await accounts.checkCredentials('jdoe', 'badPassword') + //expect(result).toBe(true) + } catch(err){ + expect(err.message).toBe('invalid password') + } finally { + done() + } + }) +}) + +describe('addUser()', () => { + // TODO +}) diff --git a/exercises/07_forms_auth/tests/unit/index.specx.js b/exercises/07_forms_auth/tests/unit/index.specx.js new file mode 100644 index 0000000..93f7ad4 --- /dev/null +++ b/exercises/07_forms_auth/tests/unit/index.specx.js @@ -0,0 +1,33 @@ + +'use strict' + +const request = require('supertest') +const status = require('http-status-codes') + +const server = require('../../index.js') + +beforeAll( async() => console.log('Jest starting!')) + +describe('GET /', () => { + // TODO +}) + +describe('GET /register', () => { + // TODO +}) + +describe('POST /register', () => { + // TODO +}) + +describe('GET /login', () => { + // TODO +}) + +describe('POST /login', () => { + // TODO +}) + +describe('GET /logout', () => { + // TODO +})