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

[ASSB-1444] Fix error on first render, update copy #351

Merged
merged 8 commits into from
Nov 7, 2024
10 changes: 0 additions & 10 deletions .github/workflows/semver-check-increment.yml

This file was deleted.

10 changes: 6 additions & 4 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
name: 'Test'
on:
pull_request:
branches:
- main
types: [ opened, reopened, synchronize ]

jobs:
test:
uses: UKHomeOffice/sas-github-workflows/.github/workflows/test-npm.yml@v1
uses: UKHomeOffice/sas-github-workflows/.github/workflows/test-npm.yml@v1
secrets: inherit
with:
lintCommand: 'test:lint'
with:
lintCommand: 'test:lint'
testCommand: 'run test:unit'

21 changes: 11 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ukhomeoffice/asl-components",
"version": "13.6.0",
"version": "13.6.1",
"description": "React components for ASL layouts and elements",
"main": "src/index.jsx",
"styles": "styles/index.scss",
Expand Down
41 changes: 30 additions & 11 deletions src/condition-reminders/index.jsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,49 @@
import React from 'react';
import { format } from 'date-fns';
import { formatDate, DATE_FORMAT } from '../utils';
import { Inset } from '../';

function ConditionReminders({ reminders, dateFormat = 'dd/MM/yyyy' }) {
if (!reminders || reminders.length < 1) {
const SINGULAR_CONTENT = {
notice: 'A deadline and automated reminders have been set for this condition',
deadline_list_intro: 'This condition has a deadline set for:',
deadline_list_outro:
'Licence holders will receive reminders 1 month before, 1 week before' +
' and on the deadline date. ASRU will receive a reminder when the' +
' deadline has passed.'
};

const PLURAL_CONTENT = {
notice: 'Deadlines and automated reminders have been set for this condition',
deadline_list_intro: 'This condition has deadlines set for:',
deadline_list_outro:
'Licence holders will receive reminders 1 month before, 1 week before' +
' and on each deadline date. ASRU will receive reminders when each' +
' deadline has passed.'
};

function ConditionReminders({ reminders, dateFormat = DATE_FORMAT.short }) {
const activeReminders = (reminders ?? []).filter(reminder => reminder.deadline);

if (activeReminders.length < 1) {
return null;
}

const content = activeReminders.length === 1 ? SINGULAR_CONTENT : PLURAL_CONTENT;

return (
<div className="condition-reminders">
<p><em>Automated reminders have been set for this condition</em></p>
<p><em>{content.notice}</em></p>
<details>
<summary>Show when reminders have been scheduled</summary>
<summary>Show when deadlines and reminders have been scheduled</summary>
<Inset>
<p>This condition has a reminder scheduled for:</p>
<p>{content.deadline_list_intro}</p>
<ul>
{
reminders.map(reminder => (
<li key={reminder.id}>{format(reminder.deadline, dateFormat)}</li>
<li key={reminder.id}>{formatDate(reminder.deadline, dateFormat)}</li>
))
}
</ul>
<p>
Licence holders will receive reminders a month before, a week before and on the day the condition
is due to be met. ASRU will receive a reminder when the deadline has passed.
</p>
<p>{content.deadline_list_outro}</p>
</Inset>
</details>
</div>
Expand Down
64 changes: 64 additions & 0 deletions src/condition-reminders/index.spec.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { shallow, render } from 'enzyme';
import React from 'react';
import ConditionReminders from './index';
import {describe, expect, test} from '@jest/globals'
import {v4 as uuid} from 'uuid'

function reminderWithDeadline(deadline) {
return {
id: uuid(),
deadline
}
}

describe('ConditionReminders component', () => {
test('Empty reminders should render nothing', () => {
for (const reminders of [null, []]) {
const wrapper = shallow(<ConditionReminders reminders={reminders}/>);
expect(wrapper.isEmptyRender()).toBe(true);
}
})

test('Reminders without a deadline should be ignored', () => {
const reminders = [{id: uuid()}]
const wrapper = shallow(<ConditionReminders reminders={reminders}/>);
expect(wrapper.isEmptyRender()).toBe(true);
})

test('When there is one reminder the copy should be singular', () => {
const reminders = [reminderWithDeadline("2025-01-01")]
const wrapper = render(<ConditionReminders reminders={reminders}/>);
expect(wrapper.text())
.toContain(
"A deadline and automated reminders have been set for this condition"
);
expect(wrapper.text())
.toContain("This condition has a deadline set for:");
expect(wrapper.text())
.toContain(
"Licence holders will receive reminders 1 month before," +
" 1 week before and on the deadline date. ASRU will receive a reminder" +
" when the deadline has passed."
);
})

test('When there are two reminders the copy should be plural', () => {
const reminders = [
reminderWithDeadline("2025-01-01"),
reminderWithDeadline("2025-02-02")
]
const wrapper = render(<ConditionReminders reminders={reminders}/>);
expect(wrapper.text())
.toContain(
"Deadlines and automated reminders have been set for this condition"
);
expect(wrapper.text())
.toContain("This condition has deadlines set for:");
expect(wrapper.text())
.toContain(
"Licence holders will receive reminders 1 month before, " +
"1 week before and on each deadline date. ASRU will receive reminders " +
"when each deadline has passed."
);
})
})
18 changes: 17 additions & 1 deletion src/utils.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const { stringify, parse } = require('qs');
const get = require('lodash/get');
const url = require('url');
const { format: dateFormatter } = require('date-fns');

const getValue = ({ row, schema, key }) => {
const accessor = schema.accessor || key;
Expand Down Expand Up @@ -36,8 +37,23 @@ const getSort = (column, state) => ({
ascending: state.column === column ? !state.ascending : true
});

const DATE_FORMAT = {
long: 'd MMMM yyyy',
short: 'd/M/yyyy'
};

const formatDate = (date, format = DATE_FORMAT.long) => {
try {
return date ? dateFormatter(date, format) : '-';
} catch (err) {
return 'Invalid date entered';
}
};

module.exports = {
getValue,
queryStringFromState,
getSort
getSort,
formatDate,
DATE_FORMAT
};
18 changes: 18 additions & 0 deletions src/utils.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const { formatDate, DATE_FORMAT } = require('./utils');

describe('formatDate', () => {
test('formats a valid date', () => {
expect(formatDate('2024-01-01', DATE_FORMAT.short)).toBe('1/1/2024');
});

test('returns "-" for empty dates', () => {
expect(formatDate(null, DATE_FORMAT.short)).toBe('-');
expect(formatDate(undefined, DATE_FORMAT.short)).toBe('-');
expect(formatDate('', DATE_FORMAT.short)).toBe('-');
});

test('returns "Invalid date entered" for invlaid dates', () => {
expect(formatDate('not a date', DATE_FORMAT.short)).toBe('Invalid date entered');
expect(formatDate('24-01-01', DATE_FORMAT.short)).toBe('Invalid date entered');
});
});
Loading