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

Release 8.6.0 #770

Merged
merged 9 commits into from
Jul 30, 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
316 changes: 196 additions & 120 deletions package-lock.json

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "flood-app",
"version": "8.5.0",
"version": "8.6.0",
"description": "Flood risk app",
"main": "index.js",
"repository": "github:defra/flood-app",
Expand Down Expand Up @@ -57,9 +57,9 @@
"babel-loader": "^9.1.3",
"body-scroll-lock": "^3.1.5",
"core-js": "^3.36.0",
"d3": "^7.8.5",
"d3": "^7.9.0",
"datatables.net-buttons": "^2.4.2",
"datatables.net-buttons-dt": "^2.4.2",
"datatables.net-buttons-dt": "^3.0.2",
"datatables.net-dt": "1.12.1",
"elm-pep": "^1.0.6",
"geojson": "0.5.0",
Expand All @@ -72,16 +72,16 @@
"node-schedule": "^2.1.0",
"nunjucks": "^3.2.4",
"ol": "^8.2.0",
"pino": "^8.16.2",
"pino": "^9.2.0",
"pino-abstract-transport": "^1.1.0",
"pino-pretty": "^10.2.3",
"qs": "^6.12.1",
"regenerator-runtime": "^0.14.0",
"sass": "^1.69.5",
"sass": "^1.77.6",
"sinon": "^17.0.1",
"standard": "^17.1.0",
"uglify-js": "^3.14.4",
"webpack": "^5.89.0",
"webpack": "^5.92.1",
"webpack-cli": "^5.1.4",
"yargs": "^17.7.2"
},
Expand Down
45 changes: 45 additions & 0 deletions release-docs/CFF-8.6.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Check For Flooding Release

* Version: 8.6.0
* Proposed Release Date: 31/07/2024
* Jira Release Overview: https://eaflood.atlassian.net/projects/FSR/versions/17134/tab/release-report-all-issues

## Sense Check

* Note that this is the definitive release notes for WebOps. The release notes in flood-service and flood-db are for CFF dev team use only.
* Cross check the list of Jira tickets below with those in the Jira release linked to above and update where needed
* Add additional Jira tickets from the related release notes in the 'Release 8.6.0' PR's created in:
* [flood-service](https://github.com/DEFRA/flood-service)

* Add any required infrastructure changes such as redirects to the infrastructure changes section below
* Once this sense check is done, delete this section

## Tickets



* FSR-1251 | npm updates (#732)

* FSR-1209: Update link and related test (#742)

* FSR-1062 | Update Visibility and Icons for Tidal Stations and Correct Naming (#720)

* FSR-1161 | Webchat Integration and Markup Amendments (#684)

* FSR-1059 | Standardize Tidal Station Titles and Meta Information (#715)

* FSR-1167 | Update Rainfall Bar Chart to 6 AM (#714)



## Instructions


1 - Execute LFW_{STAGE}_04_UPDATE_FLOOD_APP_AND_SERVICE_PIPELINE


Execute smoke tests and forward results

## Related Infrastructure Changes Required

* None
10 changes: 7 additions & 3 deletions server/models/views/station.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class ViewModel {
this.station = new Station(station)
this.station.riverNavigation = river
this.id = station.id
this.river = river

this.station.trend = river.trend

Expand Down Expand Up @@ -213,12 +214,15 @@ class ViewModel {
const stationType = stationTypeCalculator(this.station.type)
const stationLocation = this.station.name

if (this.station.type === 'g') {
if (this.station.isGroundwater) {
this.pageTitle = `Groundwater level at ${stationLocation}`
this.postTitle = `Latest groundwater level information for ${this.station.name} borehole`
} else if (this.station.type === 'c') {
} else if (this.station.isCoastal && this.river.river_name !== 'Sea Levels') {
this.pageTitle = `${this.river.river_name} level at ${stationLocation}`
this.postTitle = `Latest tidal level information for the ${this.river.river_name} at ${this.station.name}`
} else if (this.station.isCoastal) {
this.pageTitle = `Sea level at ${stationLocation}`
this.postTitle = `Latest tidal level information for the ${this.station.river} at ${this.station.name}`
this.postTitle = `Latest tidal level information for the sea at ${this.station.name}`
} else {
this.pageTitle = `${this.station.river} level ${this.station.isMulti ? this.station.direction + ' ' : ''}at ${stationLocation}`
this.postTitle = `Latest river level information for the ${this.station.river} at ${this.station.name} ${this.station.isMulti ? this.station.direction : ''}`
Expand Down
2 changes: 1 addition & 1 deletion server/src/js/components/bar-chart/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ function BarChart (containerId, stationId, data) {
xScale = xScale.range([0, width]).padding(0.4)
const xAxis = axisBottom(xScale).tickSizeOuter(0).tickValues(xScale.domain().filter((d, i) => {
const hourMinute = timeFormat('%H:%M')(new Date(d))
const labelsHours = ['00:00']
const labelsHours = ['06:00']
const labelsMinutes = ['00:00', '06:00', '12:00', '18:00']
const labels = period === 'hours' ? labelsHours : labelsMinutes
return labels.includes(hourMinute) && i >= 2 // Don't show lable if before 3rd tick
Expand Down
16 changes: 11 additions & 5 deletions server/src/js/components/map/live.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,11 +156,15 @@ function LiveMap (mapId, options) {
state = props.type === 'G' ? 'ground' : 'river'
}
} else if (props.type === 'C') {
// Tide
if (props.status === 'Suspended' || props.status === 'Closed' || (!props.value && !props.iswales)) {
state = 'seaError'
// Tide or River based on river_name
if (props.river_name !== 'Sea Levels') {
state = 'river'
} else {
state = 'sea'
if (props.status === 'Suspended' || props.status === 'Closed' || (!props.value && !props.iswales)) {
state = 'seaError'
} else {
state = 'sea'
}
}
} else if (props.type === 'R') {
// Rainfall
Expand All @@ -183,8 +187,10 @@ function LiveMap (mapId, options) {
(props.severity_value && props.severity_value === 4 && lyrCodes.includes('tr')) ||
// Rivers
(ref === 'stations' && ['S', 'M'].includes(props.type) && lyrCodes.includes('ri')) ||
// Tidal Rivers
(ref === 'stations' && props.type === 'C' && props.river_name !== 'Sea Levels' && lyrCodes.includes('ri')) ||
// Sea
(ref === 'stations' && props.type === 'C' && lyrCodes.includes('ti')) ||
(ref === 'stations' && props.type === 'C' && props.river_name === 'Sea Levels' && lyrCodes.includes('ti')) ||
// Ground
(ref === 'stations' && props.type === 'G' && lyrCodes.includes('gr')) ||
// Rainfall
Expand Down
2 changes: 1 addition & 1 deletion server/src/templates/info-live.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<div id="infoDescription">
<strong class="defra-map-info__name">
<a data-journey-click="Map:Map interaction:Map - Open station from tooltip" href="/station/{{ model.id }}">
{% if model.type === 'C' %}Sea Level{% elif model.type === 'G' %}Groundwater{% else %}{{ model.river }}{% endif %} at
{% if model.type === 'C' and model.river_name !== 'Sea Levels' %}{{model.river_name}}{%elif model.type === 'C'%}Sea Level{% elif model.type === 'G' %}Groundwater{% else %}{{ model.river }}{% endif %} at
{{ model.name }}
{% if model.iswales %} (Natural Resources Wales){% endif %}
</a>
Expand Down
38 changes: 21 additions & 17 deletions server/views/partials/context-footer.html
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
<div class="defra-context-footer">
<aside class="defra-context-footer">
<div>
<h2 class="govuk-visually-hidden">Speak to someone</h2>
<p><strong>Call Floodline for advice{% if model.isNationalPage %} about flooding from rivers, the sea and
groundwater{% endif %}</strong></p>
<p>Telephone: 0345 988 1188<br>Textphone: 0345 602 6340<br>Open 24 hours a day, 7 days a week<br><a
href="https://gov.uk/call-charges">Find out more about call charges</a></p>
{% if webchat.enabled %}
<p class="govuk-!-margin-bottom-0">
<strong>Talk to a Floodline adviser over webchat</strong>
<br>
We're running webchat as a trial.
</p>
<div id="wc-availability" data-brand-id="{{webchat.brandId}}" data-environment="{{webchat.environment}}" data-channel-id="{{webchat.channelId}}" data-audio-url="{{webchat.audioUrl}}">
<p>Webchat is not supported with your browser</p>
</div>
{% endif %}
<header class="govuk-heading-m">Contact Floodline for advice</header>
<p>
<strong>Floodline helpline</strong>
<br>Telephone: 0345 988 1188
<br>Textphone: 0345 602 6340
<br>Open 24 hours a day, 7 days a week
<br>
<a href="https://gov.uk/call-charges">Find out more about call charges</a>
</p>
{% if webchat.enabled %}
<p class="govuk-!-margin-bottom-0">
<strong>Talk to a Floodline adviser over webchat</strong>
<br>
We're running webchat as a trial.
</p>
<div id="wc-availability" data-brand-id="{{webchat.brandId}}" data-environment="{{webchat.environment}}" data-channel-id="{{webchat.channelId}}" data-audio-url="{{webchat.audioUrl}}">
<p>Webchat is not supported with your browser</p>
</div>
{% endif %}
</div>
</div>
</aside>
2 changes: 1 addition & 1 deletion server/views/partials/related-content.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ <h2 class="govuk-heading-s" id="subsection-title">
</a>
</li>
<li>
<a class="govuk-link" href="https://www.gov.uk/guidance/flood-alerts-and-warnings-what-they-are-and-what-to-do">
<a class="govuk-link" href="https://www.gov.uk/help-during-flood">
What to do before or during a flood
</a>
</li>
Expand Down
4 changes: 2 additions & 2 deletions server/views/station.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<h1 class="govuk-heading-xl govuk-!-margin-bottom-0">
{% if model.station.isGroundwater %}Groundwater{% elif model.station.isCoastal %}Sea{% else %} {{ model.station.river }} {% endif %}
level {% if model.station.isMulti %} {% if model.station.isDownstream %}downstream{% else %}upstream{% endif %}{% endif %} at {{ model.station.name }}
{% if model.station.isGroundwater %}Groundwater{% elif model.station.isCoastal and model.river.river_name != 'Sea Levels' %}{{ model.river.river_name }}{% elif model.station.isCoastal %}Sea{% else %}{{ model.station.river }}{% endif %} level
{% if model.station.isMulti %}{% if model.station.isDownstream %}downstream{% else %}upstream{% endif %}{% endif %} at {{ model.station.name }}
</h1>
</div>
</div>
Expand Down
42 changes: 42 additions & 0 deletions test/lib/helpers/context-footer-checker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
const { parse } = require('node-html-parser')
const { expect } = require('@hapi/code')

function validateFloodlineContactDetails (response) {
const contextFooterHTML = validateFooterPresent(response)

expect(contextFooterHTML).to.contain('<header class="govuk-heading-m">Contact Floodline for advice</header>')
expect(contextFooterHTML).to.contain('<strong>Floodline helpline</strong>')
expect(contextFooterHTML).to.contain('Telephone: 0345 988 1188')
expect(contextFooterHTML).to.contain('Textphone: 0345 602 6340')
expect(contextFooterHTML).to.contain('Open 24 hours a day, 7 days a week')
expect(contextFooterHTML).to.contain('<a href="https://gov.uk/call-charges">Find out more about call charges</a>')
}

function validateWebChatFooterPresent (response) {
const contextFooterHTML = validateFooterPresent(response)

expect(contextFooterHTML).to.contain('<strong>Talk to a Floodline adviser over webchat</strong>')
expect(contextFooterHTML).to.contain('We\'re running webchat as a trial.')
}

function validateWebChatFooterNotPresent (response) {
const contextFooterHTML = validateFooterPresent(response)

expect(contextFooterHTML).to.not.contain('<strong>Talk to a Floodline adviser over webchat</strong>')
expect(contextFooterHTML).to.not.contain('We\'re running webchat as a trial.')
}

function validateFooterPresent (response) {
const root = parse(response.payload)
const asideElement = root.querySelector('aside.defra-context-footer')
expect(asideElement, 'Aside footer element should exist.').to.exist()
const contextFooterHTML = asideElement ? asideElement.innerHTML : ''
return contextFooterHTML
}

module.exports = {
validateFooterPresent,
validateFloodlineContactDetails,
validateWebChatFooterPresent,
validateWebChatFooterNotPresent
}
2 changes: 1 addition & 1 deletion test/lib/helpers/html-expectations.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function fullRelatedContentChecker (root, cyltfrLink) {
expect(relatedContentLinks.length, 'Should be 6 related content links').to.equal(6)
linkChecker(relatedContentLinks, 'Get flood warnings by phone, text or email', 'https://www.gov.uk/sign-up-for-flood-warnings')
linkChecker(relatedContentLinks, 'Prepare for flooding', 'https://www.gov.uk/prepare-for-flooding')
linkChecker(relatedContentLinks, 'What to do before or during a flood', 'https://www.gov.uk/guidance/flood-alerts-and-warnings-what-they-are-and-what-to-do')
linkChecker(relatedContentLinks, 'What to do before or during a flood', 'https://www.gov.uk/help-during-flood')
linkChecker(relatedContentLinks, 'What to do after a flood', 'https://www.gov.uk/after-flood')
linkChecker(relatedContentLinks, 'Check your long term flood risk', cyltfrLink)
linkChecker(relatedContentLinks, 'Report a flood', 'https://www.gov.uk/report-flood-cause')
Expand Down
16 changes: 16 additions & 0 deletions test/routes/alerts-and-warnings.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const data = require('../data')
const outlookData = require('../data/outlook.json')
const { parse } = require('node-html-parser')
const { fullRelatedContentChecker } = require('../lib/helpers/html-expectations')
const { validateFooterPresent } = require('../lib/helpers/context-footer-checker')

lab.experiment('Test - /alerts-warnings', () => {
let server
Expand Down Expand Up @@ -476,4 +477,19 @@ lab.experiment('Test - /alerts-warnings', () => {
Code.expect(response.statusCode).to.equal(200)
Code.expect(response.payload).to.contain('Error: Find location - Check for flooding - GOV.UK')
})
lab.test('GET /alerts-and-warnings - context footer checks ', async () => {
stubs.getFloods.callsFake(() => ({
floods: []
}))
stubs.getStationsWithin.callsFake(() => [])
stubs.getImpactsWithin.callsFake(() => [])
const options = {
method: 'GET',
url: '/alerts-and-warnings'
}

const response = await server.inject(options)
Code.expect(response.statusCode).to.equal(200)
validateFooterPresent(response)
})
})
57 changes: 56 additions & 1 deletion test/routes/location.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const data = require('../data')
const moment = require('moment')
const LocationSearchError = require('../../server/location-search-error')
const { parse } = require('node-html-parser')
const { validateFooterPresent } = require('../lib/helpers/context-footer-checker')

lab.experiment('Routes test - location - 2', () => {
let sandbox
Expand Down Expand Up @@ -52,6 +53,7 @@ lab.experiment('Routes test - location - 2', () => {
delete require.cache[require.resolve('../../server/services/server-methods.js')]

sandbox = await sinon.createSandbox()

server = Hapi.server({
port: 3000,
host: 'localhost',
Expand Down Expand Up @@ -649,7 +651,7 @@ lab.experiment('Routes test - location - 2', () => {
Code.expect(response.statusCode).to.equal(200)
Code.expect(response.payload).not.to.match(/<div class="defra-related-items">[\s\S]*?<a class="govuk-link" href="https:\/\/www\.gov\.uk\/sign-up-for-flood-warnings">\s*Get flood warnings by phone, text or email\s*<\/a>/)
Code.expect(response.payload).to.match(/<div class="defra-related-items">[\s\S]*?<a class="govuk-link" href="https:\/\/www\.gov\.uk\/prepare-for-flooding">\s*Prepare for flooding\s*<\/a>/)
Code.expect(response.payload).to.match(/<div class="defra-related-items">[\s\S]*?<a class="govuk-link" href="https:\/\/www\.gov\.uk\/guidance\/flood-alerts-and-warnings-what-they-are-and-what-to-do">\s*What to do before or during a flood\s*<\/a>/)
Code.expect(response.payload).to.match(/<div class="defra-related-items">[\s\S]*?<a class="govuk-link" href="https:\/\/www\.gov\.uk\/help-during-flood">\s*What to do before or during a flood\s*<\/a>/)
Code.expect(response.payload).to.match(/<div class="defra-related-items">[\s\S]*?<a class="govuk-link" href="https:\/\/www\.gov\.uk\/after-flood">\s*What to do after a flood\s*<\/a>/)
Code.expect(response.payload).not.to.match(/<div class="defra-related-items">[\s\S]*?<a class="govuk-link" href="https:\/\/www\.gov\.uk\/check-long-term-flood-risk">\s*Check your long term flood risk\s*<\/a>/)
Code.expect(response.payload).to.match(/<div class="defra-related-items">[\s\S]*?<a class="govuk-link" href="https:\/\/www\.gov\.uk\/report-flood-cause">\s*Report a flood\s*<\/a>/)
Expand Down Expand Up @@ -2070,4 +2072,57 @@ lab.experiment('Routes test - location - 2', () => {
Code.expect(response.statusCode).to.equal(500)
Code.expect(response.payload).to.contain('<h1 class="govuk-heading-xl govuk-!-margin-bottom-2">Sorry, there is a problem with the search</h1>')
})
lab.test('GET /location - context footer checks', async () => {
const floodService = require('../../server/services/flood')

const fakeGetJson = () => data.warringtonGetJson

const fakeIsEngland = () => {
return { is_england: true }
}

const fakeFloodsData = () => {
return { floods: [] }
}
const fakeStationsData = () => []
const fakeImpactsData = () => []
const fakeOutlookData = () => { }

sandbox.stub(floodService, 'getIsEngland').callsFake(fakeIsEngland)
sandbox.stub(floodService, 'getFloodsWithin').callsFake(fakeFloodsData)
sandbox.stub(floodService, 'getStationsWithin').callsFake(fakeStationsData)
sandbox.stub(floodService, 'getImpactsWithin').callsFake(fakeImpactsData)
sandbox.stub(floodService, 'getOutlook').callsFake(fakeOutlookData)

const util = require('../../server/util')
sandbox.stub(util, 'getJson').callsFake(fakeGetJson)

const locationPlugin = {
plugin: {
name: 'location',
register: (server, options) => {
server.route(require('../../server/routes/location'))
}
}
}

await server.register(require('../../server/plugins/views'))
await server.register(require('../../server/plugins/session'))
await server.register(require('../../server/plugins/logging'))
await server.register(locationPlugin)
// Add Cache methods to server
const registerServerMethods = require('../../server/services/server-methods')
registerServerMethods(server)

await server.initialize()
const options = {
method: 'GET',
url: '/location/Warrington'
}

const response = await server.inject(options)

Code.expect(response.statusCode).to.equal(200)
validateFooterPresent(response)
})
})
Loading
Loading