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

VB-3391 Add DPS footer component #726

Merged
merged 3 commits into from
Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ API_CLIENT_SECRET=clientsecret
SYSTEM_CLIENT_ID=clientid
SYSTEM_CLIENT_SECRET=clientsecret

COMPONENT_API_URL="https://frontend-components-dev.hmpps.service.justice.gov.uk"
NOMIS_USER_ROLES_API_URL="https://nomis-user-roles-api-dev.prison.service.justice.gov.uk"
ORCHESTRATION_API_URL="https://hmpps-manage-prison-visits-orchestration-dev.prison.service.justice.gov.uk"
PRISONER_SEARCH_API_URL="https://prisoner-search-dev.prison.service.justice.gov.uk"
Expand Down
1 change: 1 addition & 0 deletions assets/sass/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ $govuk-page-width: $moj-page-width;
@import './components/block-background';
@import './components/date-picker';
@import './components/filter';
@import './components/footer';
@import './components/notificationTypes';
@import './components/prisoner-profile';
@import './components/restrictions';
Expand Down
3 changes: 3 additions & 0 deletions assets/sass/components/_footer.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.govuk-footer {
min-height: 160px;
}
2 changes: 2 additions & 0 deletions cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { defineConfig } from 'cypress'
import { resetStubs } from './integration_tests/mockApis/wiremock'

import auth from './integration_tests/mockApis/auth'
import frontendComponents from './integration_tests/mockApis/frontendComponents'
import manageUsersApi from './integration_tests/mockApis/manageUsersApi'
import tokenVerification from './integration_tests/mockApis/tokenVerification'
import nomisUserRoles from './integration_tests/mockApis/nomisUserRoles'
Expand Down Expand Up @@ -32,6 +33,7 @@ export default defineConfig({
...manageUsersApi,
...tokenVerification,

...frontendComponents,
...nomisUserRoles,
...orchestrationService,
...prisonerContactRegistry,
Expand Down
1 change: 1 addition & 0 deletions feature.env
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ SYSTEM_CLIENT_ID=clientid
SYSTEM_CLIENT_SECRET=clientsecret
FEATURE_REVIEW_BOOKINGS=true

COMPONENT_API_URL=http://localhost:9091/frontendComponents
NOMIS_USER_ROLES_API_URL=http://localhost:9091/nomisUserRoles
ORCHESTRATION_API_URL=http://localhost:9091/orchestration
PRISONER_SEARCH_API_URL=http://localhost:9091/offenderSearch
Expand Down
1 change: 1 addition & 0 deletions helm_deploy/values-dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ generic-service:
PRISONER_CONTACT_REGISTRY_API_URL: "https://prisoner-contact-registry-dev.prison.service.justice.gov.uk"
WHEREABOUTS_API_URL: "https://whereabouts-api-dev.service.justice.gov.uk"
PRISON_REGISTER_API_URL: "https://prison-register-dev.hmpps.service.justice.gov.uk"
COMPONENT_API_URL: https://frontend-components-dev.hmpps.service.justice.gov.uk
DPS_URL: "https://digital-dev.prison.service.justice.gov.uk/"
REDIS_KEY: "bapv-staff-dev"
FEATURE_REVIEW_BOOKINGS: "true"
Expand Down
1 change: 1 addition & 0 deletions helm_deploy/values-preprod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ generic-service:
PRISONER_CONTACT_REGISTRY_API_URL: "https://prisoner-contact-registry-preprod.prison.service.justice.gov.uk"
WHEREABOUTS_API_URL: "https://whereabouts-api-preprod.service.justice.gov.uk"
PRISON_REGISTER_API_URL: "https://prison-register-preprod.hmpps.service.justice.gov.uk"
COMPONENT_API_URL: https://frontend-components-preprod.hmpps.service.justice.gov.uk
DPS_URL: "https://digital-preprod.prison.service.justice.gov.uk/"
REDIS_KEY: "bapv-staff-preprod"
FEATURE_REVIEW_BOOKINGS: "true"
Expand Down
1 change: 1 addition & 0 deletions helm_deploy/values-prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ generic-service:
PRISONER_CONTACT_REGISTRY_API_URL: "https://prisoner-contact-registry.prison.service.justice.gov.uk"
WHEREABOUTS_API_URL: "https://whereabouts-api.service.justice.gov.uk"
PRISON_REGISTER_API_URL: "https://prison-register.hmpps.service.justice.gov.uk"
COMPONENT_API_URL: https://frontend-components.hmpps.service.justice.gov.uk
DPS_URL: "https://digital.prison.service.justice.gov.uk/"
REDIS_KEY: "bapv-staff-prod"
FEATURE_REVIEW_BOOKINGS: "true"
Expand Down
1 change: 1 addition & 0 deletions helm_deploy/values-staging.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ generic-service:
PRISONER_CONTACT_REGISTRY_API_URL: "https://prisoner-contact-registry-staging.prison.service.justice.gov.uk"
WHEREABOUTS_API_URL: "https://whereabouts-api-dev.service.justice.gov.uk"
PRISON_REGISTER_API_URL: "https://prison-register-dev.hmpps.service.justice.gov.uk"
COMPONENT_API_URL: https://frontend-components-dev.hmpps.service.justice.gov.uk
DPS_URL: "https://digital-dev.prison.service.justice.gov.uk/"
APPLICATIONINSIGHTS_CONNECTION_STRING: null # disable App Insights for staging
REDIS_KEY: "bapv-staff-staging"
Expand Down
1 change: 1 addition & 0 deletions integration_tests/integration/bookAVisit.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ context('Book a visit', () => {
beforeEach(() => {
cy.task('reset')
cy.task('stubSignIn')
cy.task('stubFrontendComponents')
cy.task('stubManageUser')
cy.task('stubSupportedPrisonIds')
cy.task('stubPrisonNames')
Expand Down
1 change: 1 addition & 0 deletions integration_tests/integration/cancelVisit.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ context('Cancel visit journey', () => {
beforeEach(() => {
cy.task('reset')
cy.task('stubSignIn')
cy.task('stubFrontendComponents')
cy.task('stubManageUser')
cy.task('stubSupportedPrisonIds')
cy.task('stubPrisonNames')
Expand Down
1 change: 1 addition & 0 deletions integration_tests/integration/changeEstablishment.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ context('Change establishment', () => {
beforeEach(() => {
cy.task('reset')
cy.task('stubSignIn')
cy.task('stubFrontendComponents')
cy.task('stubManageUser')
cy.task('stubSupportedPrisonIds')
cy.task('stubPrisonNames')
Expand Down
1 change: 1 addition & 0 deletions integration_tests/integration/checkYourBooking.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ context('Check visit details page', () => {
beforeEach(() => {
cy.task('reset')
cy.task('stubSignIn')
cy.task('stubFrontendComponents')
cy.task('stubManageUser')
cy.task('stubSupportedPrisonIds')
cy.task('stubPrisonNames')
Expand Down
1 change: 1 addition & 0 deletions integration_tests/integration/datePicker.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ context('Date picker', () => {
beforeEach(() => {
cy.task('reset')
cy.task('stubSignIn')
cy.task('stubFrontendComponents')
cy.task('stubManageUser')
cy.task('stubSupportedPrisonIds')
cy.task('stubPrisonNames')
Expand Down
33 changes: 33 additions & 0 deletions integration_tests/integration/frontendComponents.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import TestData from '../../server/routes/testutils/testData'
import HomePage from '../pages/home'
import Page from '../pages/page'

context('Frontend components', () => {
const notificationCount = TestData.notificationCount()

beforeEach(() => {
cy.task('reset')
cy.task('stubSignIn')
cy.task('stubManageUser')
cy.task('stubSupportedPrisonIds')
cy.task('stubPrisonNames')
cy.task('stubGetPrison')
cy.task('stubGetNotificationCount', { notificationCount })
})

it('should render the footer from the frontend components', () => {
cy.task('stubFrontendComponents')
cy.signIn()

Page.verifyOnPage(HomePage)
cy.get('footer').contains('Footer component')
})

it('should render the fallback footer when frontend components load fails', () => {
cy.task('stubFrontendComponentsFail')
cy.signIn()

Page.verifyOnPage(HomePage)
cy.get('footer').should('not.contain.text', 'Footer component')
})
})
1 change: 1 addition & 0 deletions integration_tests/integration/home.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ context('Home page', () => {
beforeEach(() => {
cy.task('reset')
cy.task('stubSignIn')
cy.task('stubFrontendComponents')
cy.task('stubManageUser')
cy.task('stubSupportedPrisonIds')
cy.task('stubPrisonNames')
Expand Down
1 change: 1 addition & 0 deletions integration_tests/integration/login.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ context('SignIn', () => {
beforeEach(() => {
cy.task('reset')
cy.task('stubSignIn')
cy.task('stubFrontendComponents')
cy.task('stubManageUser')
cy.task('stubSupportedPrisonIds')
cy.task('stubPrisonNames')
Expand Down
1 change: 1 addition & 0 deletions integration_tests/integration/prisonerProfile.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ context('Prisoner profile page', () => {
beforeEach(() => {
cy.task('reset')
cy.task('stubSignIn')
cy.task('stubFrontendComponents')
cy.task('stubManageUser')
cy.task('stubSupportedPrisonIds')
cy.task('stubPrisonNames')
Expand Down
1 change: 1 addition & 0 deletions integration_tests/integration/review.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ context('Bookings review page', () => {
beforeEach(() => {
cy.task('reset')
cy.task('stubSignIn')
cy.task('stubFrontendComponents')
cy.task('stubManageUser')
cy.task('stubSupportedPrisonIds')
cy.task('stubPrisonNames')
Expand Down
1 change: 1 addition & 0 deletions integration_tests/integration/searchForABooking.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ context('Search for a booking by reference', () => {
beforeEach(() => {
cy.task('reset')
cy.task('stubSignIn')
cy.task('stubFrontendComponents')
cy.task('stubManageUser')
cy.task('stubSupportedPrisonIds')
cy.task('stubPrisonNames')
Expand Down
1 change: 1 addition & 0 deletions integration_tests/integration/searchForAPrisoner.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ context('Search for a prisoner', () => {
beforeEach(() => {
cy.task('reset')
cy.task('stubSignIn')
cy.task('stubFrontendComponents')
cy.task('stubManageUser')
cy.task('stubSupportedPrisonIds')
cy.task('stubPrisonNames')
Expand Down
1 change: 1 addition & 0 deletions integration_tests/integration/updateAVisit.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ context('Update a visit', () => {
beforeEach(() => {
cy.task('reset')
cy.task('stubSignIn')
cy.task('stubFrontendComponents')
cy.task('stubManageUser')
cy.task('stubSupportedPrisonIds')
cy.task('stubPrisonNames')
Expand Down
1 change: 1 addition & 0 deletions integration_tests/integration/visitDetails.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ context('Visit details page', () => {
beforeEach(() => {
cy.task('reset')
cy.task('stubSignIn')
cy.task('stubFrontendComponents')
cy.task('stubManageUser')
cy.task('stubSupportedPrisonIds')
cy.task('stubPrisonNames')
Expand Down
1 change: 1 addition & 0 deletions integration_tests/integration/visitTimetable.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ context('View visit schedule timetable', () => {
beforeEach(() => {
cy.task('reset')
cy.task('stubSignIn')
cy.task('stubFrontendComponents')
cy.task('stubManageUser')
cy.task('stubSupportedPrisonIds')
cy.task('stubPrisonNames')
Expand Down
1 change: 1 addition & 0 deletions integration_tests/integration/visitsByDate.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ context('View visits by date', () => {
beforeEach(() => {
cy.task('reset')
cy.task('stubSignIn')
cy.task('stubFrontendComponents')
cy.task('stubManageUser')
cy.task('stubSupportedPrisonIds')
cy.task('stubPrisonNames')
Expand Down
36 changes: 36 additions & 0 deletions integration_tests/mockApis/frontendComponents.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { SuperAgentRequest } from 'superagent'
import { stubFor } from './wiremock'

export default {
stubFrontendComponents: (): SuperAgentRequest => {
return stubFor({
request: {
method: 'GET',
url: '/frontendComponents/components?component=footer',
},
response: {
status: 200,
headers: { 'Content-Type': 'application/json;charset=UTF-8' },
jsonBody: {
footer: {
html: '<footer class="govuk-footer"><div class="govuk-width-container">Footer component</div></footer>',
css: [],
javascript: [],
},
},
},
})
},

stubFrontendComponentsFail: () => {
return stubFor({
request: {
method: 'GET',
url: '/frontendComponents/components?component=footer',
},
response: {
status: 500,
},
})
},
}
3 changes: 3 additions & 0 deletions server/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import timetableRoutes from './routes/timetable'
import visitRoutes from './routes/visit'
import visitsRoutes from './routes/visits'
import type { Services } from './services'
import getFrontendComponents from './middleware/setupFrontendComponents'

export default function createApp(services: Services): express.Application {
const app = express()
Expand All @@ -46,6 +47,8 @@ export default function createApp(services: Services): express.Application {
app.use(setUpCurrentUser(services))
app.use(appInsightsOperationId)

app.get('*', getFrontendComponents(services))

app.use('/', indexRoutes(services))
app.use('/book-a-visit', bookAVisitRoutes(services))
app.use('/change-establishment', establishmentRoutes(services))
Expand Down
8 changes: 8 additions & 0 deletions server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,14 @@ export default {
},
agent: new AgentConfig(Number(get('ORCHESTRATION_API_TIMEOUT_RESPONSE', 10000))),
},
frontendComponents: {
url: get('COMPONENT_API_URL', 'http://localhost:8082/frontend-components', requiredInProduction),
timeout: {
response: Number(get('FRONTEND_COMPONENTS_TIMEOUT_RESPONSE', 3000)),
deadline: Number(get('FRONTEND_COMPONENTS_TIMEOUT_DEADLINE', 3000)),
},
agent: new AgentConfig(Number(get('FRONTEND_COMPONENTS_TIMEOUT_RESPONSE', 3000))),
},
},
features: {
reviewBookings: get('FEATURE_REVIEW_BOOKINGS', 'false', requiredInProduction) === 'true',
Expand Down
36 changes: 36 additions & 0 deletions server/data/frontendComponentsClient.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import nock from 'nock'
import config from '../config'
import FrontendComponentsClient from './frontendComponentsClient'

describe('FrontendComponentsClient', () => {
const frontendComponentsClient = new FrontendComponentsClient('not used')
let fakeFrontendComponentsApi: nock.Scope

beforeEach(() => {
fakeFrontendComponentsApi = nock(config.apis.frontendComponents.url)
})

afterEach(() => {
if (!nock.isDone()) {
nock.cleanAll()
throw new Error('Not all nock interceptors were used!')
}
nock.abortPendingRequests()
nock.cleanAll()
})

describe('getComponents', () => {
it('should get frontend components', async () => {
const userToken = 'user1'
const response = { some: 'response' }

fakeFrontendComponentsApi
.get('/components?component=header&component=footer')
.matchHeader('x-user-token', userToken)
.reply(200, response)

const result = await frontendComponentsClient.getComponents(['header', 'footer'], userToken)
expect(result).toStrictEqual(response)
})
})
})
29 changes: 29 additions & 0 deletions server/data/frontendComponentsClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import RestClient from './restClient'
import config from '../config'

export interface Component {
html: string
css: string[]
javascript: string[]
}

export type AvailableComponent = 'header' | 'footer'

export default class FrontendComponentsClient {
restClient: RestClient

constructor(token: string) {
this.restClient = new RestClient('Frontend components', config.apis.frontendComponents, token)
}

async getComponents<T extends AvailableComponent[]>(
components: T,
userToken: string,
): Promise<Record<T[number], Component>> {
return this.restClient.get({
path: `/components`,
query: `component=${components.join('&component=')}`,
headers: { 'x-user-token': userToken },
})
}
}
4 changes: 4 additions & 0 deletions server/data/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import PrisonRegisterApiClient from './prisonRegisterApiClient'
import { createRedisClient } from './redisClient'
import TokenStore from './tokenStore'
import WhereaboutsApiClient from './whereaboutsApiClient'
import FrontendComponentsClient from './frontendComponentsClient'

type RestClientBuilder<T> = (token: string) => T

Expand All @@ -29,6 +30,8 @@ export const dataAccess = () => ({
hmppsAuthClient: new HmppsAuthClient(new TokenStore(createRedisClient())),
manageUsersApiClient: new ManageUsersApiClient(),
nomisUserRolesApiClient: new NomisUserRolesApiClient(),
frontendComponentsClientBuilder: ((token: string) =>
new FrontendComponentsClient(token)) as RestClientBuilder<FrontendComponentsClient>,
orchestrationApiClientBuilder: ((token: string) =>
new OrchestrationApiClient(token)) as RestClientBuilder<OrchestrationApiClient>,
prisonApiClientBuilder: ((token: string) => new PrisonApiClient(token)) as RestClientBuilder<PrisonApiClient>,
Expand All @@ -46,6 +49,7 @@ export type DataAccess = ReturnType<typeof dataAccess>

export {
HmppsAuthClient,
FrontendComponentsClient,
ManageUsersApiClient,
NomisUserRolesApiClient,
OrchestrationApiClient,
Expand Down
Loading
Loading