Skip to content

Commit 7af0e43

Browse files
committed
Do not invoke validator onlyAvailableItems when 'landvelger' or 'valutavelger' because there is a bug within the validation that occurs on the summary page, which leads to the user being prevented from submitting a complete application. It applies to these two components since their values are fetched asynchronous, and the component's 'get ready'-promise is not respected for some reason (when display='wizard'), resulting in validation running before values are fetched.
1 parent ed84f4b commit 7af0e43

File tree

9 files changed

+6548
-21
lines changed

9 files changed

+6548
-21
lines changed

mocks/mocks/data/formio-api/nav083501.json

+6,352
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
{
2+
"brukerId": "03876399856",
3+
"skjemanr": "NAV 08-35.01",
4+
"tittel": "Inntektsopplysninger for selvstendig næringsdrivende og/eller frilansere som skal ha sykepenger",
5+
"tema": "SYK",
6+
"spraak": "nb",
7+
"hoveddokument": {
8+
"vedleggsnr": "NAV 08-35.01",
9+
"tittel": "Inntektsopplysninger for selvstendig næringsdrivende og/eller frilansere som skal ha sykepenger",
10+
"label": "Inntektsopplysninger for selvstendig næringsdrivende og/eller frilansere som skal ha sykepenger",
11+
"pakrevd": true,
12+
"mimetype": "application/pdf"
13+
},
14+
"hoveddokumentVariant": {
15+
"vedleggsnr": "NAV 08-35.01",
16+
"tittel": "Inntektsopplysninger for selvstendig næringsdrivende og/eller frilansere som skal ha sykepenger",
17+
"label": "Inntektsopplysninger for selvstendig næringsdrivende og/eller frilansere som skal ha sykepenger",
18+
"pakrevd": false,
19+
"mimetype": "application/json",
20+
"document": {
21+
"language": "nb-NO",
22+
"data": {
23+
"data": {
24+
"jegPlikterAGiDeOpplysningerOgLevereDeDokumenteneSomErNodvendigeForAtNavSkalKunneVurdereMineRettigheter": true,
25+
"jegHarGjortMegKjentMedMinPliktTilAInformereNavOmEndringerSomKanHaBetydningForSykepengeneJegFarUtbetalt": true,
26+
"hvaSlagsVirksomhetDriverDu": {
27+
"selvstendigNaeringsdrivende": true,
28+
"frilanser": true
29+
},
30+
"fornavnSoker": "test",
31+
"etternavnSoker": "test",
32+
"harDuNorskFodselsnummerEllerDNummer": "ja",
33+
"fodselsnummerDNummerSoker": "25058236813",
34+
"oppgiDatoForForsteSykefravaersdagDdMmAaaa": "2024-02-01",
35+
"hvaSlagsSelvstendigNaeringsvirksomhetDriverDu": {
36+
"enkeltpersonforetak": true,
37+
"fiskeBladA": false,
38+
"fiskeBladB": false,
39+
"fiskeLott": false,
40+
"fiskeHyre": false,
41+
"jordbrukSkogbruk": false,
42+
"dagmammaIEgetHjem": false,
43+
"annenVirksomhet": false
44+
},
45+
"harDuInntekterSomArbeidstakerITilleggTilInntektSomSelvstendigNaeringsdrivendeOgEllerFrilanser": "nei",
46+
"andreOpplysningerDuMenerErViktigeNarNavSkalFastsetteSykepengegrunnlagetDitt": "nei",
47+
"harDuDokumentasjonDuOnskerALeggeVedSoknaden": "ja",
48+
"hvaOnskerDuALeggeVed": {
49+
"personinntektsskjema": true,
50+
"resultatregnskap": true,
51+
"naeringsoppgave": false,
52+
"annet": false
53+
},
54+
"narStartetDuSomFrilanserDdMmAaaa": "2023-11-01",
55+
"harDuInntektFraFosterhjem": "nei",
56+
"orgNr": "242667913",
57+
"narStartetDuVirksomhetenDinDdMmAaaa": "2024-02-14",
58+
"hvaHarDuHattINaeringsresultatForSkattDeSiste12Manedene": 1200000,
59+
"harDetVaertDriftIVirksomhetenFremTilDuBleSykmeldt": "ja",
60+
"vilDuFortsattHaNaeringsinntektMensDuErSykmeldt": "nei",
61+
"erVirksomhetenRegistrertINorge": "nei",
62+
"landvelger": {
63+
"label": "Frankrike",
64+
"value": "FR"
65+
},
66+
"harDuFattEnVarigEndringAvArbeidssituasjonenVirksomhetenILopetAvDeSisteFireArene": "nei",
67+
"personinntektsskjema1": "leggerVedNaa",
68+
"resultatregnskap1": "leggerVedNaa"
69+
},
70+
"metadata": {
71+
"timezone": "Europe/Oslo",
72+
"offset": 60,
73+
"origin": "https://fyllut-preprod.intern.dev.nav.no",
74+
"referrer": "https://fyllut-preprod.intern.dev.nav.no/fyllut/nav083501",
75+
"browserName": "Netscape",
76+
"userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36",
77+
"pathName": "/fyllut/nav083501/vedlegg",
78+
"onLine": true
79+
},
80+
"state": "submitted",
81+
"_vnote": ""
82+
}
83+
}
84+
},
85+
"innsendingsId": "2db25aab-3524-4426-a333-489542bf16bf",
86+
"status": "Opprettet",
87+
"vedleggsListe": [
88+
{
89+
"vedleggsnr": "L2",
90+
"tittel": "Personinntektsskjema",
91+
"label": "Personinntektsskjema",
92+
"pakrevd": true,
93+
"beskrivelse": "",
94+
"formioId": "eiaivlp"
95+
},
96+
{
97+
"vedleggsnr": "L2",
98+
"tittel": "Resultatregnskap",
99+
"label": "Resultatregnskap",
100+
"pakrevd": true,
101+
"beskrivelse": "",
102+
"formioId": "etpewjh"
103+
}
104+
],
105+
"kanLasteOppAnnet": true,
106+
"fristForEttersendelse": 14,
107+
"endretDato": "2024-02-15T10:26:31.152815+01:00",
108+
"skalSlettesDato": "2024-04-11",
109+
"skjemaPath": "nav083501",
110+
"visningsType": "fyllUt"
111+
}

mocks/mocks/routes/formio-api.js

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ const translationsSubmissionMethod = require('../data/formio-api/submission-meth
1919
const globalTranslationsEn = require('../data/formio-api/global-translation.json');
2020
const formCustomCompsAlert = require('../data/formio-api/custom-components-alert.json');
2121
const formActivities = require('../data/formio-api/activities.json');
22+
const nav083501 = require('../data/formio-api/nav083501.json');
2223

2324
const allForms = [
2425
{ form: formCypress101, translations: translationsCypress101 },
@@ -35,6 +36,7 @@ const allForms = [
3536
{ form: formTestPrefillData, translations: undefined },
3637
{ form: formSelectV1, formV2: formSelectV2, translations: undefined },
3738
{ form: formActivities, translations: undefined },
39+
{ form: nav083501, translations: undefined },
3840
];
3941

4042
const findTestdata = (formPath) => allForms.find((testdata) => testdata.form.path === formPath);

mocks/mocks/routes/innsending-api.js

+9
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const formSelectSoknadCompleteV1 = require('../data/innsending-api/mellomlagring
1212
const formSelectSoknadInvalidCountryV1 = require('../data/innsending-api/mellomlagring/form-select/saved-invalid-country-v1.json');
1313
const formSelectSoknadInvalidInstrumentV1 = require('../data/innsending-api/mellomlagring/form-select/saved-invalid-instrument-v2.json');
1414
const mellomlagringActivities = require('../data/innsending-api/activities/mellomlagring-activities.json');
15+
const nav083591soknadComplete = require('../data/innsending-api/mellomlagring/nav083591/complete.json');
1516
const objectToByteArray = (obj) => Array.from(new TextEncoder().encode(JSON.stringify(obj)));
1617

1718
const base64Encode = (data) => {
@@ -223,6 +224,14 @@ module.exports = [
223224
body: convertToInnsendingApiResponse(formSelectSoknadInvalidInstrumentV1),
224225
},
225226
},
227+
{
228+
id: 'nav083501-complete-v1',
229+
type: 'json',
230+
options: {
231+
status: 200,
232+
body: convertToInnsendingApiResponse(nav083591soknadComplete),
233+
},
234+
},
226235
{
227236
id: 'not-found',
228237
type: 'json',

packages/fyllut/cypress/e2e/mellomlagring.cy.ts

+52-18
Original file line numberDiff line numberDiff line change
@@ -373,8 +373,9 @@ describe('Mellomlagring', () => {
373373
cy.findByRole('heading', { name: TEXTS.statiske.summaryPage.title }).should('exist');
374374
});
375375

376-
it('when submission data contains invalid country', () => {
377-
cy.mocksUseRouteVariant('get-soknad:form-select-invalid-country-v1');
376+
it('when form-v2 does not allow value anymore', () => {
377+
cy.mocksUseRouteVariant('get-form:success-v2');
378+
cy.mocksUseRouteVariant('get-soknad:form-select-invalid-instrument-v1');
378379

379380
cy.visit(
380381
'/fyllut/testselect/oppsummering?sub=digital&innsendingsId=df6c8a69-9eb0-4878-b51f-38b3849ef9b6&lang=nb-NO',
@@ -385,50 +386,62 @@ describe('Mellomlagring', () => {
385386
.within(() => {
386387
cy.get('dt').should('have.length', 3);
387388
cy.get('dt').eq(0).should('contain.text', 'Velg instrument');
388-
cy.get('dd').eq(0).should('contain.text', 'Piano');
389+
cy.get('dd').eq(0).should('contain.text', 'Piano'); // <- invalid in form v2
389390
cy.get('dt').eq(1).should('contain.text', 'Velg land du vil reise til');
390-
cy.get('dd').eq(1).should('contain.text', 'Invalid country'); // <- invalid (dataSrc=url)
391+
cy.get('dd').eq(1).should('contain.text', 'Italia');
391392
cy.get('dt').eq(2).should('contain.text', 'Velg valuta du vil betale med');
392393
cy.get('dd').eq(2).should('contain.text', 'Euro (EUR)');
393394
});
394395
cy.findByText(/Alle steg som mangler informasjon er markert med/).should('exist');
395396
cy.findByRole('button', { name: TEXTS.grensesnitt.navigation.saveAndContinue }).should('not.exist');
396397
cy.findByRole('heading', { name: TEXTS.statiske.summaryPage.title }).should('exist');
397398
});
399+
});
398400

399-
it('when form-v2 does not allow value anymore', () => {
400-
cy.mocksUseRouteVariant('get-form:success-v2');
401-
cy.mocksUseRouteVariant('get-soknad:form-select-invalid-instrument-v1');
401+
describe('allows user to continue to sendinn application', () => {
402+
it('when submission data is complete and valid', () => {
403+
cy.mocksUseRouteVariant('get-soknad:form-select-complete-v1');
404+
405+
cy.intercept('PUT', '/fyllut/api/send-inn/utfyltsoknad', (req) => {
406+
const { submission, attachments, ...rest } = req.body;
407+
expect(submission.data.velgInstrument).to.deep.eq({ label: 'Piano', value: 'piano' });
408+
expect(submission.data.velgLand).to.deep.eq({ label: 'Italia', value: 'IT' });
409+
expect(submission.data.velgValutaDuVilBetaleMed).to.deep.eq({ label: 'Euro (EUR)', value: 'EUR' });
410+
expect(attachments).to.have.length(1);
411+
expect(attachments[0].vedleggsnr).to.eq('P2');
412+
}).as('submitMellomlagring');
402413

403414
cy.visit(
404415
'/fyllut/testselect/oppsummering?sub=digital&innsendingsId=df6c8a69-9eb0-4878-b51f-38b3849ef9b6&lang=nb-NO',
405416
);
406417
cy.wait('@getMellomlagring');
418+
cy.findByRole('button', { name: /Veiledning/ }).should('exist');
407419
cy.get('dl')
408420
.eq(0)
409421
.within(() => {
410422
cy.get('dt').should('have.length', 3);
411423
cy.get('dt').eq(0).should('contain.text', 'Velg instrument');
412-
cy.get('dd').eq(0).should('contain.text', 'Piano'); // <- invalid in form v2
424+
cy.get('dd').eq(0).should('contain.text', 'Piano');
413425
cy.get('dt').eq(1).should('contain.text', 'Velg land du vil reise til');
414426
cy.get('dd').eq(1).should('contain.text', 'Italia');
415427
cy.get('dt').eq(2).should('contain.text', 'Velg valuta du vil betale med');
416428
cy.get('dd').eq(2).should('contain.text', 'Euro (EUR)');
417429
});
418-
cy.findByText(/Alle steg som mangler informasjon er markert med/).should('exist');
419-
cy.findByRole('button', { name: TEXTS.grensesnitt.navigation.saveAndContinue }).should('not.exist');
430+
cy.findByRole('button', { name: TEXTS.grensesnitt.navigation.saveAndContinue }).should('exist');
431+
cy.findByText(/Alle steg som mangler informasjon er markert med/).should('not.exist');
420432
cy.findByRole('heading', { name: TEXTS.statiske.summaryPage.title }).should('exist');
433+
434+
cy.clickSaveAndContinue();
435+
cy.wait('@submitMellomlagring');
421436
});
422-
});
423437

424-
describe('allows user to continue to sendinn application', () => {
425-
it('when submission data is complete and valid', () => {
426-
cy.mocksUseRouteVariant('get-soknad:form-select-complete-v1');
438+
it('even if submission data contains an invalid country', () => {
439+
cy.mocksUseRouteVariant('get-soknad:form-select-invalid-country-v1');
427440

428441
cy.intercept('PUT', '/fyllut/api/send-inn/utfyltsoknad', (req) => {
429-
const { submission, attachments, ...rest } = req.body;
442+
const { submission, attachments } = req.body;
430443
expect(submission.data.velgInstrument).to.deep.eq({ label: 'Piano', value: 'piano' });
431-
expect(submission.data.velgLand).to.deep.eq({ label: 'Italia', value: 'IT' });
444+
expect(submission.data.velgLand).to.deep.eq({ label: 'Invalid country', value: 'INVALID' });
432445
expect(submission.data.velgValutaDuVilBetaleMed).to.deep.eq({ label: 'Euro (EUR)', value: 'EUR' });
433446
expect(attachments).to.have.length(1);
434447
expect(attachments[0].vedleggsnr).to.eq('P2');
@@ -438,15 +451,14 @@ describe('Mellomlagring', () => {
438451
'/fyllut/testselect/oppsummering?sub=digital&innsendingsId=df6c8a69-9eb0-4878-b51f-38b3849ef9b6&lang=nb-NO',
439452
);
440453
cy.wait('@getMellomlagring');
441-
cy.findByRole('button', { name: /Veiledning/ }).should('exist');
442454
cy.get('dl')
443455
.eq(0)
444456
.within(() => {
445457
cy.get('dt').should('have.length', 3);
446458
cy.get('dt').eq(0).should('contain.text', 'Velg instrument');
447459
cy.get('dd').eq(0).should('contain.text', 'Piano');
448460
cy.get('dt').eq(1).should('contain.text', 'Velg land du vil reise til');
449-
cy.get('dd').eq(1).should('contain.text', 'Italia');
461+
cy.get('dd').eq(1).should('contain.text', 'Invalid country'); // <- invalid (dataSrc=url)
450462
cy.get('dt').eq(2).should('contain.text', 'Velg valuta du vil betale med');
451463
cy.get('dd').eq(2).should('contain.text', 'Euro (EUR)');
452464
});
@@ -459,6 +471,28 @@ describe('Mellomlagring', () => {
459471
});
460472
});
461473
});
474+
475+
it('Allows user to submit complete submission', () => {
476+
cy.mocksUseRouteVariant('get-soknad:nav083501-complete-v1');
477+
cy.intercept('PUT', '/fyllut/api/send-inn/utfyltsoknad', (req) => {
478+
const { submission, attachments } = req.body;
479+
expect(submission.data.landvelger).to.deep.eq({ label: 'Frankrike', value: 'FR' });
480+
expect(attachments).to.have.length(2);
481+
expect(attachments[0].label).to.eq('Personinntektsskjema');
482+
expect(attachments[1].label).to.eq('Resultatregnskap');
483+
}).as('submitMellomlagring');
484+
cy.intercept('GET', '/fyllut/api/send-inn/soknad/2db25aab-3524-4426-a333-489542bf16bf').as('getMellomlagring');
485+
486+
cy.visit(
487+
'/fyllut/nav083501/oppsummering?sub=digital&innsendingsId=2db25aab-3524-4426-a333-489542bf16bf&lang=nb-NO',
488+
);
489+
cy.wait('@getMellomlagring');
490+
cy.findByRole('button', { name: TEXTS.grensesnitt.navigation.saveAndContinue }).should('exist');
491+
cy.findByText(/Alle steg som mangler informasjon er markert med/).should('not.exist');
492+
cy.findByRole('heading', { name: TEXTS.statiske.summaryPage.title }).should('exist');
493+
cy.clickSaveAndContinue();
494+
cy.wait('@submitMellomlagring');
495+
});
462496
});
463497
});
464498
});

packages/shared-components/src/formio/components/base/index.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ interface ReactComponentType {
4343
} | null;
4444
builderMode: boolean;
4545
validators: any[];
46-
init(): any;
46+
init(options?: {}): any;
4747
redraw(): any;
4848
attach(element: any): any;
4949
detach(): void;

packages/shared-components/src/formio/components/core/select/Select.tsx

+5-2
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ const ReactSelectWrapper = ({
9494
);
9595
};
9696

97+
type SelectInitOptions = { skipOnlyAvailableItems?: boolean };
98+
9799
/**
98100
* TODO: Rename this to Select and dont use wrapper when we change to Aksel component.
99101
*/
@@ -180,9 +182,10 @@ class NavSelect extends BaseComponent {
180182
}
181183
}
182184

183-
init() {
185+
init(options: SelectInitOptions = {}) {
184186
super.init();
185-
this.validators = this.validators.concat(['onlyAvailableItems']);
187+
const { skipOnlyAvailableItems = false } = options;
188+
this.validators = this.validators.concat(skipOnlyAvailableItems ? [] : ['onlyAvailableItems']);
186189
this.loadItems();
187190
}
188191

packages/shared-components/src/formio/components/extensions/country-select/CountrySelect.ts

+8
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,17 @@ class CountrySelect extends NavSelect {
1313
},
1414
dataSrc: 'url',
1515
disableLimit: true,
16+
validate: {
17+
required: true,
18+
onlyAvailableItems: false,
19+
},
1620
};
1721
}
1822

23+
init() {
24+
super.init({ skipOnlyAvailableItems: true });
25+
}
26+
1927
static get builderInfo() {
2028
return countrySelectBuilder();
2129
}

packages/shared-components/src/formio/components/extensions/currency-select/CurrencySelect.ts

+8
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,17 @@ class CurrencySelect extends NavSelect {
1414
},
1515
dataSrc: 'url',
1616
disableLimit: true,
17+
validate: {
18+
required: true,
19+
onlyAvailableItems: false,
20+
},
1721
};
1822
}
1923

24+
init() {
25+
super.init({ skipOnlyAvailableItems: true });
26+
}
27+
2028
static get builderInfo() {
2129
return currencySelectBuilder();
2230
}

0 commit comments

Comments
 (0)