Skip to content

Commit

Permalink
Merge pull request #34 from DFE-Digital/add-webhook-for-frameworks
Browse files Browse the repository at this point in the history
Add webhook service for published frameworks
  • Loading branch information
ryantk authored Jul 27, 2022
2 parents 9d3ba2b + 9b3f0d1 commit f07d34d
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 10 deletions.
2 changes: 0 additions & 2 deletions api/adaptors/mongodoc/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,6 @@ const structureModelSchema = new Schema({

const structure = async options => {
const { connectionString, collectionName } = options
mongoose.set('useCreateIndex', true)
mongoose.set('useFindAndModify', false)
const db = await mongoose.connect(connectionString, { useNewUrlParser: true }, err => {
if (err) {
throw new Error(errors.CONNECTION_ERROR)
Expand Down
2 changes: 1 addition & 1 deletion api/controllers/framework.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

const shared = require('./shared')

const frameworkController = (dataSource) => {
const frameworkController = (dataSource) => {
return {
list: (req, res) => {
dataSource.framework.list()
Expand Down
33 changes: 29 additions & 4 deletions api/controllers/structure.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
const shared = require('./shared')


const webhookService = require('../services/webhookService')

const structureController = (dataSource) => {
const populateFrameworkReferences = (frameworks, categories, providers) => {
const populatedFrameworks = frameworks.map(f => {
if (f.cat) {
f.cat = JSON.parse(JSON.stringify(categories.filter(c => c._id.toString() === f.cat.toString())[0]))
delete f.cat._id
}
if (f.provider) {
f.provider = JSON.parse(JSON.stringify(providers.filter(p => p._id.toString() === f.provider.toString())[0]))
delete f.provider._id
}
delete f._id
return f
})
return populatedFrameworks
}

const me = {
list: (req, res) => {
dataSource.structure.list()
Expand All @@ -21,14 +36,24 @@ const structureController = (dataSource) => {
},
put: (req, res) => {
dataSource.structure.put(req.params.structureId, req.body)
.then(results => res.send(results))
.then(results => {
res.send(results)
if (results.status === 'LIVE') {
const frameworks = results.framework.map(f => f.toJSON())
const categories = results.category.map(c => c.toJSON())
const providers = results.provider.map(p => p.toJSON())
const populatedFrameworks = populateFrameworkReferences(frameworks, categories, providers)
webhookService.send(populatedFrameworks)
}
})
.catch(err => shared.stdErrorResponse(res, err))
},
remove: (req, res) => {
dataSource.structure.remove(req.params.structureId)
.then(results => res.send(results))
.catch(err => shared.stdErrorResponse(res, err))
}
},
populateFrameworkReferences: populateFrameworkReferences
}

return me
Expand Down
27 changes: 27 additions & 0 deletions api/services/webhookService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const send = async (payload) => {
const https = require('https')

const data = JSON.stringify(payload)

const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(data),
'Authorization': `Token ${process.env.GHBS_WEBHOOK_SECRET}`
}
}

const req = https.request(process.env.GHBS_WEBHOOK_ENDPOINT, options, res => {
console.log(`statusCode: ${res.statusCode}`)
})

req.on('error', error => {
console.error(error)
})

req.write(data)
req.end()
}

module.exports = { send }
44 changes: 44 additions & 0 deletions api/test/api.structure.populateFrameworkReferences.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const mongoose = require('mongoose')
const chai = require('chai')

const testData = require('./testdata/frameworks.json')
const testProviderData = require('./testdata/providers.json')
const testCategoryData = require('./testdata/categories.json')

const expect = chai.expect
const setup = require('./setup')

describe('structureController', () => {
let structureController = require('../controllers/structure')
let testProviders = []
let testCategories = []
let testFrameworks = []

before(async () => {
const setupDone = await setup()
await setupDone.helpers.removeAllRecords('framework')
await setupDone.helpers.removeAllRecords('provider')
testProviders.push(await setupDone.helpers.createRecord('provider', testProviderData.spectre))
await setupDone.helpers.removeAllRecords('category')
testCategories.push(await setupDone.helpers.createRecord('category', testCategoryData.construction))
structureController = structureController(setupDone.dataSource)

const framework = JSON.parse(JSON.stringify(testData.builders))
framework.cat = mongoose.Types.ObjectId(testCategories[0].id)
framework.provider = mongoose.Types.ObjectId(testProviders[0].id)
testFrameworks.push(await setupDone.helpers.createRecord('framework', framework))
})

describe('populateFrameworkReferences', () => {
it('should return referenced objects and remove ids', done => {
let result = structureController.populateFrameworkReferences(testFrameworks.map(f => f.toJSON()), testCategories.map(c => c.toJSON()), testProviders.map(p => p.toJSON()))
expect(result.length).to.equal(1)
expect(result[0]).to.not.have.property('_id')
expect(result[0].cat).to.be.an('object')
expect(result[0].cat).to.not.have.property('_id')
expect(result[0].provider).to.be.an('object')
expect(result[0].provider).to.not.have.property('_id')
done()
})
})
})
49 changes: 49 additions & 0 deletions api/test/services.webhookService.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
const sinon = require('sinon')

const testData = require('./testdata/frameworks.json')

describe('webhookService', () => {
let https
let webhookService
let testFramework
let stub
let env

before(() => {
https = require('https')
stub = sinon.stub(https, 'request').returns({
on() {},
write() {},
end() {}
})
webhookService = require('../services/webhookService')
testFramework = testData.builders
env = process.env
process.env = {
GHBS_WEBHOOK_SECRET: 'secret',
GHBS_WEBHOOK_ENDPOINT: 'endpoint'
}
})

describe('send', () => {
it('sends a post request to the webhook endpoint', () => {
webhookService.send(testFramework)

const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': 664,
'Authorization': 'Token secret'
}
}

sinon.assert.calledOnce(https.request)
sinon.assert.calledWith(stub, 'endpoint', options, sinon.match.any)
})
})

after(() => {
process.env = env
})
})
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"dependencies": {
"body-parser": "^1.19.0",
"cors": "^2.8.5",
"eslint": "^6.1.0",
"express": "^4.17.1",
"express-basic-auth": "^1.2.0",
"govuk-frontend": "^2.13.0",
Expand All @@ -26,16 +27,16 @@
"lodash.template": ">=4.5.0",
"md5": "^2.2.1",
"moment": "^2.24.0",
"mongoose": "^5.5.13",
"node-sass": "^4.12.0",
"mongoose": "^5.13.14",
"query-string": "^6.8.1",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-redux": "^7.1.0",
"react-router-dom": "^5.0.1",
"react-scripts": "3.0.1",
"react-scripts": "3.1.1",
"redux": "^4.0.1",
"redux-thunk": "^2.3.0",
"sass": "^1.52.3",
"serve-static": "^1.14.1",
"url-join": "^4.0.1"
},
Expand Down Expand Up @@ -76,6 +77,7 @@
"node-env-run": "^3.0.2",
"nodemon": "^1.19.1",
"puppeteer": "^1.19.0",
"sinon": "^14.0.0",
"superagent": "^5.1.0"
}
}

0 comments on commit f07d34d

Please sign in to comment.