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 e69de29..125a389 100644 Binary files a/exercises/07_forms_auth/public/avatars/avatar.png and b/exercises/07_forms_auth/public/avatars/avatar.png differ 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 +})