Skip to content

Commit

Permalink
auto refresh. updated TA tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Ash committed Sep 23, 2024
1 parent cc50515 commit 961efe6
Show file tree
Hide file tree
Showing 2 changed files with 199 additions and 17 deletions.
194 changes: 188 additions & 6 deletions server/views/partials/latest-levels.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
<div class="govuk-visually-hidden" role="status" data-live-status></div>

<div class="defra-live">
<h2 class="defra-live__title">Latest level{% if model.latestLevels.length > 1 %}s{% endif %}</h2>
{% for warnings in model.latestLevels %}
<div class="defra-live__item">
{% if warnings.isSuspendedOrOffline %}
<p class="defra-flood-meta defra-flood-meta--no-border govuk-!-margin-bottom-0"><strong>Latest Level</strong></p>
<div class="defra-live__item" data-item-status="{{ warnings.status }}" data-item-name="{{ warnings.river_name }}" data-item-agency="{{ warnings.agency_name }}" data-item-id="{{ warnings.rloi_id }}{% if warnings.direction == 'd' %}-downstage{% endif %}">
{% if warnings.status == 'Suspended' or (warnings.status == 'Active' and warnings.latest_level == null) %}
<p class="defra-flood-meta defra-flood-meta--no-border govuk-!-margin-bottom-0">
<strong>Latest Level</strong>
</p>
<p>The {{ warnings.river_name }} level at {{ warnings.agency_name }} is currently unavailable.</p>
{% else %}
<p class="defra-flood-meta defra-flood-meta--no-border govuk-!-margin-bottom-0"><strong>{{ warnings.formatted_time }}</strong></p>
<p>The {{ warnings.river_name }} level at {{ warnings.agency_name }} was {{ warnings.latest_level | toFixed(2) }} metres. Property flooding is possible when it goes above {{ warnings.threshold_value | toFixed(2) }} metres.
<p class="defra-flood-meta defra-flood-meta--no-border govuk-!-margin-bottom-0">
<strong data-item-time>{{ warnings.formatted_time }}</strong>
</p>
<p>The {{ warnings.river_name }} level at {{ warnings.agency_name }} was <span data-item-value>{{ warnings.latest_level | toFixed(2) }}</span> metres. Property flooding is possible when it goes above {{ warnings.threshold_value | toFixed(2) }} metres.
{% if model.latestLevels.length > 1 %}
<a href="/station/{{ warnings.rloi_id }}{% if warnings.direction == 'd' %}-downstage{% endif %}">Monitor the {{ warnings.river_name }} level at {{ warnings.agency_name }}</a>
{% endif %}
Expand All @@ -20,4 +26,180 @@ <h2 class="defra-live__title">Latest level{% if model.latestLevels.length > 1 %}
{% endif %}
</div>
{% endfor %}
</div>
</div>

<script>
/* global DOMParser */

(function () {
let timeout
let timeAgoInterval
let liveStatusMessages = []

const latestLevels = document.querySelectorAll('.defra-live__item')

if (latestLevels.length === 0) return

function renderTimeAgo () {
const elements = document.querySelectorAll('[data-item-time]')

elements.forEach((element, index) => {
console.log('element', index)
const timeAgoText = element.textContent
const timeAgoValue = parseInt(timeAgoText, 10)

console.log('--currentTime', timeAgoText)

if (!timeAgoText.includes('hour')) {
element.textContent = `${timeAgoValue + 1} minutes ago`
console.log('--newTime', element.textContent)
}
})

console.log('\n')
}

function updateTimeAgo () {
console.log('--updateTimeAgo() started')

setTimeout(() => {
renderTimeAgo()
timeAgoInterval = setInterval(renderTimeAgo, 60000)
}, (60 - new Date().getSeconds()) * 1000)
}

function updateLiveStatus () {
if (liveStatusMessages.length === 0) return

const element = document.querySelector('[data-live-status]')
element.innerHTML = ''

const p = document.createElement('p')
p.innerText = liveStatusMessages.join('. ')
element.append(p)
}

function fetchRiverLevels () {
console.log('fetchRiverLevels...')

liveStatusMessages = []

fetch(window.location.href)
.then(res => {
if (!res.ok) throw new Error('Failed to fetch data')
return res.text()
})
.then(html => {
const parser = new DOMParser()
const doc = parser.parseFromString(html, 'text/html')

// Get elements from fetched content
const fetchedElements = Array.from(doc.querySelectorAll('.defra-live .defra-live__item'))

// Check if any elements are missing in the fetched data
const isMissingElements = latestLevels.length !== fetchedElements.length
console.log('isMissingElements', isMissingElements, latestLevels.length, fetchedElements.length)
console.log('latestLevels', latestLevels)
console.log('fetchedElements', fetchedElements)

if (isMissingElements) {
return liveStatusMessages.push('Warnings have been removed, please refresh the page.')
}

fetchedElements.forEach((fetchedElement, index) => {
const itemId = fetchedElement.getAttribute('data-item-id')
const itemRiverName = fetchedElement.getAttribute('data-item-name')
const itemRiverAgency = fetchedElement.getAttribute('data-item-agency')

const currentItem = document.querySelector(`[data-item-id="${itemId}"]`)

console.log('fetchedElement', itemId, itemRiverName, itemRiverAgency)

if (currentItem) {
const fetchedTime = fetchedElement.querySelector('[data-item-time]')
const fetchedValue = fetchedElement.querySelector('[data-item-value]')
const fetchedStatus = fetchedElement.getAttribute('data-item-status')

const currentTime = currentItem.querySelector('[data-item-time]')
const currentValue = currentItem.querySelector('[data-item-value]')
const currentStatus = currentItem.getAttribute('data-item-status')

console.log('--currentValue', currentValue?.textContent, currentStatus)
console.log('--fetchedValue', fetchedValue?.textContent, fetchedStatus)
console.log('--requires update?', fetchedValue?.textContent !== currentValue?.textContent)

if (fetchedStatus === currentStatus) {
if (fetchedValue?.textContent !== currentValue?.textContent) {
console.log('--new value fetched')
clearInterval(timeAgoInterval)
console.log('--interval cleared')
currentValue.textContent = fetchedValue.textContent

liveStatusMessages.push(`The ${itemRiverName} at ${itemRiverAgency} level was ${fetchedValue.textContent} metres ${fetchedTime.textContent}`)

updateTimeAgo()
} else {
console.log('--no change')
}

currentTime.textContent = fetchedTime.textContent
} else {
liveStatusMessages.push('Please refresh the page')
}
} else {
liveStatusMessages.push('Please refresh the page')
}

console.log('-------------------\n')
})
})
.catch(error => {
console.error('Error updating levels:', error)

liveStatusMessages.push(`There was an error getting the latest level`)
})
.finally(() => {
updateLiveStatus()
})
}

function nextUpdate () {
clearTimeout(timeout)

const now = new Date()
const nowMinute = now.getMinutes()
const targetMinutes = [3, 18, 33, 48]

// Find the next target minute
const nextTargetMinute = targetMinutes.find(minute => minute > nowMinute) ?? targetMinutes[0]

console.log('--Current minute:', nowMinute)
console.log('--Next target minute:', nextTargetMinute)

// Create the next target date based on the next target minute
const nextTargetDate = new Date(now)
nextTargetDate.setMinutes(nextTargetMinute)
nextTargetDate.setSeconds(0)
nextTargetDate.setMilliseconds(0)

if (nowMinute >= targetMinutes[3]) {
nextTargetDate.setHours(nextTargetDate.getHours() + 1)
}

// Calculate delay correctly from now
const delay = nextTargetDate.getTime() - now.getTime()

console.log('--delay (calc)', Math.round(delay / 1000 / 60))
console.log(`Next update scheduled in ${Math.round(delay / 1000 / 60)} minutes at ${nextTargetDate.toLocaleTimeString()}\n\n`)

// Schedule the next update
timeout = setTimeout(() => {
fetchRiverLevels()
nextUpdate()
}, delay)
}

updateTimeAgo()
nextUpdate()
})()
</script>
22 changes: 11 additions & 11 deletions test/routes/target-area.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,10 @@ lab.experiment('Target-area tests', () => {

// Latest level (single threshold)
Code.expect(response.payload).to.contain('<h2 class="defra-live__title">Latest level</h2>')
Code.expect(response.payload).to.contain('<p>The River Derwent level at Derby St Marys was 0.54 metres. Property flooding is possible when it goes above 3.30 metres.')
Code.expect(response.payload).to.contain('The River Derwent level at Derby St Marys was <span data-item-value>0.54</span> metres. Property flooding is possible when it goes above 3.30 metres.')
Code.expect(response.payload).to.contain('<a href="/station/2138">Monitor the latest level at Derby St Marys</a>')
Code.expect(response.payload).to.match(/<div class="defra-flood-status-item__text">\s*<strong>Flooding is possible - <a class="govuk-link" href="https:\/\/www\.gov\.uk\/guidance\/flood-alerts-and-warnings-what-they-are-and-what-to-do#flood-alert">\s*be prepared\s*<\/a><\/strong>\s*<\/div>/)
Code.expect(response.payload).to.contain('<p class="defra-flood-meta defra-flood-meta--no-border govuk-!-margin-bottom-0"><strong>30 minutes ago</strong></p>')
Code.expect(response.payload).to.contain('30 minutes ago')

clock.restore()
})
Expand Down Expand Up @@ -190,10 +190,10 @@ lab.experiment('Target-area tests', () => {

// latests levels (multi)
Code.expect(response.payload).to.contain('<h2 class="defra-live__title">Latest levels</h2>')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Eastcote Road was 0.35 metres. Property flooding is possible when it goes above 1.40 metres.')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Avenue Road was 0.18 metres. Property flooding is possible when it goes above 1.46 metres.')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Eastcote Road was <span data-item-value>0.35</span> metres. Property flooding is possible when it goes above 1.40 metres.')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Avenue Road was <span data-item-value>0.18</span> metres. Property flooding is possible when it goes above 1.46 metres.')
Code.expect(response.payload).to.contain(' <a href="/station/7173">Monitor the River Pinn level at Avenue Road</a>')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Moss Close was 0.13 metres. Property flooding is possible when it goes above 1.15 metres.')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Moss Close was <span data-item-value>0.13</span> metres. Property flooding is possible when it goes above 1.15 metres.')
Code.expect(response.payload).to.contain('<a href="/station/7201">Monitor the River Pinn level at Moss Close</a>')
})
lab.test('Check flood severity banner link for Flood warning', async () => {
Expand Down Expand Up @@ -657,7 +657,7 @@ lab.experiment('Target-area tests', () => {
Code.expect(response.statusCode).to.equal(200)

Code.expect(response.payload).to.contain('<h2 class="defra-live__title">Latest levels</h2>')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Eastcote Road was 0.35 metres. Property flooding is possible when it goes above 1.40 metres.')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Eastcote Road was <span data-item-value>0.35</span> metres. Property flooding is possible when it goes above 1.40 metres.')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Avenue Road is currently unavailable.</p>')
})

Expand Down Expand Up @@ -706,7 +706,7 @@ lab.experiment('Target-area tests', () => {
Code.expect(response.statusCode).to.equal(200)

Code.expect(response.payload).to.contain('<h2 class="defra-live__title">Latest levels</h2>')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Eastcote Road was 0.35 metres. Property flooding is possible when it goes above 1.40 metres.')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Eastcote Road was <span data-item-value>0.35</span> metres. Property flooding is possible when it goes above 1.40 metres.')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Avenue Road is currently unavailable.</p>')
})

Expand Down Expand Up @@ -755,7 +755,7 @@ lab.experiment('Target-area tests', () => {
Code.expect(response.statusCode).to.equal(200)

Code.expect(response.payload).to.contain('<h2 class="defra-live__title">Latest level</h2>')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Eastcote Road was 0.35 metres. Property flooding is possible when it goes above 1.40 metres.')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Eastcote Road was <span data-item-value>0.35</span> metres. Property flooding is possible when it goes above 1.40 metres.')
})

lab.test('Displays multiple levels with one normal, one active but offline, and one Welsh station with no values', async () => {
Expand Down Expand Up @@ -803,7 +803,7 @@ lab.experiment('Target-area tests', () => {
Code.expect(response.statusCode).to.equal(200)

Code.expect(response.payload).to.contain('<h2 class="defra-live__title">Latest levels</h2>')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Eastcote Road was 0.35 metres. Property flooding is possible when it goes above 1.40 metres.')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Eastcote Road was <span data-item-value>0.35</span> metres. Property flooding is possible when it goes above 1.40 metres.')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Avenue Road is currently unavailable.</p>')
Code.expect(response.payload).to.not.contain('<p>The River Welsh station level is currently unavailable.</p>')
})
Expand Down Expand Up @@ -853,7 +853,7 @@ lab.experiment('Target-area tests', () => {
Code.expect(response.statusCode).to.equal(200)

Code.expect(response.payload).to.contain('<h2 class="defra-live__title">Latest levels</h2>')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Eastcote Road was 0.35 metres. Property flooding is possible when it goes above 1.40 metres.')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Eastcote Road was <span data-item-value>0.35</span> metres. Property flooding is possible when it goes above 1.40 metres.')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Avenue Road is currently unavailable.</p>')
Code.expect(response.payload).to.not.contain('<p>The River Test level at Test Road is currently unavailable.</p>')
})
Expand Down Expand Up @@ -949,6 +949,6 @@ lab.experiment('Target-area tests', () => {
Code.expect(response.statusCode).to.equal(200)

Code.expect(response.payload).to.contain('<h2 class="defra-live__title">Latest level</h2>')
Code.expect(response.payload).to.contain('<p>The River Welsh level at Welsh Station was 0.35 metres. Property flooding is possible when it goes above 1.40 metres.\n \n </p>')
Code.expect(response.payload).to.contain('<p>The River Welsh level at Welsh Station was <span data-item-value>0.35</span> metres. Property flooding is possible when it goes above 1.40 metres.\n \n </p>')
})
})

0 comments on commit 961efe6

Please sign in to comment.