From bec14e5b06d3982806f54ae400b10cd16e2686ec Mon Sep 17 00:00:00 2001 From: Lawrence Sarpong Date: Mon, 14 May 2018 13:09:41 +0100 Subject: [PATCH] modularise saveProfileData quries relates #36 --- src/lib/makeFacCodeName.js | 10 ++ src/model/queries/addFacCodeReturnID.js | 8 ++ src/model/queries/getAllFacCodes.js | 5 + src/model/queries/getFacCodeID.js | 6 ++ src/model/queries/saveProfileData.js | 127 +++-------------------- src/model/queries/updateMemberDetails.js | 14 +++ src/test/db.test.js | 55 ++++++++++ 7 files changed, 113 insertions(+), 112 deletions(-) create mode 100644 src/lib/makeFacCodeName.js create mode 100644 src/model/queries/addFacCodeReturnID.js create mode 100644 src/model/queries/getAllFacCodes.js create mode 100644 src/model/queries/getFacCodeID.js create mode 100644 src/model/queries/updateMemberDetails.js diff --git a/src/lib/makeFacCodeName.js b/src/lib/makeFacCodeName.js new file mode 100644 index 0000000..0d798b7 --- /dev/null +++ b/src/lib/makeFacCodeName.js @@ -0,0 +1,10 @@ +const makeFacCodeName = (facCampus, facNumber) => { + const prefix = { + london: 'FAC', + nazareth: 'FACN', + gaza: 'FACG', + }[facCampus.toLowerCase()]; + return `${prefix}${facNumber}`; +}; + +module.exports = makeFacCodeName; diff --git a/src/model/queries/addFacCodeReturnID.js b/src/model/queries/addFacCodeReturnID.js new file mode 100644 index 0000000..0519cfd --- /dev/null +++ b/src/model/queries/addFacCodeReturnID.js @@ -0,0 +1,8 @@ +const dbConnection = require('../database/db_connection'); + +const addFacCodeReturnID = codeName => dbConnection.query( + 'INSERT INTO fac_code (code) VALUES ($1) RETURNING id', + [codeName], +).then(res => res[0]); + +module.exports = addFacCodeReturnID; diff --git a/src/model/queries/getAllFacCodes.js b/src/model/queries/getAllFacCodes.js new file mode 100644 index 0000000..dd26a11 --- /dev/null +++ b/src/model/queries/getAllFacCodes.js @@ -0,0 +1,5 @@ +const dbConnection = require('../database/db_connection'); + +const getAllFacCodes = () => dbConnection.query('SELECT * FROM fac_code'); + +module.exports = getAllFacCodes; diff --git a/src/model/queries/getFacCodeID.js b/src/model/queries/getFacCodeID.js new file mode 100644 index 0000000..4812928 --- /dev/null +++ b/src/model/queries/getFacCodeID.js @@ -0,0 +1,6 @@ +const dbConnection = require('../database/db_connection'); + +const getFacCodeID = codeName => dbConnection.query('SELECT id FROM fac_code WHERE code = $1', [codeName]) + .then(res => res[0]); + +module.exports = getFacCodeID; diff --git a/src/model/queries/saveProfileData.js b/src/model/queries/saveProfileData.js index 54c2d00..c22ae22 100644 --- a/src/model/queries/saveProfileData.js +++ b/src/model/queries/saveProfileData.js @@ -1,115 +1,18 @@ -const dbConnection = require('../database/db_connection'); +const addFacCodeReturnID = require('./addFacCodeReturnID'); +const getFacCodeID = require('./getFacCodeID'); +const updateMemberDetails = require('./updateMemberDetails'); +const makeFacCodeName = require('../../lib/makeFacCodeName'); -// const formData = { -// full_name: 'Helen', -// github_handle: 'helenzhou6', -// fac_campus: 'London', -// fac_number: '0', -// tech_stack: 'Java', -// linkedin_url: 'knowwhere.com', -// twitter_handle: 'helenTweetz', -// }; - -/* - * There are a number of steps required to save from data into the database. - * - * The form uses fac_number but the members table requires fac_code_id - * so a query is needed to get the id - * and INSERT INTO the table if what we are looking for does not exist - * - * With the fac_code_id and github_id (provided by router) we can update the - * the members table with the values needed and return the - * member id for member_tech_stack_table - * - * The form also provides tech_stack and there is a member_tech_stack table - * which requires a stack_id, member_id and optional order (I thick this should default to 1) - * - * A query is required to get the stack_id - * and INSERT INTO the table if what we are looking for does not exist - * - * To insert into member_tech_stack we need member_id and stack_id at the same time. - * Using Promise.all(), query updateMemberGetID and getTechStack - * use the response values to query and insert into member_tech_stack - * - * TODO: modularise queries in file and test -*/ - -// transform query result into an object -const toResObj = res => res[0]; - -// insert code into fac_code table and return id -const addFacCode = codeName => dbConnection.query( - 'INSERT INTO fac_code (code) VALUES ($1) RETURNING id', - [codeName], -).then(toResObj); - -// use form data to create fac code neame needed for fac_code table -const makeFacCodeName = (facCampus, facNumber) => { - const prefix = { - london: 'FAC', - nazareth: 'FACN', - gaza: 'FACG', - }[facCampus.toLowerCase()]; - return `${prefix}${facNumber}`; -}; - -// get fac code id for memeber table -const getFacCodeID = (facCampus, facNumber) => { - const codeName = makeFacCodeName(facCampus, facNumber); - return dbConnection.query('SELECT id FROM fac_code WHERE code = $1', [codeName]) - .then(res => res[0] || addFacCode(codeName)) - .then(o => o.id); -}; - -// query must be an update because a member is created during authentication -// the id returned is used to insert into member_tech_Stack -const updateMemberGetID = (formDataObj, facCodeID, githubID) => dbConnection.query(` - UPDATE members - SET full_name = $/full_name/, - github_handle = $/github_handle/, - fac_campus = $/fac_campus/, - fac_code_id = $/facCodeID/, - linkedin_url = $/linkedin_url/, - twitter_handle = $/twitter_handle/ - WHERE github_id = $/githubID/ RETURNING id - `, { ...formDataObj, facCodeID, githubID }) - .then(toResObj) - .then(res => ({ member_id: res.id })); - -// query will insert a tech to tech_stack table and return member_id object -const addTechStack = name => dbConnection.query( - 'INSERT INTO tech_stack (tech) VALUES ($1) RETURNING id', - [name], -).then(toResObj); - -// query will return the stack_id object of a tech and insert it if it does not exist -const getTechStackID = tech => dbConnection.query( - 'SELECT id FROM tech_stack WHERE tech = $1', - [tech], -) - .then(res => res[0] || addTechStack(tech)) - .then(res => ({ stack_id: res.id })); - -// transform promise.all()result array into an object -const promiseAllResultToObj = arr => arr.reduce((acc, curr) => Object.assign(acc, curr), {}); - -// insert member_id and stack_id into member_tech_stack -// need to handle error for when query tries to insert a stack that someone already has -const addMemberTechStack = idObj => dbConnection.query( - 'INSERT INTO member_tech_stack ($/this:name/) VALUES ($/this:list/) RETURNING *', - idObj, -) - .then(toResObj); - - -// module.exports = saveProfileData; -module.exports = (dataObj, githubID) => { +exports.saveProfileData = (dataObj, githubID) => { const objClone = JSON.parse(JSON.stringify(dataObj)); - return getFacCodeID(objClone.fac_campus, objClone.fac_number) - .then(facCodeID => Promise.all([ - updateMemberGetID(objClone, facCodeID, githubID), - getTechStackID(objClone.tech_stack), - ])) - .then(promiseAllResultToObj) - .then(addMemberTechStack); + const codeName = makeFacCodeName(objClone.fac_campus, objClone.fac_number); + return getFacCodeID(codeName) + .then((resObj) => { + if (Object.keys(resObj).length === 0) { + return addFacCodeReturnID(codeName); + } + return resObj; + }) + .then(facCodeID => updateMemberDetails(objClone, facCodeID.id, githubID)); }; + diff --git a/src/model/queries/updateMemberDetails.js b/src/model/queries/updateMemberDetails.js new file mode 100644 index 0000000..79d61bb --- /dev/null +++ b/src/model/queries/updateMemberDetails.js @@ -0,0 +1,14 @@ +const dbConnection = require('../database/db_connection'); + +const updateMemberDetails = (formDataObj, facCodeID, githubID) => dbConnection.query(` + UPDATE members + SET full_name = $/full_name/, + github_handle = $/github_handle/, + fac_campus = $/fac_campus/, + fac_code_id = $/facCodeID/, + linkedin_url = $/linkedin_url/, + twitter_handle = $/twitter_handle/ + WHERE github_id = $/githubID/ + `, { ...formDataObj, facCodeID, githubID }); + +module.exports = updateMemberDetails; diff --git a/src/test/db.test.js b/src/test/db.test.js index d62b38f..f3b9b48 100644 --- a/src/test/db.test.js +++ b/src/test/db.test.js @@ -4,6 +4,9 @@ const runDbBuild = require('../model/database/db_build_test'); const dbConnection = require('../model/database/db_connection'); const postMemberInfo = require('../model/queries/postMemberInfo.js'); const getMemberData = require('../model/queries/getMemberData.js'); +const getAllFacCodes = require('../model/queries/getAllFacCodes.js'); +const addFacCodeReturnID = require('../model/queries/addFacCodeReturnID'); +const getFacCodeID = require('../model/queries/getFacCodeID'); const selectAllMembers = 'SELECT * FROM members'; @@ -112,6 +115,58 @@ test('Test postMemberInfo adds a row', (t) => { }); }); +// ADD FACCODE +test('Add fac code to fac_code table and return id', (t) => { + const facCode = 'FAC13'; + let original; + runDbBuild() + .then(getAllFacCodes) + .then((res) => { + original = res; + }) + .then(() => addFacCodeReturnID(facCode)) + .then((res) => { + t.equal(typeof res, 'object', 'db response is an object'); + t.deepEqual(Object.keys(res), ['id'], 'res is an object containing an id'); + t.end(); + }) + .then(getAllFacCodes) + .then((res) => { + t.equal(res.length, original.length + 1, 'added one row to fac codes table'); + t.deepEqual(res[res.length - 1].code, facCode, 'added FAC13'); + }) + .catch((error) => { + t.error(error, 'no db error'); + t.end(); + }); +}); + +// getAllFacCodes +test('Test get all FAC codes', (t) => { + runDbBuild() + .then(() => getAllFacCodes()) + .then((res) => { + t.ok(Array.isArray(res), 'db response is an array'); + t.end(); + }) + .catch((error) => { + t.error(error, 'no db error'); + t.end(); + }); +}); + +// getFacCodeID +test('Test get fac code id', (t) => { + const facCode = 'FAC0'; + runDbBuild() + .then(() => getFacCodeID(facCode)) + .then((res) => { + t.equal(typeof res, 'object', 'db response is an object'); + t.deepEqual(Object.keys(res), ['id'], 'res is an object containing an id'); + t.end(); + }); +}); + test.onFinish(() => { dbConnection.$pool.end(); });