Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,7 @@ exports[`ChooseTemplatesPage renders correctly for a message plan with multiple
class="nhsuk-button"
data-testid="move-to-production-cta"
draggable="false"
href="/message-plans/move-to-production/fbb81055-79b9-4759-ac07-d191ae57be34"
href="/message-plans/get-ready-to-move/fbb81055-79b9-4759-ac07-d191ae57be34"
role="button"
>
Move to production
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import type { CascadeItem, RoutingConfig } from 'nhs-notify-backend-client';
import type { MessageOrder } from 'nhs-notify-web-template-management-utils';
import { createMessagePlanServerAction } from '@app/message-plans/create-message-plan/server-action';
import { NextRedirectError } from '@testhelpers/next-redirect';
import { createRoutingConfig } from '@utils/form-actions';
import { createRoutingConfig } from '@utils/message-plans';

jest.mock('next/navigation');
jest.mocked(redirect).mockImplementation((url, type) => {
throw new NextRedirectError(url, type);
});

jest.mock('@utils/form-actions');
jest.mock('@utils/message-plans');
jest.mocked(createRoutingConfig).mockResolvedValue(
mock<RoutingConfig>({
id: 'mock-routing-config-id',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`matches snapshot 1`] = `
<DocumentFragment>
<main
class="nhsuk-main-wrapper"
id="maincontent"
role="main"
>
<div
class="nhsuk-grid-row"
>
<div
class="nhsuk-grid-column-two-thirds"
>
<span
class="nhsuk-caption-xl"
>
Step 1 of 2
</span>
<h1
class="nhsuk-heading-xl"
>
Get ready to move message plan to production
</h1>
<dl
class="nhsuk-summary-list"
>
<div
class="nhsuk-summary-list__row"
>
<dt
class="nhsuk-summary-list__key"
>
Name
</dt>
<dd
class="nhsuk-summary-list__value"
>
My Routing Config
</dd>
</div>
</dl>
<p>
Moving message plans from draft to production means they are ready to send.
</p>
<p>
Any templates used in these message plans will be locked.
</p>
<p>
Messages will only be sent to recipients when you make a request with
<a
href="https://digital.nhs.uk/developer/api-catalogue/nhs-notify"
rel="noopener noreferrer"
target="_blank"
>
NHS Notify API (opens in a new tab)
</a>
or
<a
href="https://digital.nhs.uk/developer/api-catalogue/nhs-notify-mesh"
rel="noopener noreferrer"
target="_blank"
>
NHS Notify MESH (opens in a new tab)
</a>
.
</p>
<h2
class="nhsuk-heading-m"
id="before-you-continue"
>
Before you continue
</h2>
<p>
Make sure:
</p>
<ul
class="nhsuk-list nhsuk-list--bullet"
>
<li>
the relevant stakeholders in your team have approved your templates and message plan
</li>
<li>
your templates have no errors
</li>
</ul>
<div
class="nhsuk-warning-callout"
>
<h3
class="nhsuk-warning-callout__label"
>
Important
<span
class="nhsuk-u-visually-hidden"
>
:
</span>
</h3>
<p>
You cannot edit anything that is in production.
</p>
<p>
If you need to edit your templates or message plans, you can copy and replace them.
</p>
</div>
<div
class="nhsuk-form-group"
>
<a
aria-disabled="false"
class="nhsuk-button"
data-testid="continue-link"
draggable="false"
href="/templates/message-plans/review-and-move-to-production/routing-config-id"
role="button"
>
Continue
</a>
<a
aria-disabled="false"
class="nhsuk-button nhsuk-button--secondary nhsuk-u-margin-left-3"
data-testid="cancel-link"
draggable="false"
href="/templates/message-plans"
role="button"
>
Keep in draft
</a>
</div>
</div>
</div>
</main>
</DocumentFragment>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { render } from '@testing-library/react';
import { mock } from 'jest-mock-extended';
import { redirect, RedirectType } from 'next/navigation';
import { RoutingConfig } from 'nhs-notify-backend-client';
import { getRoutingConfig } from '@utils/message-plans';
import Page, {
metadata,
} from '../../../../app/message-plans/get-ready-to-move/[routingConfigId]/page';

jest.mock('next/navigation');
jest.mock('@utils/message-plans');

const routingConfig = mock<RoutingConfig>({
name: 'My Routing Config',
});

beforeEach(() => {
jest.clearAllMocks();
});

test('metadata', () => {
expect(metadata).toEqual({
title: 'Get ready to move message plan to production - NHS Notify',
});
});

test('matches snapshot', async () => {
jest.mocked(getRoutingConfig).mockResolvedValueOnce(routingConfig);

const page = await Page({
params: Promise.resolve({ routingConfigId: 'routing-config-id' }),
});

const container = render(page);

expect(container.asFragment()).toMatchSnapshot();
});

test('redirects if routing config is not found from path parameter', async () => {
await Page({
params: Promise.resolve({ routingConfigId: 'routing-config-id' }),
});

expect(getRoutingConfig).toHaveBeenCalledWith('routing-config-id');

expect(redirect).toHaveBeenCalledWith(
'/message-plans/invalid',
RedirectType.replace
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
ContentBlock,
ContentItem,
} from '@molecules/ContentRenderer/ContentRenderer';
import { markdownList } from '@utils/markdown-list';

describe('ContentRenderer', () => {
it('renders nothing for empty content array', () => {
Expand All @@ -14,7 +15,8 @@ describe('ContentRenderer', () => {
});

it('renders a plain string as MarkdownContent in inline mode', () => {
render(<ContentRenderer content='Just a string block' />);
const container = render(<ContentRenderer content='Just a string block' />);
expect(container.asFragment()).toMatchSnapshot();
expect(screen.getByText('Just a string block')).toBeInTheDocument();
});

Expand Down Expand Up @@ -45,7 +47,9 @@ describe('ContentRenderer', () => {
{ type: 'text', text: 'Another paragraph.' },
];

render(<ContentRenderer content={content} />);
const container = render(<ContentRenderer content={content} />);

expect(container.asFragment()).toMatchSnapshot();

const listItems = screen.getAllByRole('paragraph');
expect(listItems).toHaveLength(2);
Expand All @@ -58,14 +62,16 @@ describe('ContentRenderer', () => {
{ type: 'inline-text', text: 'Inline content' },
];

render(
const container = render(
<ul>
<li data-testid='list-item'>
<ContentRenderer content={content} />
</li>
</ul>
);

expect(container.asFragment()).toMatchSnapshot();

const listItem = screen.getByTestId('list-item');
expect(listItem).toHaveTextContent('Inline content');
expect(listItem.querySelector('p')).toBeNull();
Expand All @@ -74,14 +80,16 @@ describe('ContentRenderer', () => {
it('treats a string as inline text (no paragraph wrapper)', () => {
const content: string = 'Inline via string';

render(
const container = render(
<ul>
<li data-testid='list-item'>
<ContentRenderer content={content} />
</li>
</ul>
);

expect(container.asFragment()).toMatchSnapshot();

const listItem = screen.getByTestId('list-item');
expect(listItem).toHaveTextContent('Inline via string');
expect(listItem.querySelector('p')).toBeNull();
Expand All @@ -90,14 +98,16 @@ describe('ContentRenderer', () => {
it('treats a string array as inline text (no paragraph wrapper)', () => {
const content: ContentItem[] = ['Inline via string'];

render(
const container = render(
<ul>
<li data-testid='list-item'>
<ContentRenderer content={content} />
</li>
</ul>
);

expect(container.asFragment()).toMatchSnapshot();

const listItem = screen.getByTestId('list-item');
expect(listItem).toHaveTextContent('Inline via string');
expect(listItem.querySelector('p')).toBeNull();
Expand All @@ -115,7 +125,9 @@ describe('ContentRenderer', () => {
},
];

render(<ContentRenderer content={content} />);
const container = render(<ContentRenderer content={content} />);

expect(container.asFragment()).toMatchSnapshot();

const hiddenText = screen.getByText('An example of heading markdown');
expect(hiddenText).toHaveAttribute('id', 'heading-markdown-description');
Expand All @@ -127,19 +139,84 @@ describe('ContentRenderer', () => {
);
});

it('renders list blocks', () => {
it('renders unordered list blocks', () => {
const content: ContentBlock[] = [
{
type: 'list',
items: ['Item 1', 'Item 2', 'Item 3'],
type: 'text',
text: markdownList('ul', ['Item 1', 'Item 2', 'Item 3']),
},
];

render(<ContentRenderer content={content} />);
const container = render(<ContentRenderer content={content} />);

expect(container.asFragment()).toMatchSnapshot();

const listItems = screen.getAllByRole('listitem');
expect(listItems).toHaveLength(3);
expect(listItems[0]?.parentElement?.tagName).toBe('UL');
expect(listItems[0]).toHaveTextContent('Item 1');
expect(listItems[1]).toHaveTextContent('Item 2');
expect(listItems[2]).toHaveTextContent('Item 3');
});

it('renders ordered list blocks', () => {
const content: ContentBlock[] = [
{
type: 'text',
text: markdownList('ol', ['Item 1', 'Item 2', 'Item 3']),
},
];

const container = render(<ContentRenderer content={content} />);

expect(container.asFragment()).toMatchSnapshot();

const listItems = screen.getAllByRole('listitem');
expect(listItems).toHaveLength(3);
expect(listItems[0]?.parentElement?.tagName).toBe('OL');
expect(listItems[0]).toHaveTextContent('Item 1');
expect(listItems[1]).toHaveTextContent('Item 2');
expect(listItems[2]).toHaveTextContent('Item 3');
});

it('renders with overrides on text blocks', () => {
const content: ContentBlock[] = [
{
type: 'text',
text: 'This is a paragraph.',
overrides: { p: { props: { className: 'foo' } } },
},
{
type: 'text',
text: 'Another paragraph.',
overrides: { p: { props: { className: 'bar' } } },
},
];

const container = render(<ContentRenderer content={content} />);

expect(container.asFragment()).toMatchSnapshot();

const paragraphs = screen.getAllByRole('paragraph');
expect(paragraphs).toHaveLength(2);
expect(paragraphs[0]).toHaveClass('foo');
expect(paragraphs[1]).toHaveClass('bar');
});

it('renders with overrides on inline-text blocks', () => {
const content: ContentBlock[] = [
{
type: 'inline-text',
text: 'This is a [link](https://example.com).',
overrides: { a: { props: { className: 'foo' } } },
},
];

const container = render(<ContentRenderer content={content} />);

expect(container.asFragment()).toMatchSnapshot();

const link = screen.getByRole('link');
expect(link).toHaveClass('foo');
});
});
Loading
Loading