Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/fcrm 5441 #456

Merged
merged 10 commits into from
Jan 28, 2025
18 changes: 0 additions & 18 deletions .jest/setup.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,17 @@
jest.mock('../config/environment')
const createServer = require('../server')
const ORIGINAL_ENV = process.env
const CONSOLE_ERROR = console.error
const CONSOLE_LOG = console.log
const DEV_NULL_LOG = () => {}
let server

beforeEach(async () => {
jest.resetAllMocks()
// add any common mockage here, eg json POSTs
server = await createServer()
await server.initialize()
if (process.env.NOLOG) {
console.log = DEV_NULL_LOG
console.error = DEV_NULL_LOG
}
})

afterEach(async () => {
try {
if (server) {
await server.stop()
}
} finally {
// reset environment variables after test
process.env = { ...ORIGINAL_ENV }
}
console.log = CONSOLE_LOG
console.error = CONSOLE_ERROR
})

const getServer = () => server

export { getServer }
35 changes: 33 additions & 2 deletions __mocks__/@esri/arcgis-rest-request.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

let expectedParameters
const response = {
token: 'TEST_TOKEN',
refreshToken: () => {
Expand All @@ -14,4 +14,35 @@ const ApplicationCredentialsManager = {
fromCredentials: () => (response)
}

module.exports = { ApplicationCredentialsManager, _invalidateToken, _resetToken }
const requestSpy = {
expectParameters: (params) => { expectedParameters = params }
}

const request = async (url, requestObject) => {
if (expectedParameters) {
expect(url).toEqual(expectedParameters.url)
expect(requestObject).toEqual(expectedParameters.requestObject)
}
return {
layers: [
{
id: 0,
count: 0
}, {
id: 1,
count: 0
}, {
id: 2,
count: 0
}
]
}
}

module.exports = {
ApplicationCredentialsManager,
_invalidateToken,
_resetToken,
request,
requestSpy
}
5 changes: 1 addition & 4 deletions config/.env-example
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,7 @@ placeApiUrl=http://dummyuri
agolClientId=TEST_AGOL_CLIENT_ID
agolClientSecret=TEST_AGOL_CLIENT_SECRET
agolServiceId=DUMMY_SERVICE_ID
agolCustomerTeamEndPoint=/Flood_Map_for_Planning_Query_Service_NON_PRODUCTION/FeatureServer/0
agolLocalAuthorityEndPoint=/Flood_Map_for_Planning_Query_Service_NON_PRODUCTION/FeatureServer/1
agolIsEnglandEndPoint=/Flood_Map_for_Planning_Query_Service_NON_PRODUCTION/FeatureServer/2
agolFloodZonesRiversAndSeaEndPoint=/Flood_Zones_2_and_3_Rivers_and_Sea_NON_PRODUCTION/FeatureServer/0

#EA Maps
eamapsServiceUrl=http://dummyEAMapslUrl
eamapsProduct1User=PRODUCT1_USER
Expand Down
72 changes: 69 additions & 3 deletions config/__tests__/config.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
const { toBool } = require('../toBool')

describe('Ensure config is correct', () => {
beforeEach(() => {
jest.resetModules()
})
it('test config', () => {
expect(() => {
require('../index')
Expand Down Expand Up @@ -41,7 +44,72 @@ describe('Ensure config is correct', () => {
customerTeamEndPoint: '/Flood_Map_for_Planning_Query_Service_NON_PRODUCTION/FeatureServer/0',
localAuthorityEndPoint: '/Flood_Map_for_Planning_Query_Service_NON_PRODUCTION/FeatureServer/1',
isEnglandEndPoint: '/Flood_Map_for_Planning_Query_Service_NON_PRODUCTION/FeatureServer/2',
floodZonesRiversAndSeaEndPoint: '/Flood_Zones_2_and_3_Rivers_and_Sea_NON_PRODUCTION/FeatureServer/0'
floodZonesRiversAndSeaEndPoint: '/Flood_Zones_2_and_3_Rivers_and_Sea_NON_PRODUCTION/FeatureServer/0',
riversAndSeaDefendedEndPoint: '/Rivers_and_Sea_Defended_Depth_NON_PRODUCTION/FeatureServer',
riversAndSeaUndefendedEndPoint: '/Rivers_and_Sea_Undefended_Depth_NON_PRODUCTION/FeatureServer',
riversAndSeaDefendedCCP1EndPoint: '/Rivers_and_Sea_Defended_Depth_CCP1_NON_PRODUCTION/FeatureServer',
riversAndSeaUndefendedCCP1EndPoint: '/Rivers_and_Sea_Undefended_Depth_CCP1_NON_PRODUCTION/FeatureServer',
surfaceWaterEndPoint: '/Risk_of_Flooding_from_Surface_Water_Depth_0mm_NON_PRODUCTION/FeatureServer/0'
},
eamaps: {
serviceUrl: 'http://dummyEAMapslUrl',
product1User: 'PRODUCT1_USER',
product1Password: 'PRODUCT1_PASSWORD',
product1EndPoint: '/rest/services/FMfP/FMFPGetProduct1/GPServer/fmfp_get_product1/execute',
tokenEndPoint: '/tokens/generateToken'
},
defraMap: {
layerNameSuffix: '_NON_PRODUCTION'
},
riskAdminApi: {
url: 'http://riskadmin-api-url'
}
}
expect(config).toStrictEqual(expectedConfig)
})

it('test config values in production', () => {
jest.resetModules()
process.env.ENV = 'prod-green'
const { config } = require('../index')
const expectedConfig = {
env: 'prod-green',
appType: 'internal',
server: { port: '8050' },
geoserver: 'http://dummyuri',
views: { isCached: false },
analyticsAccount: 'replace_this',
googleVerification: 'replace_this',
fbAppId: 'replace_this',
httpTimeoutMs: '3000',
ordnanceSurvey: {
osGetCapabilitiesUrl: 'http://dummyuri',
osMapsUrl: 'http://dummyuri',
osNamesUrl: 'http://dummyuri',
osSearchKey: 'replace_this',
osMapsKey: 'replace_this',
osClientId: 'replace_this',
osClientSecret: 'replace_this'
},
siteUrl: 'http://dummyuri',
functionAppUrl: 'http://dummyuri',
ignoreUseAutomatedService: true,
placeApi: { url: 'http://dummyuri' },
agol: {
clientId: 'TEST_AGOL_CLIENT_ID',
clientSecret: 'TEST_AGOL_CLIENT_SECRET',
serviceId: 'DUMMY_SERVICE_ID',
serviceUrl: 'https://services1.arcgis.com/DUMMY_SERVICE_ID/arcgis/rest/services',
vectorTileUrl: 'https://tiles.arcgis.com/tiles/DUMMY_SERVICE_ID/arcgis/rest/services',
customerTeamEndPoint: '/Flood_Map_for_Planning_Query_Service/FeatureServer/0',
localAuthorityEndPoint: '/Flood_Map_for_Planning_Query_Service/FeatureServer/1',
isEnglandEndPoint: '/Flood_Map_for_Planning_Query_Service/FeatureServer/2',
floodZonesRiversAndSeaEndPoint: '/Flood_Zones_2_and_3_Rivers_and_Sea/FeatureServer/0',
riversAndSeaDefendedEndPoint: '/Rivers_and_Sea_Defended_Depth/FeatureServer',
riversAndSeaUndefendedEndPoint: '/Rivers_and_Sea_Undefended_Depth/FeatureServer',
riversAndSeaDefendedCCP1EndPoint: '/Rivers_and_Sea_Defended_Depth_CCP1/FeatureServer',
riversAndSeaUndefendedCCP1EndPoint: '/Rivers_and_Sea_Undefended_Depth_CCP1/FeatureServer',
surfaceWaterEndPoint: '/Risk_of_Flooding_from_Surface_Water_Depth_0mm/FeatureServer/0'
},
eamaps: {
serviceUrl: 'http://dummyEAMapslUrl',
Expand All @@ -51,8 +119,6 @@ describe('Ensure config is correct', () => {
tokenEndPoint: '/tokens/generateToken'
},
defraMap: {
agolServiceUrl: 'https://services1.arcgis.com/DUMMY_SERVICE_ID/arcgis/rest/services',
agolVectorTileUrl: 'https://tiles.arcgis.com/tiles/DUMMY_SERVICE_ID/arcgis/rest/services',
layerNameSuffix: '_NON_PRODUCTION'
},
riskAdminApi: {
Expand Down
37 changes: 33 additions & 4 deletions config/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,30 @@ const { validateSchema } = require('./schema')
const { toBool } = require('./toBool')
require('./environment')

const agolEndpoints = {
customerTeamEndPoint: '/Flood_Map_for_Planning_Query_Service_NON_PRODUCTION/FeatureServer/0',
localAuthorityEndPoint: '/Flood_Map_for_Planning_Query_Service_NON_PRODUCTION/FeatureServer/1',
isEnglandEndPoint: '/Flood_Map_for_Planning_Query_Service_NON_PRODUCTION/FeatureServer/2',
floodZonesRiversAndSeaEndPoint: '/Flood_Zones_2_and_3_Rivers_and_Sea_NON_PRODUCTION/FeatureServer/0',
riversAndSeaDefendedEndPoint: '/Rivers_and_Sea_Defended_Depth_NON_PRODUCTION/FeatureServer',
riversAndSeaUndefendedEndPoint: '/Rivers_and_Sea_Undefended_Depth_NON_PRODUCTION/FeatureServer',
riversAndSeaDefendedCCP1EndPoint: '/Rivers_and_Sea_Defended_Depth_CCP1_NON_PRODUCTION/FeatureServer',
riversAndSeaUndefendedCCP1EndPoint: '/Rivers_and_Sea_Undefended_Depth_CCP1_NON_PRODUCTION/FeatureServer',
surfaceWaterEndPoint: '/Risk_of_Flooding_from_Surface_Water_Depth_0mm_NON_PRODUCTION/FeatureServer/0'
}

const isProduction = () => {
return process.env.ENV === 'prd' ||
process.env.ENV === 'production' ||
process.env.ENV === 'prod' ||
process.env.ENV === 'prod-green' ||
process.env.ENV === 'prod-blue'
}

const productioniseEndpoint = (endpoint) => {
return isProduction() ? endpoint.replace('_NON_PRODUCTION', '') : endpoint
}

const config = {
env: process.env.ENV,
appType: process.env.fmpAppType,
Expand Down Expand Up @@ -37,10 +61,15 @@ const config = {
serviceId: process.env.agolServiceId,
serviceUrl: `https://services1.arcgis.com/${process.env.agolServiceId}/arcgis/rest/services`,
vectorTileUrl: `https://tiles.arcgis.com/tiles/${process.env.agolServiceId}/arcgis/rest/services`,
customerTeamEndPoint: process.env.agolCustomerTeamEndPoint,
localAuthorityEndPoint: process.env.agolLocalAuthorityEndPoint,
isEnglandEndPoint: process.env.agolIsEnglandEndPoint,
floodZonesRiversAndSeaEndPoint: process.env.agolFloodZonesRiversAndSeaEndPoint
customerTeamEndPoint: productioniseEndpoint(agolEndpoints.customerTeamEndPoint),
localAuthorityEndPoint: productioniseEndpoint(agolEndpoints.localAuthorityEndPoint),
isEnglandEndPoint: productioniseEndpoint(agolEndpoints.isEnglandEndPoint),
floodZonesRiversAndSeaEndPoint: productioniseEndpoint(agolEndpoints.floodZonesRiversAndSeaEndPoint),
riversAndSeaDefendedEndPoint: productioniseEndpoint(agolEndpoints.riversAndSeaDefendedEndPoint),
riversAndSeaUndefendedEndPoint: productioniseEndpoint(agolEndpoints.riversAndSeaUndefendedEndPoint),
riversAndSeaDefendedCCP1EndPoint: productioniseEndpoint(agolEndpoints.riversAndSeaDefendedCCP1EndPoint),
riversAndSeaUndefendedCCP1EndPoint: productioniseEndpoint(agolEndpoints.riversAndSeaUndefendedCCP1EndPoint),
surfaceWaterEndPoint: productioniseEndpoint(agolEndpoints.surfaceWaterEndPoint)
},
eamaps: {
serviceUrl: process.env.eamapsServiceUrl,
Expand Down
7 changes: 6 additions & 1 deletion config/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,12 @@ const schema = Joi.object({
customerTeamEndPoint: Joi.string().required(),
localAuthorityEndPoint: Joi.string().required(),
isEnglandEndPoint: Joi.string().required(),
floodZonesRiversAndSeaEndPoint: Joi.string().required()
floodZonesRiversAndSeaEndPoint: Joi.string().required(),
riversAndSeaDefendedEndPoint: Joi.string().required(),
riversAndSeaUndefendedEndPoint: Joi.string().required(),
riversAndSeaDefendedCCP1EndPoint: Joi.string().required(),
riversAndSeaUndefendedCCP1EndPoint: Joi.string().required(),
surfaceWaterEndPoint: Joi.string().required()
},
eamaps: {
serviceUrl: Joi.string().uri().required(),
Expand Down
20 changes: 17 additions & 3 deletions server/__test-helpers__/server.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
const { getServer } = require('../../.jest/setup')
const constants = require('../constants')
const createServer = require('../../server')
let server

beforeEach(async () => {
server = await createServer()
await server.initialize()
})

afterEach(async () => {
await server.stop()
})

const getServer = () => server

const submitGetRequest = async (options, header, expectedResponseCode = constants.statusCodes.OK) => {
options.method = 'GET'
Expand All @@ -13,7 +25,8 @@ const submitGetRequest = async (options, header, expectedResponseCode = constant

const submitPostRequest = async (options, expectedResponseCode = constants.statusCodes.REDIRECT) => {
options.method = 'POST'
return submitRequest(options, expectedResponseCode)
const response = await submitRequest(options, expectedResponseCode)
return response
}

const submitPostRequestExpectHandledError = async (options, errorMessage) => {
Expand Down Expand Up @@ -45,5 +58,6 @@ module.exports = {
submitGetRequest,
submitPostRequest,
submitPostRequestExpectHandledError,
submitPostRequestExpectServiceError
submitPostRequestExpectServiceError,
getServer
}
4 changes: 3 additions & 1 deletion server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ async function createServer () {
]
})

// Cached server methods
await server.method(require('./services/pso-contact'))
await server.method(require('./services/pso-contact-by-polygon'))
await server.method(require('./services/flood-zones-by-polygon'))
await server.method(require('./services/floodDataByPolygon'))
await server.method(require('./services/floodZoneByPolygon'))
await server.method(require('./services/use-automated'))

// Register the plugins
Expand Down
21 changes: 11 additions & 10 deletions server/routes/__tests__/check-your-details.spec.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
const { getServer } = require('../../../.jest/setup')
const { assertCopy } = require('../../__test-helpers__/copy')
const {
submitGetRequest,
submitPostRequest
submitPostRequest,
getServer
} = require('../../__test-helpers__/server')
const { mockPolygons } = require('../../services/__tests__/__mocks__/floodZonesByPolygonMock')
const { mockPolygons } = require('../../services/__tests__/__mocks__/floodZoneByPolygonMock')
const { getCentreOfPolygon } = require('../../services/shape-utils')
jest.mock('../../services/agol/getContacts')
jest.mock('../../services/address')
jest.mock('@hapi/wreck')
const wreck = require('@hapi/wreck')
const user = {
fullName: 'John Smith',
email: '[email protected]'
}

const url = '/check-your-details'
let postSpy

describe('Check your details page', () => {
beforeEach(() => {
wreck.post.mockResolvedValue({
payload: {
applicationReferenceNumber: '12345',
nextTask: 'SEND_CONFIRMATION_EMAIL'
postSpy = jest.spyOn(wreck, 'post').mockImplementation(() => {
return {
payload: {
applicationReferenceNumber: '12345',
nextTask: 'SEND_CONFIRMATION_EMAIL'
}
}
})
})
Expand Down Expand Up @@ -123,7 +124,7 @@ describe('Check your details page', () => {
postcode: 'M1 1AA'
})

expect(wreck.post).toHaveBeenCalledWith('http://dummyuri/order-product-four', { json: true, payload: expectedPayload })
expect(postSpy).toHaveBeenCalledWith('http://dummyuri/order-product-four', { json: true, payload: expectedPayload })
}
})
})
Expand Down
2 changes: 1 addition & 1 deletion server/routes/__tests__/results.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { submitGetRequest } = require('../../__test-helpers__/server')
const { assertCopy } = require('../../__test-helpers__/copy')
const { mockPolygons } = require('../../services/__tests__/__mocks__/floodZonesByPolygonMock')
const { mockPolygons } = require('../../services/__tests__/__mocks__/floodDataByPolygonMock')
const { config } = require('../../../config')
jest.mock('../../services/agol/getContacts')

Expand Down
9 changes: 2 additions & 7 deletions server/routes/check-your-details.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ const getFunctionAppResponse = async (data) => {
return wreck.post(publishToQueueURL, { json: true, payload: JSON.stringify(payload) })
}

const floodZoneResultsToFloodZone = (floodZoneResults) =>
floodZoneResults.floodzone_3 ? '3' : floodZoneResults.floodzone_2 ? '2' : '1'

module.exports = [
{
method: 'GET',
Expand All @@ -26,8 +23,7 @@ module.exports = [
description: 'Application Review Summary',
handler: async (request, h) => {
const { polygon, fullName, recipientemail } = request.query
const floodZoneResults = await request.server.methods.getFloodZonesByPolygon(polygon)
const floodZone = floodZoneResultsToFloodZone(floodZoneResults)
const { floodZone } = await request.server.methods.getFloodZoneByPolygon(polygon)
const contactUrl = `/contact?polygon=${polygon}&fullName=${fullName}&recipientemail=${recipientemail}`
const confirmLocationUrl = `confirm-location?fullName=${fullName}&recipientemail=${recipientemail}`
return h.view('check-your-details', { polygon, fullName, recipientemail, contactUrl, confirmLocationUrl, floodZone })
Expand All @@ -43,8 +39,7 @@ module.exports = [
const payload = request.payload || {}
const { recipientemail, fullName, polygon } = payload
const coordinates = getCentreOfPolygon(polygon)
const floodZoneResults = await request.server.methods.getFloodZonesByPolygon(polygon)
const zoneNumber = floodZoneResultsToFloodZone(floodZoneResults)
const { floodZone: zoneNumber } = await request.server.methods.getFloodZoneByPolygon(polygon)
let applicationReferenceNumber

// Check if p4Request is duplicate
Expand Down
2 changes: 1 addition & 1 deletion server/routes/flood-zone-results.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ module.exports = [
if (!request.server.methods.ignoreUseAutomatedService()) {
useAutomatedService = contactDetails.useAutomatedService
}
const floodZoneResults = await request.server.methods.getFloodZonesByPolygon(polygon)
const floodZoneResults = await request.server.methods.getFloodDataByPolygon(polygon)

const plotSize = getAreaInHectares(polygon)
const floodZoneResultsData = new FloodRiskView.Model({
Expand Down
Loading
Loading