Skip to content

Commit

Permalink
♻️ [open-formulieren/open-forms#4929] Grab the form from context inst…
Browse files Browse the repository at this point in the history
…ead of prop in FormStart

We wrap the app in form context anyway when the SDK is initialized, as the
form is statically loaded only once initially when the SDK bootstraps.

This means we do not need to pass it as a prop, nor do we need to worry
about too-frequent re-renders.
  • Loading branch information
sergei-maertens committed Jan 13, 2025
1 parent 4b9c035 commit 037ed7f
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 23 deletions.
3 changes: 2 additions & 1 deletion src/api-mocks/forms.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {produce} from 'immer';
import {HttpResponse, http} from 'msw';

import {PRIVACY_POLICY_ACCEPTED} from 'components/SummaryConfirmation/mocks';
import {SUBMISSION_ALLOWED} from 'components/constants';

import {BASE_URL, getDefaultFactory} from './base';

Expand All @@ -18,7 +19,7 @@ export const FORM_DEFAULTS = {
showSummaryProgress: false,
maintenanceMode: false,
active: true,
submissionAllowed: 'yes',
submissionAllowed: SUBMISSION_ALLOWED.yes,
suspensionAllowed: true,
sendConfirmationEmail: true,
submissionStatementsConfiguration: [PRIVACY_POLICY_ACCEPTED],
Expand Down
5 changes: 3 additions & 2 deletions src/components/FormStart/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import AuthenticationOutage, {
} from 'components/auth/AuthenticationOutage';
import {UnprocessableEntity} from 'errors';
import {IsFormDesigner} from 'headers';
import useFormContext from 'hooks/useFormContext';
import useInitialDataReference from 'hooks/useInitialDataReference';
import useStartSubmission from 'hooks/useStartSubmission';
import useTitle from 'hooks/useTitle';
Expand All @@ -43,7 +44,8 @@ const FormStartMessage = ({form}) => {
* This is shown when the form is initially loaded and provides the explicit user
* action to start the form, or present the login button (DigiD, eHerkenning...)
*/
const FormStart = ({form, submission, onFormStart, onDestroySession}) => {
const FormStart = ({submission, onFormStart, onDestroySession}) => {
const form = useFormContext();
const hasActiveSubmission = !!submission;
const isAuthenticated = hasActiveSubmission && submission.isAuthenticated;
const doStart = useStartSubmission();
Expand Down Expand Up @@ -144,7 +146,6 @@ const FormStart = ({form, submission, onFormStart, onDestroySession}) => {
};

FormStart.propTypes = {
form: Types.Form.isRequired,
submission: Types.Submission,
onFormStart: PropTypes.func.isRequired,
onDestroySession: PropTypes.func.isRequired,
Expand Down
77 changes: 57 additions & 20 deletions src/components/FormStart/tests.spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,35 @@ import messagesEN from 'i18n/compiled/en.json';
import {IntlProvider} from 'react-intl';
import {RouterProvider, createMemoryRouter} from 'react-router-dom';

import {buildSubmission} from 'api-mocks';
import {FormContext} from 'Context';
import {buildForm, buildSubmission} from 'api-mocks';

import {testForm, testLoginForm} from './fixtures';
import FormStart from './index';

let scrollIntoViewMock = vi.fn();
window.HTMLElement.prototype.scrollIntoView = scrollIntoViewMock;

const Wrap = ({children, currentUrl = '/startpagina'}) => {
beforeEach(() => {
localStorage.clear();
});

afterEach(() => {
localStorage.clear();
});

afterAll(() => {
vi.clearAllMocks();
});

const Wrap = ({form = buildForm(), children, currentUrl = '/startpagina'}) => {
const parsedUrl = new URL(currentUrl, 'http://dummy');
const routes = [{path: parsedUrl.pathname, element: <>{children}</>}];
const router = createMemoryRouter(routes, {initialEntries: [currentUrl]});
return (
<IntlProvider locale="en" messages={messagesEN}>
<RouterProvider router={router} />
<FormContext.Provider value={form}>
<RouterProvider router={router} />
</FormContext.Provider>
</IntlProvider>
);
};
Expand All @@ -28,7 +42,7 @@ it('Form start page start if _start parameter is present', async () => {

render(
<Wrap currentUrl="/startpagina?_start=1">
<FormStart form={testForm} onFormStart={onFormStart} onDestroySession={onDestroySession} />
<FormStart onFormStart={onFormStart} onDestroySession={onDestroySession} />
</Wrap>
);

Expand Down Expand Up @@ -60,12 +74,12 @@ it.each([
const url = `/startpagina?_start=1&${testQuery}`;
render(
<Wrap currentUrl={url}>
<FormStart form={testForm} onFormStart={onFormStart} onDestroySession={onDestroySession} />
<FormStart onFormStart={onFormStart} onDestroySession={onDestroySession} />
</Wrap>
);

expect(await screen.findByText(expectedMessage)).toBeVisible();
expect(onFormStart).toHaveBeenCalledTimes(0);
expect(onFormStart).not.toHaveBeenCalled();
}
);

Expand All @@ -76,7 +90,6 @@ it('Form start page does not show login buttons if an active submission is prese
render(
<Wrap>
<FormStart
form={testForm}
onFormStart={onFormStart}
onDestroySession={onDestroySession}
submission={buildSubmission({isAuthenticated: false})}
Expand All @@ -92,14 +105,26 @@ it('Form start page does not show login buttons if an active submission is prese
it('Form start page with initial_data_reference', async () => {
const onFormStart = vi.fn();
const onDestroySession = vi.fn();
const form = buildForm({
loginOptions: [
{
identifier: 'digid',
label: 'DigiD',
url: 'https://openforms.nl/auth/form-name/digid/start',
logo: {
title: 'DigiD',
imageSrc: 'https://openforms.nl/static/img/digid-46x46.71ea68346bbb.png',
href: 'https://www.digid.nl/',
appearance: 'dark',
},
isForGemachtigde: false,
},
],
});

render(
<Wrap currentUrl="/startpagina?initial_data_reference=1234">
<FormStart
form={testLoginForm}
onFormStart={onFormStart}
onDestroySession={onDestroySession}
/>
<Wrap form={form} currentUrl="/startpagina?initial_data_reference=1234">
<FormStart onFormStart={onFormStart} onDestroySession={onDestroySession} />
</Wrap>
);

Expand All @@ -117,14 +142,26 @@ it('Form start page with initial_data_reference', async () => {
it('Form start page without initial_data_reference', async () => {
const onFormStart = vi.fn();
const onDestroySession = vi.fn();
const form = buildForm({
loginOptions: [
{
identifier: 'digid',
label: 'DigiD',
url: 'https://openforms.nl/auth/form-name/digid/start',
logo: {
title: 'DigiD',
imageSrc: 'https://openforms.nl/static/img/digid-46x46.71ea68346bbb.png',
href: 'https://www.digid.nl/',
appearance: 'dark',
},
isForGemachtigde: false,
},
],
});

render(
<Wrap currentUrl="/startpagina?initial_data_reference=">
<FormStart
form={testLoginForm}
onFormStart={onFormStart}
onDestroySession={onDestroySession}
/>
<Wrap form={form} currentUrl="/startpagina?initial_data_reference=">
<FormStart onFormStart={onFormStart} onDestroySession={onDestroySession} />
</Wrap>
);

Expand Down

0 comments on commit 037ed7f

Please sign in to comment.