diff --git a/apps/ekstra-omsorgsdager-andre-forelder-ikke-tilsyn/mockServiceWorker.js b/apps/ekstra-omsorgsdager-andre-forelder-ikke-tilsyn/mockServiceWorker.js index be4527c7ee..fff922cccf 100644 --- a/apps/ekstra-omsorgsdager-andre-forelder-ikke-tilsyn/mockServiceWorker.js +++ b/apps/ekstra-omsorgsdager-andre-forelder-ikke-tilsyn/mockServiceWorker.js @@ -7,160 +7,157 @@ * - Please do NOT modify this file. */ -const PACKAGE_VERSION = '2.10.4' -const INTEGRITY_CHECKSUM = 'f5825c521429caf22a4dd13b66e243af' -const IS_MOCKED_RESPONSE = Symbol('isMockedResponse') -const activeClientIds = new Set() +const PACKAGE_VERSION = '2.10.4'; +const INTEGRITY_CHECKSUM = 'f5825c521429caf22a4dd13b66e243af'; +const IS_MOCKED_RESPONSE = Symbol('isMockedResponse'); +const activeClientIds = new Set(); addEventListener('install', function () { - self.skipWaiting() -}) + self.skipWaiting(); +}); addEventListener('activate', function (event) { - event.waitUntil(self.clients.claim()) -}) + event.waitUntil(self.clients.claim()); +}); addEventListener('message', async function (event) { - const clientId = Reflect.get(event.source || {}, 'id') + const clientId = Reflect.get(event.source || {}, 'id'); - if (!clientId || !self.clients) { - return - } - - const client = await self.clients.get(clientId) - - if (!client) { - return - } + if (!clientId || !self.clients) { + return; + } - const allClients = await self.clients.matchAll({ - type: 'window', - }) + const client = await self.clients.get(clientId); - switch (event.data) { - case 'KEEPALIVE_REQUEST': { - sendToClient(client, { - type: 'KEEPALIVE_RESPONSE', - }) - break + if (!client) { + return; } - case 'INTEGRITY_CHECK_REQUEST': { - sendToClient(client, { - type: 'INTEGRITY_CHECK_RESPONSE', - payload: { - packageVersion: PACKAGE_VERSION, - checksum: INTEGRITY_CHECKSUM, - }, - }) - break + const allClients = await self.clients.matchAll({ + type: 'window', + }); + + switch (event.data) { + case 'KEEPALIVE_REQUEST': { + sendToClient(client, { + type: 'KEEPALIVE_RESPONSE', + }); + break; + } + + case 'INTEGRITY_CHECK_REQUEST': { + sendToClient(client, { + type: 'INTEGRITY_CHECK_RESPONSE', + payload: { + packageVersion: PACKAGE_VERSION, + checksum: INTEGRITY_CHECKSUM, + }, + }); + break; + } + + case 'MOCK_ACTIVATE': { + activeClientIds.add(clientId); + + sendToClient(client, { + type: 'MOCKING_ENABLED', + payload: { + client: { + id: client.id, + frameType: client.frameType, + }, + }, + }); + break; + } + + case 'MOCK_DEACTIVATE': { + activeClientIds.delete(clientId); + break; + } + + case 'CLIENT_CLOSED': { + activeClientIds.delete(clientId); + + const remainingClients = allClients.filter((client) => { + return client.id !== clientId; + }); + + // Unregister itself when there are no more clients + if (remainingClients.length === 0) { + self.registration.unregister(); + } + + break; + } } +}); - case 'MOCK_ACTIVATE': { - activeClientIds.add(clientId) - - sendToClient(client, { - type: 'MOCKING_ENABLED', - payload: { - client: { - id: client.id, - frameType: client.frameType, - }, - }, - }) - break +addEventListener('fetch', function (event) { + // Bypass navigation requests. + if (event.request.mode === 'navigate') { + return; } - case 'MOCK_DEACTIVATE': { - activeClientIds.delete(clientId) - break + // Opening the DevTools triggers the "only-if-cached" request + // that cannot be handled by the worker. Bypass such requests. + if (event.request.cache === 'only-if-cached' && event.request.mode !== 'same-origin') { + return; } - case 'CLIENT_CLOSED': { - activeClientIds.delete(clientId) - - const remainingClients = allClients.filter((client) => { - return client.id !== clientId - }) - - // Unregister itself when there are no more clients - if (remainingClients.length === 0) { - self.registration.unregister() - } - - break + // Bypass all requests when there are no active clients. + // Prevents the self-unregistered worked from handling requests + // after it's been deleted (still remains active until the next reload). + if (activeClientIds.size === 0) { + return; } - } -}) -addEventListener('fetch', function (event) { - // Bypass navigation requests. - if (event.request.mode === 'navigate') { - return - } - - // Opening the DevTools triggers the "only-if-cached" request - // that cannot be handled by the worker. Bypass such requests. - if ( - event.request.cache === 'only-if-cached' && - event.request.mode !== 'same-origin' - ) { - return - } - - // Bypass all requests when there are no active clients. - // Prevents the self-unregistered worked from handling requests - // after it's been deleted (still remains active until the next reload). - if (activeClientIds.size === 0) { - return - } - - const requestId = crypto.randomUUID() - event.respondWith(handleRequest(event, requestId)) -}) + const requestId = crypto.randomUUID(); + event.respondWith(handleRequest(event, requestId)); +}); /** * @param {FetchEvent} event * @param {string} requestId */ async function handleRequest(event, requestId) { - const client = await resolveMainClient(event) - const requestCloneForEvents = event.request.clone() - const response = await getResponse(event, client, requestId) - - // Send back the response clone for the "response:*" life-cycle events. - // Ensure MSW is active and ready to handle the message, otherwise - // this message will pend indefinitely. - if (client && activeClientIds.has(client.id)) { - const serializedRequest = await serializeRequest(requestCloneForEvents) - - // Clone the response so both the client and the library could consume it. - const responseClone = response.clone() - - sendToClient( - client, - { - type: 'RESPONSE', - payload: { - isMockedResponse: IS_MOCKED_RESPONSE in response, - request: { - id: requestId, - ...serializedRequest, - }, - response: { - type: responseClone.type, - status: responseClone.status, - statusText: responseClone.statusText, - headers: Object.fromEntries(responseClone.headers.entries()), - body: responseClone.body, - }, - }, - }, - responseClone.body ? [serializedRequest.body, responseClone.body] : [], - ) - } + const client = await resolveMainClient(event); + const requestCloneForEvents = event.request.clone(); + const response = await getResponse(event, client, requestId); + + // Send back the response clone for the "response:*" life-cycle events. + // Ensure MSW is active and ready to handle the message, otherwise + // this message will pend indefinitely. + if (client && activeClientIds.has(client.id)) { + const serializedRequest = await serializeRequest(requestCloneForEvents); + + // Clone the response so both the client and the library could consume it. + const responseClone = response.clone(); + + sendToClient( + client, + { + type: 'RESPONSE', + payload: { + isMockedResponse: IS_MOCKED_RESPONSE in response, + request: { + id: requestId, + ...serializedRequest, + }, + response: { + type: responseClone.type, + status: responseClone.status, + statusText: responseClone.statusText, + headers: Object.fromEntries(responseClone.headers.entries()), + body: responseClone.body, + }, + }, + }, + responseClone.body ? [serializedRequest.body, responseClone.body] : [], + ); + } - return response + return response; } /** @@ -172,30 +169,30 @@ async function handleRequest(event, requestId) { * @returns {Promise} */ async function resolveMainClient(event) { - const client = await self.clients.get(event.clientId) - - if (activeClientIds.has(event.clientId)) { - return client - } - - if (client?.frameType === 'top-level') { - return client - } - - const allClients = await self.clients.matchAll({ - type: 'window', - }) - - return allClients - .filter((client) => { - // Get only those clients that are currently visible. - return client.visibilityState === 'visible' - }) - .find((client) => { - // Find the client ID that's recorded in the - // set of clients that have registered the worker. - return activeClientIds.has(client.id) - }) + const client = await self.clients.get(event.clientId); + + if (activeClientIds.has(event.clientId)) { + return client; + } + + if (client?.frameType === 'top-level') { + return client; + } + + const allClients = await self.clients.matchAll({ + type: 'window', + }); + + return allClients + .filter((client) => { + // Get only those clients that are currently visible. + return client.visibilityState === 'visible'; + }) + .find((client) => { + // Find the client ID that's recorded in the + // set of clients that have registered the worker. + return activeClientIds.has(client.id); + }); } /** @@ -205,73 +202,71 @@ async function resolveMainClient(event) { * @returns {Promise} */ async function getResponse(event, client, requestId) { - // Clone the request because it might've been already used - // (i.e. its body has been read and sent to the client). - const requestClone = event.request.clone() - - function passthrough() { - // Cast the request headers to a new Headers instance - // so the headers can be manipulated with. - const headers = new Headers(requestClone.headers) - - // Remove the "accept" header value that marked this request as passthrough. - // This prevents request alteration and also keeps it compliant with the - // user-defined CORS policies. - const acceptHeader = headers.get('accept') - if (acceptHeader) { - const values = acceptHeader.split(',').map((value) => value.trim()) - const filteredValues = values.filter( - (value) => value !== 'msw/passthrough', - ) - - if (filteredValues.length > 0) { - headers.set('accept', filteredValues.join(', ')) - } else { - headers.delete('accept') - } + // Clone the request because it might've been already used + // (i.e. its body has been read and sent to the client). + const requestClone = event.request.clone(); + + function passthrough() { + // Cast the request headers to a new Headers instance + // so the headers can be manipulated with. + const headers = new Headers(requestClone.headers); + + // Remove the "accept" header value that marked this request as passthrough. + // This prevents request alteration and also keeps it compliant with the + // user-defined CORS policies. + const acceptHeader = headers.get('accept'); + if (acceptHeader) { + const values = acceptHeader.split(',').map((value) => value.trim()); + const filteredValues = values.filter((value) => value !== 'msw/passthrough'); + + if (filteredValues.length > 0) { + headers.set('accept', filteredValues.join(', ')); + } else { + headers.delete('accept'); + } + } + + return fetch(requestClone, { headers }); } - return fetch(requestClone, { headers }) - } - - // Bypass mocking when the client is not active. - if (!client) { - return passthrough() - } - - // Bypass initial page load requests (i.e. static assets). - // The absence of the immediate/parent client in the map of the active clients - // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet - // and is not ready to handle requests. - if (!activeClientIds.has(client.id)) { - return passthrough() - } - - // Notify the client that a request has been intercepted. - const serializedRequest = await serializeRequest(event.request) - const clientMessage = await sendToClient( - client, - { - type: 'REQUEST', - payload: { - id: requestId, - ...serializedRequest, - }, - }, - [serializedRequest.body], - ) - - switch (clientMessage.type) { - case 'MOCK_RESPONSE': { - return respondWithMock(clientMessage.data) + // Bypass mocking when the client is not active. + if (!client) { + return passthrough(); } - case 'PASSTHROUGH': { - return passthrough() + // Bypass initial page load requests (i.e. static assets). + // The absence of the immediate/parent client in the map of the active clients + // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet + // and is not ready to handle requests. + if (!activeClientIds.has(client.id)) { + return passthrough(); + } + + // Notify the client that a request has been intercepted. + const serializedRequest = await serializeRequest(event.request); + const clientMessage = await sendToClient( + client, + { + type: 'REQUEST', + payload: { + id: requestId, + ...serializedRequest, + }, + }, + [serializedRequest.body], + ); + + switch (clientMessage.type) { + case 'MOCK_RESPONSE': { + return respondWithMock(clientMessage.data); + } + + case 'PASSTHROUGH': { + return passthrough(); + } } - } - return passthrough() + return passthrough(); } /** @@ -281,22 +276,19 @@ async function getResponse(event, client, requestId) { * @returns {Promise} */ function sendToClient(client, message, transferrables = []) { - return new Promise((resolve, reject) => { - const channel = new MessageChannel() + return new Promise((resolve, reject) => { + const channel = new MessageChannel(); - channel.port1.onmessage = (event) => { - if (event.data && event.data.error) { - return reject(event.data.error) - } + channel.port1.onmessage = (event) => { + if (event.data && event.data.error) { + return reject(event.data.error); + } - resolve(event.data) - } + resolve(event.data); + }; - client.postMessage(message, [ - channel.port2, - ...transferrables.filter(Boolean), - ]) - }) + client.postMessage(message, [channel.port2, ...transferrables.filter(Boolean)]); + }); } /** @@ -304,41 +296,41 @@ function sendToClient(client, message, transferrables = []) { * @returns {Response} */ function respondWithMock(response) { - // Setting response status code to 0 is a no-op. - // However, when responding with a "Response.error()", the produced Response - // instance will have status code set to 0. Since it's not possible to create - // a Response instance with status code 0, handle that use-case separately. - if (response.status === 0) { - return Response.error() - } - - const mockedResponse = new Response(response.body, response) - - Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, { - value: true, - enumerable: true, - }) - - return mockedResponse + // Setting response status code to 0 is a no-op. + // However, when responding with a "Response.error()", the produced Response + // instance will have status code set to 0. Since it's not possible to create + // a Response instance with status code 0, handle that use-case separately. + if (response.status === 0) { + return Response.error(); + } + + const mockedResponse = new Response(response.body, response); + + Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, { + value: true, + enumerable: true, + }); + + return mockedResponse; } /** * @param {Request} request */ async function serializeRequest(request) { - return { - url: request.url, - mode: request.mode, - method: request.method, - headers: Object.fromEntries(request.headers.entries()), - cache: request.cache, - credentials: request.credentials, - destination: request.destination, - integrity: request.integrity, - redirect: request.redirect, - referrer: request.referrer, - referrerPolicy: request.referrerPolicy, - body: await request.arrayBuffer(), - keepalive: request.keepalive, - } + return { + url: request.url, + mode: request.mode, + method: request.method, + headers: Object.fromEntries(request.headers.entries()), + cache: request.cache, + credentials: request.credentials, + destination: request.destination, + integrity: request.integrity, + redirect: request.redirect, + referrer: request.referrer, + referrerPolicy: request.referrerPolicy, + body: await request.arrayBuffer(), + keepalive: request.keepalive, + }; } diff --git a/apps/endringsmelding-pleiepenger/mock/data/app/arbeidsukerMockData.ts b/apps/endringsmelding-pleiepenger/mock/data/app/arbeidsukerMockData.ts index a82e19841e..2891baf704 100644 --- a/apps/endringsmelding-pleiepenger/mock/data/app/arbeidsukerMockData.ts +++ b/apps/endringsmelding-pleiepenger/mock/data/app/arbeidsukerMockData.ts @@ -7,6 +7,7 @@ import { getDatesInDateRange, ISODateRange, ISODateRangeToDateRange, + ISODateToDate, } from '@navikt/sif-common-utils'; import { ArbeidstidEnkeltdagMap, Arbeidsuke } from '@types'; @@ -33,6 +34,7 @@ const getMockArbeidsuke = ( isoDateRange, periode, arbeidstidEnkeltdager, + dagerSøktFor: dagerSøktFor.map(ISODateToDate), normalt: { uke: decimalDurationToDuration(durationToDecimalDuration(normaltPerDag) * antallDagerMedArbeidstid), dag: normaltPerDag, diff --git a/apps/endringsmelding-pleiepenger/mock/data/scenario/arbeidsgiver-ikke-i-sak-flere-ansettelser/ArbeidsgiverIkkeISakFlereAnsettelser.ts b/apps/endringsmelding-pleiepenger/mock/data/scenario/arbeidsgiver-ikke-i-sak-flere-ansettelser/ArbeidsgiverIkkeISakFlereAnsettelser.ts new file mode 100644 index 0000000000..acb4dd2797 --- /dev/null +++ b/apps/endringsmelding-pleiepenger/mock/data/scenario/arbeidsgiver-ikke-i-sak-flere-ansettelser/ArbeidsgiverIkkeISakFlereAnsettelser.ts @@ -0,0 +1,10 @@ +import { ScenarioData } from '..'; +import arbeidsgiver from './arbeidsgiver-mock'; +import sak from './sak-mock'; +import søker from './søker-mock'; + +export const ArbeidsgiverIkkeISakFlereAnsettelser: ScenarioData = { + sak, + arbeidsgiver, + søker, +}; diff --git a/apps/endringsmelding-pleiepenger/mock/data/scenario/arbeidsgiver-ikke-i-sak-flere-ansettelser/arbeidsgiver-mock.ts b/apps/endringsmelding-pleiepenger/mock/data/scenario/arbeidsgiver-ikke-i-sak-flere-ansettelser/arbeidsgiver-mock.ts new file mode 100644 index 0000000000..a45b295c82 --- /dev/null +++ b/apps/endringsmelding-pleiepenger/mock/data/scenario/arbeidsgiver-ikke-i-sak-flere-ansettelser/arbeidsgiver-mock.ts @@ -0,0 +1,8 @@ +export default { + organisasjoner: [ + { navn: 'Dykkert svømmeutstyr', organisasjonsnummer: '947064649', ansattFom: '2008-10-01' }, + { navn: 'Vinge flyfly', organisasjonsnummer: '947064640', ansattFom: '2008-10-01' }, + { navn: 'IKKE-I-SAK-AS 1', organisasjonsnummer: '947064642', ansattFom: '2023-02-05', ansattTom: '2023-04-05' }, + { navn: 'IKKE-I-SAK-AS 1', organisasjonsnummer: '947064642', ansattFom: '2023-04-06' }, + ], +}; diff --git a/apps/endringsmelding-pleiepenger/mock/data/scenario/arbeidsgiver-ikke-i-sak-flere-ansettelser/sak-mock.ts b/apps/endringsmelding-pleiepenger/mock/data/scenario/arbeidsgiver-ikke-i-sak-flere-ansettelser/sak-mock.ts new file mode 100644 index 0000000000..5f9c1a3f8f --- /dev/null +++ b/apps/endringsmelding-pleiepenger/mock/data/scenario/arbeidsgiver-ikke-i-sak-flere-ansettelser/sak-mock.ts @@ -0,0 +1,343 @@ +export default [ + { + barn: { + fødselsdato: '2017-03-03', + fornavn: 'NORA', + mellomnavn: null, + etternavn: 'Nordmann', + aktørId: '2559652436225', + identitetsnummer: '03831799748', + }, + søknad: { + søknadId: 'generert', + versjon: '1.0.0.', + mottattDato: '2023-01-18T08:13:37.525Z', + søker: { norskIdentitetsnummer: '00000000000' }, + ytelse: { + type: 'PLEIEPENGER_SYKT_BARN', + barn: { norskIdentitetsnummer: '00000000000', fødselsdato: null }, + søknadsperiode: ['2022-01-01/2024-09-31'], + endringsperiode: [], + trekkKravPerioder: [], + opptjeningAktivitet: {}, + dataBruktTilUtledning: null, + infoFraPunsj: null, + bosteder: { perioder: {}, perioderSomSkalSlettes: {} }, + utenlandsopphold: { perioder: {}, perioderSomSkalSlettes: {} }, + beredskap: { perioder: {}, perioderSomSkalSlettes: {} }, + nattevåk: { perioder: {}, perioderSomSkalSlettes: {} }, + tilsynsordning: { + perioder: { + '2022-12-01/2023-01-31': { etablertTilsynTimerPerDag: 'PT8H' }, + '2023-02-14/2023-03-16': { etablertTilsynTimerPerDag: 'PT8H' }, + }, + }, + lovbestemtFerie: { + perioder: { + '2023-01-12/2023-01-15': { + skalHaFerie: false, + }, + }, + }, + arbeidstid: { + arbeidstakerList: [ + { + norskIdentitetsnummer: null, + organisasjonsnummer: '947064649', + arbeidstidInfo: { + perioder: { + '2022-01-01/2022-03-25': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-03-28/2022-04-01': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-04-04/2022-04-08': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-04-11/2022-04-15': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-04-18/2022-04-22': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-04-25/2022-04-29': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-05-02/2022-05-06': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-05-09/2022-05-13': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-05-16/2022-05-20': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-05-23/2022-05-27': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-05-30/2022-06-03': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-06-06/2022-06-10': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-06-13/2022-06-17': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-06-20/2022-06-24': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-06-27/2022-06-30': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-07-01/2022-07-01': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT7H30M', + }, + '2022-07-04/2022-07-07': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-07-08/2022-07-08': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT7H30M', + }, + '2022-07-11/2022-07-14': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-07-15/2022-07-15': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT7H30M', + }, + '2022-07-18/2022-07-21': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-07-22/2022-07-22': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT7H30M', + }, + '2022-07-25/2022-07-28': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-07-29/2022-07-29': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT7H30M', + }, + '2022-08-01/2022-08-04': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-08-05/2022-08-05': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT7H30M', + }, + '2022-08-08/2022-08-11': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-08-12/2022-08-12': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT7H30M', + }, + '2022-08-15/2022-08-18': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-08-19/2022-08-19': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT7H30M', + }, + '2022-08-22/2022-08-25': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-08-26/2022-08-26': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT7H30M', + }, + '2022-08-29/2022-08-31': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-09-01/2022-09-01': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT3H', + }, + '2022-09-02/2022-09-02': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT4H30M', + }, + '2022-09-05/2022-09-05': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-09-06/2022-09-06': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT2H30M', + }, + '2022-09-07/2022-09-08': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-09-09/2022-09-09': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT5H', + }, + '2022-09-12/2022-09-13': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-09-14/2022-09-14': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT4H', + }, + '2022-09-15/2022-09-15': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT3H30M', + }, + '2022-09-16/2022-09-16': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT7H30M', + }, + '2022-09-19/2022-09-22': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-09-23/2022-09-23': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT7H30M', + }, + '2022-09-26/2022-09-29': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-09-30/2022-09-30': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT7H30M', + }, + '2022-10-03/2024-12-30': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + }, + }, + }, + { + norskIdentitetsnummer: null, + organisasjonsnummer: '947064640', + arbeidstidInfo: { + perioder: { + '2022-09-01/2022-09-30': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-10-03/2022-12-30': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2023-01-01/2023-01-15': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2023-01-16/2023-03-12': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT4H30M', + }, + '2023-03-13/2023-09-31': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + }, + }, + }, + ], + frilanserArbeidstidInfo: { + perioder: { + '2022-06-25/2022-12-31': { + jobberNormaltTimerPerDag: 'PT0S', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2023-01-02/2023-01-06': { + jobberNormaltTimerPerDag: 'PT3H', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2023-01-09/2023-01-13': { + jobberNormaltTimerPerDag: 'PT3H', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2023-01-16/2023-01-20': { + jobberNormaltTimerPerDag: 'PT3H', + faktiskArbeidTimerPerDag: 'PT3H', + }, + '2023-01-23/2023-01-27': { + jobberNormaltTimerPerDag: 'PT3H', + faktiskArbeidTimerPerDag: 'PT3H', + }, + '2023-01-30/2023-02-03': { + jobberNormaltTimerPerDag: 'PT3H', + faktiskArbeidTimerPerDag: 'PT3H', + }, + '2023-02-06/2023-02-10': { + jobberNormaltTimerPerDag: 'PT3H', + faktiskArbeidTimerPerDag: 'PT3H', + }, + '2023-02-13/2023-02-17': { + jobberNormaltTimerPerDag: 'PT3H', + faktiskArbeidTimerPerDag: 'PT3H', + }, + '2023-02-20/2023-02-24': { + jobberNormaltTimerPerDag: 'PT3H', + faktiskArbeidTimerPerDag: 'PT3H', + }, + '2023-02-27/2023-03-03': { + jobberNormaltTimerPerDag: 'PT3H', + faktiskArbeidTimerPerDag: 'PT3H', + }, + '2023-03-06/2023-03-10': { + jobberNormaltTimerPerDag: 'PT3H', + faktiskArbeidTimerPerDag: 'PT3H', + }, + '2023-03-13/2023-03-17': { + jobberNormaltTimerPerDag: 'PT3H', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2023-03-20/2023-03-24': { + jobberNormaltTimerPerDag: 'PT3H', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2023-03-27/2023-09-31': { + jobberNormaltTimerPerDag: 'PT3H', + faktiskArbeidTimerPerDag: 'PT0S', + }, + }, + }, + selvstendigNæringsdrivendeArbeidstidInfo: {}, + }, + uttak: { perioder: {} }, + omsorg: { relasjonTilBarnet: null, beskrivelseAvOmsorgsrollen: null }, + }, + språk: 'nb', + journalposter: [], + begrunnelseForInnsending: { tekst: null }, + }, + }, +]; diff --git "a/apps/endringsmelding-pleiepenger/mock/data/scenario/arbeidsgiver-ikke-i-sak-flere-ansettelser/s\303\270ker-mock.ts" "b/apps/endringsmelding-pleiepenger/mock/data/scenario/arbeidsgiver-ikke-i-sak-flere-ansettelser/s\303\270ker-mock.ts" new file mode 100644 index 0000000000..2dd3e1c484 --- /dev/null +++ "b/apps/endringsmelding-pleiepenger/mock/data/scenario/arbeidsgiver-ikke-i-sak-flere-ansettelser/s\303\270ker-mock.ts" @@ -0,0 +1,8 @@ +export default { + aktørId: '234', + fødselsnummer: '30086421581', + fødselsdato: '2001-02-01', + fornavn: 'NORA', + mellomnavn: null, + etternavn: 'KRONJUVEL', +}; diff --git a/apps/endringsmelding-pleiepenger/mock/data/scenario/arbeidsgiver-ikke-i-sak/arbeidsgiver-mock.ts b/apps/endringsmelding-pleiepenger/mock/data/scenario/arbeidsgiver-ikke-i-sak/arbeidsgiver-mock.ts index d1f2d8394d..767079758f 100644 --- a/apps/endringsmelding-pleiepenger/mock/data/scenario/arbeidsgiver-ikke-i-sak/arbeidsgiver-mock.ts +++ b/apps/endringsmelding-pleiepenger/mock/data/scenario/arbeidsgiver-ikke-i-sak/arbeidsgiver-mock.ts @@ -2,7 +2,7 @@ export default { organisasjoner: [ { navn: 'Dykkert svømmeutstyr', organisasjonsnummer: '947064649', ansattFom: '2008-10-01' }, { navn: 'Vinge flyfly', organisasjonsnummer: '947064640', ansattFom: '2008-10-01' }, - { navn: 'IKKE-I-SAK-AS 1', organisasjonsnummer: '947064642', ansattFom: '2023-02-01' }, + { navn: 'IKKE-I-SAK-AS 1', organisasjonsnummer: '947064642', ansattFom: '2023-02-05' }, { navn: 'IKKE-I-SAK-AS 2', organisasjonsnummer: '947064643', ansattFom: '2023-02-01' }, ], }; diff --git a/apps/endringsmelding-pleiepenger/mock/data/scenario/debug/arbeidsgiver-mock.ts b/apps/endringsmelding-pleiepenger/mock/data/scenario/debug/arbeidsgiver-mock.ts index a5c1abb86b..f1f6838bf5 100644 --- a/apps/endringsmelding-pleiepenger/mock/data/scenario/debug/arbeidsgiver-mock.ts +++ b/apps/endringsmelding-pleiepenger/mock/data/scenario/debug/arbeidsgiver-mock.ts @@ -1,5 +1,8 @@ export default { - organisasjoner: [], - privateArbeidsgivere: null, - frilansoppdrag: null, + frilansoppdrag: [], + organisasjoner: [ + { ansattFom: '2005-01-09', ansattTom: '2024-11-01', navn: 'SAUEFABRIKK', organisasjonsnummer: '896929119' }, + { ansattFom: '2024-12-12', ansattTom: null, navn: 'SAUEFABRIKK', organisasjonsnummer: '896929119' }, + ], + privateArbeidsgivere: [], }; diff --git a/apps/endringsmelding-pleiepenger/mock/data/scenario/debug/sak-mock.ts b/apps/endringsmelding-pleiepenger/mock/data/scenario/debug/sak-mock.ts index b341db01ac..23b0466153 100644 --- a/apps/endringsmelding-pleiepenger/mock/data/scenario/debug/sak-mock.ts +++ b/apps/endringsmelding-pleiepenger/mock/data/scenario/debug/sak-mock.ts @@ -1,28 +1,28 @@ export default [ { barn: { - fødselsdato: '2008-07-27', - fornavn: 'RAVGUL', + fødselsdato: '2023-01-24', + fornavn: 'GEOMETRISK', mellomnavn: null, - etternavn: 'LØVETANN', - aktørId: '2175638020356', - identitetsnummer: '27870899799', + etternavn: 'RIST', + aktørId: '2487158514882', + identitetsnummer: '24412358038', }, søknad: { søknadId: 'generert', versjon: '1.0.0', - mottattDato: '2024-12-10T08:47:11.929Z', + mottattDato: '2025-01-24T07:51:23.794Z', søker: { norskIdentitetsnummer: '00000000000', }, - språk: null, + språk: 'nb', ytelse: { type: 'PLEIEPENGER_SYKT_BARN', barn: { norskIdentitetsnummer: '00000000000', fødselsdato: null, }, - søknadsperiode: ['2024-12-03/2024-12-05'], + søknadsperiode: ['2024-11-01/2025-02-28'], endringsperiode: [], trekkKravPerioder: [], opptjeningAktivitet: {}, @@ -47,23 +47,37 @@ export default [ }, tilsynsordning: { perioder: { - '2024-12-03/2024-12-05': { + '2024-11-01/2025-02-28': { etablertTilsynTimerPerDag: 'PT0S', }, }, }, lovbestemtFerie: { - perioder: { - '2024-12-04/2024-12-05': { - skalHaFerie: false, - }, - }, + perioder: {}, }, arbeidstid: { - arbeidstakerList: [], + arbeidstakerList: [ + { + norskIdentitetsnummer: null, + organisasjonsnummer: '896929119', + organisasjonsnavn: null, + arbeidstidInfo: { + perioder: { + '2024-11-01/2024-11-30': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2024-12-01/2025-02-28': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT0S', + }, + }, + }, + }, + ], frilanserArbeidstidInfo: { perioder: { - '2024-12-03/2024-12-05': { + '2024-11-01/2025-02-28': { jobberNormaltTimerPerDag: 'PT0S', faktiskArbeidTimerPerDag: 'PT0S', }, diff --git "a/apps/endringsmelding-pleiepenger/mock/data/scenario/debug/s\303\270ker-mock.ts" "b/apps/endringsmelding-pleiepenger/mock/data/scenario/debug/s\303\270ker-mock.ts" index b80d44748e..0921da2df9 100644 --- "a/apps/endringsmelding-pleiepenger/mock/data/scenario/debug/s\303\270ker-mock.ts" +++ "b/apps/endringsmelding-pleiepenger/mock/data/scenario/debug/s\303\270ker-mock.ts" @@ -1,9 +1,8 @@ export default { - aktørId: '2486083225079', - fødselsdato: '1987-10-09', - fødselsnummer: '09908799647', - fornavn: 'NORA', + aktørId: '2912771641580', + etternavn: 'FJORD', + fornavn: 'TØFF', + fødselsdato: '1983-05-26', + fødselsnummer: '26458341337', mellomnavn: null, - etternavn: 'Etternavn', - myndig: true, }; diff --git a/apps/endringsmelding-pleiepenger/mock/data/scenario/en-arbeidsgiver-en-periode/arbeidsgiver-mock.ts b/apps/endringsmelding-pleiepenger/mock/data/scenario/en-arbeidsgiver-en-periode/arbeidsgiver-mock.ts index 74e2a56eec..d96164a10d 100644 --- a/apps/endringsmelding-pleiepenger/mock/data/scenario/en-arbeidsgiver-en-periode/arbeidsgiver-mock.ts +++ b/apps/endringsmelding-pleiepenger/mock/data/scenario/en-arbeidsgiver-en-periode/arbeidsgiver-mock.ts @@ -4,7 +4,6 @@ export default { organisasjonsnummer: '947064649', navn: 'Norsk bedrift AS', ansattFom: '2003-01-16', - ansattTom: null, }, ], privateArbeidsgivere: null, diff --git a/apps/endringsmelding-pleiepenger/mock/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold/EnArbeidsgiverToAnsettelserSammeUkeMedOpphold.ts b/apps/endringsmelding-pleiepenger/mock/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold/EnArbeidsgiverToAnsettelserSammeUkeMedOpphold.ts new file mode 100644 index 0000000000..64031f82f0 --- /dev/null +++ b/apps/endringsmelding-pleiepenger/mock/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold/EnArbeidsgiverToAnsettelserSammeUkeMedOpphold.ts @@ -0,0 +1,10 @@ +import { ScenarioData } from '..'; +import arbeidsgiver from './arbeidsgiver-mock'; +import sak from './sak-mock'; +import søker from './søker-mock'; + +export const EnArbeidsgiverToAnsettelserSammeUkeMedOpphold: ScenarioData = { + sak, + arbeidsgiver, + søker, +}; diff --git a/apps/endringsmelding-pleiepenger/mock/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold/arbeidsgiver-mock.ts b/apps/endringsmelding-pleiepenger/mock/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold/arbeidsgiver-mock.ts new file mode 100644 index 0000000000..a148bdd78a --- /dev/null +++ b/apps/endringsmelding-pleiepenger/mock/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold/arbeidsgiver-mock.ts @@ -0,0 +1,18 @@ +export default { + organisasjoner: [ + { + organisasjonsnummer: '947064649', + navn: 'Norsk bedrift AS', + ansattFom: '2003-01-16', + ansattTom: '2022-01-11', + }, + { + organisasjonsnummer: '947064649', + navn: 'Norsk bedrift AS', + ansattFom: '2022-01-13', + ansattTom: null, + }, + ], + privateArbeidsgivere: null, + frilansoppdrag: null, +}; diff --git a/apps/endringsmelding-pleiepenger/mock/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold/sak-mock.ts b/apps/endringsmelding-pleiepenger/mock/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold/sak-mock.ts new file mode 100644 index 0000000000..8b2cc9fe4d --- /dev/null +++ b/apps/endringsmelding-pleiepenger/mock/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold/sak-mock.ts @@ -0,0 +1,114 @@ +export default [ + { + barn: { + fødselsdato: '2017-03-03', + fornavn: 'NORA', + mellomnavn: null, + etternavn: 'Nordmann', + aktørId: '2559652436225', + identitetsnummer: '03831799748', + }, + søknad: { + søknadId: 'generert', + versjon: '1.0.0.', + mottattDato: '2023-01-18T08:13:37.525Z', + søker: { norskIdentitetsnummer: '00000000000' }, + ytelse: { + type: 'PLEIEPENGER_SYKT_BARN', + barn: { norskIdentitetsnummer: '00000000000', fødselsdato: null }, + søknadsperiode: ['2022-12-01/2024-05-31'], + endringsperiode: [], + trekkKravPerioder: [], + opptjeningAktivitet: {}, + dataBruktTilUtledning: null, + infoFraPunsj: null, + bosteder: { perioder: {}, perioderSomSkalSlettes: {} }, + utenlandsopphold: { + perioder: { + '2018-12-30/2019-10-20': { + land: 'DNK', + årsak: 'barnetInnlagtIHelseinstitusjonForNorskOffentligRegning', + }, + }, + }, + beredskap: { perioder: {}, perioderSomSkalSlettes: {} }, + nattevåk: { perioder: {}, perioderSomSkalSlettes: {} }, + tilsynsordning: { + perioder: { + '2022-12-01/2023-01-31': { etablertTilsynTimerPerDag: 'PT8H' }, + '2023-02-14/2023-03-16': { etablertTilsynTimerPerDag: 'PT8H' }, + }, + }, + lovbestemtFerie: { + perioder: { + '2023-01-01/2023-01-10': { + skalHaFerie: true, + }, + '2023-01-12/2023-01-15': { + skalHaFerie: false, + }, + }, + }, + arbeidstid: { + arbeidstakerList: [ + { + norskIdentitetsnummer: null, + organisasjonsnummer: '947064649', + arbeidstidInfo: { + perioder: { + '2022-12-01/2022-12-02': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2022-12-05/2022-12-09': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2022-12-12/2022-12-16': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2022-12-19/2022-12-23': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2022-12-26/2022-12-30': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2023-01-02/2023-01-06': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2023-01-09/2023-01-13': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2023-01-16/2023-01-20': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2023-01-23/2023-01-27': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2023-01-30/2024-05-31': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + }, + }, + }, + ], + frilanserArbeidstidInfo: {}, + selvstendigNæringsdrivendeArbeidstidInfo: {}, + }, + uttak: { perioder: {} }, + omsorg: { relasjonTilBarnet: null, beskrivelseAvOmsorgsrollen: null }, + }, + språk: 'nb', + journalposter: [], + begrunnelseForInnsending: { tekst: null }, + }, + }, +]; diff --git "a/apps/endringsmelding-pleiepenger/mock/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold/s\303\270ker-mock.ts" "b/apps/endringsmelding-pleiepenger/mock/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold/s\303\270ker-mock.ts" new file mode 100644 index 0000000000..b80d44748e --- /dev/null +++ "b/apps/endringsmelding-pleiepenger/mock/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold/s\303\270ker-mock.ts" @@ -0,0 +1,9 @@ +export default { + aktørId: '2486083225079', + fødselsdato: '1987-10-09', + fødselsnummer: '09908799647', + fornavn: 'NORA', + mellomnavn: null, + etternavn: 'Etternavn', + myndig: true, +}; diff --git a/apps/endringsmelding-pleiepenger/mock/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-uten-opphold/EnArbeidsgiverToAnsettelserSammeUkeUtenOpphold.ts b/apps/endringsmelding-pleiepenger/mock/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-uten-opphold/EnArbeidsgiverToAnsettelserSammeUkeUtenOpphold.ts new file mode 100644 index 0000000000..579142c282 --- /dev/null +++ b/apps/endringsmelding-pleiepenger/mock/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-uten-opphold/EnArbeidsgiverToAnsettelserSammeUkeUtenOpphold.ts @@ -0,0 +1,10 @@ +import { ScenarioData } from '..'; +import arbeidsgiver from './arbeidsgiver-mock'; +import sak from './sak-mock'; +import søker from './søker-mock'; + +export const EnArbeidsgiverToAnsettelserSammeUkeUtenOpphold: ScenarioData = { + sak, + arbeidsgiver, + søker, +}; diff --git a/apps/endringsmelding-pleiepenger/mock/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-uten-opphold/arbeidsgiver-mock.ts b/apps/endringsmelding-pleiepenger/mock/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-uten-opphold/arbeidsgiver-mock.ts new file mode 100644 index 0000000000..049ad63a0c --- /dev/null +++ b/apps/endringsmelding-pleiepenger/mock/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-uten-opphold/arbeidsgiver-mock.ts @@ -0,0 +1,18 @@ +export default { + organisasjoner: [ + { + organisasjonsnummer: '947064649', + navn: 'Norsk bedrift AS', + ansattFom: '2003-01-16', + ansattTom: '2022-12-05', + }, + { + organisasjonsnummer: '947064649', + navn: 'Norsk bedrift AS', + ansattFom: '2023-01-01', + ansattTom: null, + }, + ], + privateArbeidsgivere: null, + frilansoppdrag: null, +}; diff --git a/apps/endringsmelding-pleiepenger/mock/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-uten-opphold/sak-mock.ts b/apps/endringsmelding-pleiepenger/mock/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-uten-opphold/sak-mock.ts new file mode 100644 index 0000000000..8b2cc9fe4d --- /dev/null +++ b/apps/endringsmelding-pleiepenger/mock/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-uten-opphold/sak-mock.ts @@ -0,0 +1,114 @@ +export default [ + { + barn: { + fødselsdato: '2017-03-03', + fornavn: 'NORA', + mellomnavn: null, + etternavn: 'Nordmann', + aktørId: '2559652436225', + identitetsnummer: '03831799748', + }, + søknad: { + søknadId: 'generert', + versjon: '1.0.0.', + mottattDato: '2023-01-18T08:13:37.525Z', + søker: { norskIdentitetsnummer: '00000000000' }, + ytelse: { + type: 'PLEIEPENGER_SYKT_BARN', + barn: { norskIdentitetsnummer: '00000000000', fødselsdato: null }, + søknadsperiode: ['2022-12-01/2024-05-31'], + endringsperiode: [], + trekkKravPerioder: [], + opptjeningAktivitet: {}, + dataBruktTilUtledning: null, + infoFraPunsj: null, + bosteder: { perioder: {}, perioderSomSkalSlettes: {} }, + utenlandsopphold: { + perioder: { + '2018-12-30/2019-10-20': { + land: 'DNK', + årsak: 'barnetInnlagtIHelseinstitusjonForNorskOffentligRegning', + }, + }, + }, + beredskap: { perioder: {}, perioderSomSkalSlettes: {} }, + nattevåk: { perioder: {}, perioderSomSkalSlettes: {} }, + tilsynsordning: { + perioder: { + '2022-12-01/2023-01-31': { etablertTilsynTimerPerDag: 'PT8H' }, + '2023-02-14/2023-03-16': { etablertTilsynTimerPerDag: 'PT8H' }, + }, + }, + lovbestemtFerie: { + perioder: { + '2023-01-01/2023-01-10': { + skalHaFerie: true, + }, + '2023-01-12/2023-01-15': { + skalHaFerie: false, + }, + }, + }, + arbeidstid: { + arbeidstakerList: [ + { + norskIdentitetsnummer: null, + organisasjonsnummer: '947064649', + arbeidstidInfo: { + perioder: { + '2022-12-01/2022-12-02': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2022-12-05/2022-12-09': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2022-12-12/2022-12-16': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2022-12-19/2022-12-23': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2022-12-26/2022-12-30': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2023-01-02/2023-01-06': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2023-01-09/2023-01-13': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2023-01-16/2023-01-20': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2023-01-23/2023-01-27': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2023-01-30/2024-05-31': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + }, + }, + }, + ], + frilanserArbeidstidInfo: {}, + selvstendigNæringsdrivendeArbeidstidInfo: {}, + }, + uttak: { perioder: {} }, + omsorg: { relasjonTilBarnet: null, beskrivelseAvOmsorgsrollen: null }, + }, + språk: 'nb', + journalposter: [], + begrunnelseForInnsending: { tekst: null }, + }, + }, +]; diff --git "a/apps/endringsmelding-pleiepenger/mock/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-uten-opphold/s\303\270ker-mock.ts" "b/apps/endringsmelding-pleiepenger/mock/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-uten-opphold/s\303\270ker-mock.ts" new file mode 100644 index 0000000000..b80d44748e --- /dev/null +++ "b/apps/endringsmelding-pleiepenger/mock/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-uten-opphold/s\303\270ker-mock.ts" @@ -0,0 +1,9 @@ +export default { + aktørId: '2486083225079', + fødselsdato: '1987-10-09', + fødselsnummer: '09908799647', + fornavn: 'NORA', + mellomnavn: null, + etternavn: 'Etternavn', + myndig: true, +}; diff --git a/apps/endringsmelding-pleiepenger/mock/data/scenario/index.ts b/apps/endringsmelding-pleiepenger/mock/data/scenario/index.ts index 47b7bec2d1..4669bb3c06 100644 --- a/apps/endringsmelding-pleiepenger/mock/data/scenario/index.ts +++ b/apps/endringsmelding-pleiepenger/mock/data/scenario/index.ts @@ -1,19 +1,20 @@ import { ScenarioType } from '../../../src/app/dev/scenarioer'; import { ArbeidsaktivitetUtenArbeidsgiver } from './arbeidsaktivitet-uten-arbeidsgiver/ArbeidsaktivitetUtenArbeidsgiver'; import { ArbeidsgiverIkkeISak } from './arbeidsgiver-ikke-i-sak/ArbeidsgiverIkkeISak'; +import { ArbeidsgiverIkkeISakFlereAnsettelser } from './arbeidsgiver-ikke-i-sak-flere-ansettelser/ArbeidsgiverIkkeISakFlereAnsettelser'; import { ArbeidsgiverOgFrilanser } from './arbeidsgiver-og-frilanser/ArbeidsgiverOgFrilanser'; import { ArbeidsgivereOgFrilanser } from './arbeidsgivere-og-frilanser/ArbeidsgivereOgFrilanser'; import { Debug } from './debug/Debug'; import { EnArbeidsgiverEnPeriode } from './en-arbeidsgiver-en-periode/EnArbeidsgiverEnPeriode'; +import { EnArbeidsgiverToAnsettelserSammeUkeMedOpphold } from './en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold/EnArbeidsgiverToAnsettelserSammeUkeMedOpphold'; +import { EnArbeidsgiverToAnsettelserSammeUkeUtenOpphold } from './en-arbeidsgiver-to-ansettelser-samme-uke-uten-opphold/EnArbeidsgiverToAnsettelserSammeUkeUtenOpphold'; import { EnArbeidsgiverToPerioder } from './en-arbeidsgiver-to-perioder/EnArbeidsgiverToPerioder'; import { FlereSaker } from './flere-saker/FlereSaker'; import { IngenSak } from './ingen-sak/IngenSak'; import { SelvstendigNæringsdrivende } from './selvstendig-næringsdrivende/SelvstendigNæringsdrivende'; import { UgyldigK9Format } from './ugyldig-k9-format/UgyldigK9Format'; -type ScenarioMap = { - [key: string]: ScenarioData; -}; +type ScenarioMap = Record; export const mockData: ScenarioMap = { ['en-arbeidsgiver-en-periode']: EnArbeidsgiverEnPeriode, @@ -25,8 +26,11 @@ export const mockData: ScenarioMap = { ['ingen-sak']: IngenSak, ['debug']: Debug, ['arbeidsgiver-ikke-i-sak']: ArbeidsgiverIkkeISak, + ['arbeidsgiver-ikke-i-sak-flere-ansettelser']: ArbeidsgiverIkkeISakFlereAnsettelser, ['arbeidsaktivitet-uten-arbeidsgiver']: ArbeidsaktivitetUtenArbeidsgiver, ['ugyldig-k9-format']: UgyldigK9Format, + ['en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold']: EnArbeidsgiverToAnsettelserSammeUkeMedOpphold, + ['en-arbeidsgiver-to-ansettelser-samme-uke-uten-opphold']: EnArbeidsgiverToAnsettelserSammeUkeUtenOpphold, }; export interface ScenarioData { diff --git a/apps/endringsmelding-pleiepenger/playwright/tests/ikke-tilgang/ikke-tilgang-melding.spec.ts b/apps/endringsmelding-pleiepenger/playwright/tests/ikke-tilgang/ikke-tilgang-melding.spec.ts index b1f8184986..aa40d14f0d 100644 --- a/apps/endringsmelding-pleiepenger/playwright/tests/ikke-tilgang/ikke-tilgang-melding.spec.ts +++ b/apps/endringsmelding-pleiepenger/playwright/tests/ikke-tilgang/ikke-tilgang-melding.spec.ts @@ -35,3 +35,14 @@ test('Er selvstendig næringsdrivende', async ({ page }) => { await expect(page.getByText('Hei Nora')).toBeVisible(); await expect(page.getByTestId('erSN')).toBeVisible(); }); + +test('Har en arbeidsgiver med to ansettelsesforhold som slutter og starter samme uke med opphold', async ({ page }) => { + await routeUtils.resumeFromRoute( + page, + SøknadRoutes.VELKOMMEN, + 'en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold', + ); + await expect(page).toHaveTitle('Ingen tilgang - Endringsmelding for pleiepenger sykt barn'); + await expect(page.getByText('Hei Nora')).toBeVisible(); + await expect(page.getByTestId('enArbeidsgiverToAnsettelserSammeUkeMedOpphold')).toBeVisible(); +}); diff --git a/apps/endringsmelding-pleiepenger/playwright/tests/utfylling/ny-arbeidsgiver.spec.ts b/apps/endringsmelding-pleiepenger/playwright/tests/utfylling/ny-arbeidsgiver.spec.ts index 29bc6ee866..bb8ec6d8ad 100644 --- a/apps/endringsmelding-pleiepenger/playwright/tests/utfylling/ny-arbeidsgiver.spec.ts +++ b/apps/endringsmelding-pleiepenger/playwright/tests/utfylling/ny-arbeidsgiver.spec.ts @@ -41,7 +41,8 @@ test('test', async ({ page }) => { await page.getByTestId('timer-verdi').click(); await page.getByTestId('timer-verdi').fill('5'); await page.getByRole('button', { name: 'Ok' }).click(); - await page.getByLabel('Endre uke 5 (01.02.2023 - 05.').click(); + await page.getByLabel('Endre uke 6 (06.02').first().click(); + await page.getByTestId('toggle-timer').click(); await page.getByTestId('timer-verdi').click(); await page.getByTestId('timer-verdi').fill('5'); await page.getByRole('button', { name: 'Ok' }).click(); diff --git a/apps/endringsmelding-pleiepenger/src/app/api/__tests__/fetchInitialData.test.ts b/apps/endringsmelding-pleiepenger/src/app/api/__tests__/fetchInitialData.test.ts index 48fe09378d..839727ae45 100644 --- a/apps/endringsmelding-pleiepenger/src/app/api/__tests__/fetchInitialData.test.ts +++ b/apps/endringsmelding-pleiepenger/src/app/api/__tests__/fetchInitialData.test.ts @@ -1,26 +1,83 @@ -import { dateToISODate, ISODateRangeToDateRange } from '@navikt/sif-common-utils'; +import { dateToISODate, ISODateRangeToDateRange, ISODateToDate } from '@navikt/sif-common-utils'; -import { getPeriodeForArbeidsgiverOppslag } from '../../utils/initialDataUtils'; +import { ArbeidsgiverMedAnsettelseperioder } from '../../types'; +import { + getArbeidsgivereFromArbeidsgiverOrganisasjoner, + getPeriodeForArbeidsgiverOppslag, +} from '../../utils/initialDataUtils'; +import { AARegArbeidsgiverOrganisasjon } from '../endpoints/arbeidsgivereEndpoint'; -describe('getPeriodeForArbeidsgiverOppslag', () => { - const endringsperiode = ISODateRangeToDateRange('2022-05-01/2022-10-01'); +describe('initialDataUtils', () => { + describe('getPeriodeForArbeidsgiverOppslag', () => { + const endringsperiode = ISODateRangeToDateRange('2022-05-01/2022-10-01'); - it('returnerer minste dateRange ut fra maks endringsperiode og samletSøknadsperiode', () => { - const samletSøknadsperiode = ISODateRangeToDateRange('2022-06-01/2022-09-01'); - const result = getPeriodeForArbeidsgiverOppslag(samletSøknadsperiode, endringsperiode); - expect(result).toBeDefined(); - if (result) { - expect(dateToISODate(result.from)).toEqual('2022-06-01'); - expect(dateToISODate(result.to)).toEqual('2022-09-01'); - } + it('returnerer minste dateRange ut fra maks endringsperiode og samletSøknadsperiode', () => { + const samletSøknadsperiode = ISODateRangeToDateRange('2022-06-01/2022-09-01'); + const result = getPeriodeForArbeidsgiverOppslag(samletSøknadsperiode, endringsperiode); + expect(result).toBeDefined(); + if (result) { + expect(dateToISODate(result.from)).toEqual('2022-06-01'); + expect(dateToISODate(result.to)).toEqual('2022-09-01'); + } + }); + it('returnerer endringsperiode hvis samletSøknadsperiode går utover endringsperiode', () => { + const samletSøknadsperiode = ISODateRangeToDateRange('2021-01-01/2023-01-01'); + const result = getPeriodeForArbeidsgiverOppslag(samletSøknadsperiode, endringsperiode); + expect(result).toBeDefined(); + if (result) { + expect(dateToISODate(result.from)).toEqual('2022-05-01'); + expect(dateToISODate(result.to)).toEqual('2022-10-01'); + } + }); }); - it('returnerer endringsperiode hvis samletSøknadsperiode går utover endringsperiode', () => { - const samletSøknadsperiode = ISODateRangeToDateRange('2021-01-01/2023-01-01'); - const result = getPeriodeForArbeidsgiverOppslag(samletSøknadsperiode, endringsperiode); - expect(result).toBeDefined(); - if (result) { - expect(dateToISODate(result.from)).toEqual('2022-05-01'); - expect(dateToISODate(result.to)).toEqual('2022-10-01'); - } + + describe('getArbeidsgivereFromArbeidsgiverOrganisasjoner', () => { + it('oppretter ansettelsesperiode riktig når bruker har ett ansettelsesforhold hos én arbeidsgiver', () => { + const organisasjoner: AARegArbeidsgiverOrganisasjon[] = [ + { + navn: 'a', + organisasjonsnummer: '123', + ansattFom: '2022-01-01', + ansattTom: '2022-02-01', + }, + ]; + + const expectedResult: ArbeidsgiverMedAnsettelseperioder[] = [ + { + key: 'a_123', + navn: 'a', + organisasjonsnummer: '123', + ansettelsesperioder: [{ from: ISODateToDate('2022-01-01'), to: ISODateToDate('2022-02-01') }], + }, + ]; + expect(getArbeidsgivereFromArbeidsgiverOrganisasjoner(organisasjoner)).toEqual(expectedResult); + }); + it('oppretter ansettelsesperioder riktig når bruker har to ansettelsesforhold hos samme arbeidsgiver', () => { + const organisasjoner: AARegArbeidsgiverOrganisasjon[] = [ + { + navn: 'a', + organisasjonsnummer: '123', + ansattFom: '2022-01-01', + ansattTom: '2022-02-01', + }, + { + navn: 'a', + organisasjonsnummer: '123', + ansattFom: '2022-02-15', + }, + ]; + const expectedResult: ArbeidsgiverMedAnsettelseperioder[] = [ + { + key: 'a_123', + navn: 'a', + organisasjonsnummer: '123', + ansettelsesperioder: [ + { from: ISODateToDate('2022-01-01'), to: ISODateToDate('2022-02-01') }, + { from: ISODateToDate('2022-02-15') }, + ], + }, + ]; + expect(getArbeidsgivereFromArbeidsgiverOrganisasjoner(organisasjoner)).toEqual(expectedResult); + }); }); }); diff --git a/apps/endringsmelding-pleiepenger/src/app/api/endpoints/arbeidsgivereEndpoint.ts b/apps/endringsmelding-pleiepenger/src/app/api/endpoints/arbeidsgivereEndpoint.ts index 547676323c..e13bdb5972 100644 --- a/apps/endringsmelding-pleiepenger/src/app/api/endpoints/arbeidsgivereEndpoint.ts +++ b/apps/endringsmelding-pleiepenger/src/app/api/endpoints/arbeidsgivereEndpoint.ts @@ -1,38 +1,30 @@ -import { DateRange, dateToISODate, ISODate, ISODateToDate } from '@navikt/sif-common-utils'; -import { Arbeidsgiver } from '@types'; +import { DateRange, dateToISODate, ISODate } from '@navikt/sif-common-utils'; +import { ArbeidsgiverMedAnsettelseperioder } from '@types'; -import { getArbeidsgiverKey } from '../../utils/arbeidsgiverUtils'; +import { getArbeidsgivereFromArbeidsgiverOrganisasjoner } from '../../utils/initialDataUtils'; import api from '../api'; import { ApiEndpointPsb } from './'; -type AAregArbeidsgiver = { - organisasjoner?: Array<{ - organisasjonsnummer: string; - navn: string; - ansattFom?: ISODate; - ansattTom?: ISODate; - }>; +export type AAregArbeidsgiver = { + organisasjoner?: AARegArbeidsgiverOrganisasjon[]; +}; + +export type AARegArbeidsgiverOrganisasjon = { + organisasjonsnummer: string; + navn: string; + ansattFom?: ISODate; + ansattTom?: ISODate; }; export const arbeidsgivereEndpoint = { - fetch: async (periode: DateRange): Promise => { + fetch: async (periode: DateRange): Promise => { try { const { from, to } = periode; const { data } = await api.psb.get( ApiEndpointPsb.arbeidsgiver, - `ytelse=endringsmelding-pleiepenger&fra_og_med=${dateToISODate(from)}&til_og_med=${dateToISODate(to)}`, + `ytelse=endringsmelding-pleiepenger&fra_og_med=${dateToISODate(from)}&til_og_med=${dateToISODate(to)}&inkluderAlleAnsettelsesperioder=true`, ); - const aaArbeidsgivere: Arbeidsgiver[] = []; - (data.organisasjoner || []).forEach((a) => { - aaArbeidsgivere.push({ - key: getArbeidsgiverKey(a.organisasjonsnummer), - organisasjonsnummer: a.organisasjonsnummer, - navn: a.navn, - ansattFom: a.ansattFom ? ISODateToDate(a.ansattFom) : undefined, - ansattTom: a.ansattTom ? ISODateToDate(a.ansattTom) : undefined, - }); - }); - return Promise.resolve(aaArbeidsgivere); + return Promise.resolve(getArbeidsgivereFromArbeidsgiverOrganisasjoner(data.organisasjoner || [])); } catch (error) { return Promise.reject(error); } diff --git a/apps/endringsmelding-pleiepenger/src/app/api/fetchInitialData.ts b/apps/endringsmelding-pleiepenger/src/app/api/fetchInitialData.ts index 99af8e3d71..54f5cd7066 100644 --- a/apps/endringsmelding-pleiepenger/src/app/api/fetchInitialData.ts +++ b/apps/endringsmelding-pleiepenger/src/app/api/fetchInitialData.ts @@ -3,7 +3,7 @@ import { isForbidden, isUnauthorized } from '@navikt/sif-common-core-ds/src/util import { getMaybeEnv } from '@navikt/sif-common-env'; import { DateRange, dateRangeUtils } from '@navikt/sif-common-utils'; import { - Arbeidsgiver, + ArbeidsgiverMedAnsettelseperioder, IngenTilgangÅrsak, isK9Sak, isUgyldigK9SakFormat, @@ -32,7 +32,7 @@ export const fetchInitialData = async ( søker: Søker; k9saker: K9Sak[]; antallSakerFørEndringsperiode: number; - arbeidsgivere: Arbeidsgiver[]; + arbeidsgivere: ArbeidsgiverMedAnsettelseperioder[]; lagretSøknadState?: SøknadStatePersistence; }> => { const [søker, k9sakerResult] = await Promise.all([fetchSøker(), sakerEndpoint.fetch()]); @@ -53,7 +53,7 @@ export const fetchInitialData = async ( try { let k9saker: K9Sak[]; - let arbeidsgivere: Arbeidsgiver[]; + let arbeidsgivere: ArbeidsgiverMedAnsettelseperioder[]; const sakerInnenforEndringsperiode = k9sakerResult.k9Saker; const sakerFørEndringsperiode = k9sakerResult.eldreSaker; @@ -76,7 +76,7 @@ export const fetchInitialData = async ( }) .then((result) => { arbeidsgivere = result; - return kontrollerTilgang(k9saker, tillattEndringsperiode); + return kontrollerTilgang(k9saker, tillattEndringsperiode, arbeidsgivere); }) .then(() => hentOgKontrollerLagretSøknadState(søker, k9saker)) .then((lagretSøknadState) => { @@ -152,8 +152,13 @@ const kontrollerSaker = ( return Promise.resolve({ k9saker, dateRangeAlleSaker }); }; -const kontrollerTilgang = async (k9saker: K9Sak[], tillattEndringsperiode: DateRange): Promise => { - const resultat = tilgangskontroll(k9saker, tillattEndringsperiode); +const kontrollerTilgang = async ( + k9saker: K9Sak[], + tillattEndringsperiode: DateRange, + arbeidsgivere: ArbeidsgiverMedAnsettelseperioder[], +): Promise => { + const resultat = tilgangskontroll(k9saker, tillattEndringsperiode, arbeidsgivere); + if (resultat.kanBrukeSøknad) { return Promise.resolve(true); } diff --git a/apps/endringsmelding-pleiepenger/src/app/components/arbeidsaktivitet-block/AnsettelsesperioderInfo.tsx b/apps/endringsmelding-pleiepenger/src/app/components/arbeidsaktivitet-block/AnsettelsesperioderInfo.tsx new file mode 100644 index 0000000000..2b93bb2288 --- /dev/null +++ b/apps/endringsmelding-pleiepenger/src/app/components/arbeidsaktivitet-block/AnsettelsesperioderInfo.tsx @@ -0,0 +1,65 @@ +import { dateFormatter, MaybeDateRange, sortMaybeDateRange } from '@navikt/sif-common-utils'; +import { AppText, useAppIntl } from '../../i18n'; +import { Box, List } from '@navikt/ds-react'; +import ExpandableInfo from '@navikt/sif-common-core-ds/src/components/expandable-info/ExpandableInfo'; + +interface Props { + ansettelsesperioder: MaybeDateRange[]; +} + +const Ansettelsesperiode = ({ periode }: { periode: MaybeDateRange }) => { + if (periode.from === undefined && periode.to === undefined) { + return null; + } + if (periode.from && periode.to) { + return ( + + ); + } + if (periode.from) { + return ( + + ); + } + if (periode.to) { + return ( + + ); + } + return null; +}; + +const AnsettelsesperioderInfo = ({ ansettelsesperioder }: Props) => { + const { text } = useAppIntl(); + return ansettelsesperioder.length === 1 ? ( + + ) : ( + + + + {ansettelsesperioder + .sort(sortMaybeDateRange) + .reverse() + .map((periode, index) => { + return ( + + + + ); + })} + + + + ); +}; + +export default AnsettelsesperioderInfo; diff --git a/apps/endringsmelding-pleiepenger/src/app/components/arbeidsaktivitet-block/ArbeidsaktivitetBlock.tsx b/apps/endringsmelding-pleiepenger/src/app/components/arbeidsaktivitet-block/ArbeidsaktivitetBlock.tsx index 6a0ac105b1..019c005e5e 100644 --- a/apps/endringsmelding-pleiepenger/src/app/components/arbeidsaktivitet-block/ArbeidsaktivitetBlock.tsx +++ b/apps/endringsmelding-pleiepenger/src/app/components/arbeidsaktivitet-block/ArbeidsaktivitetBlock.tsx @@ -1,12 +1,12 @@ import { BoxNew, ExpansionCard, VStack } from '@navikt/ds-react'; -import { ArbeidsaktivitetType, Arbeidsgiver } from '@types'; +import { ArbeidsaktivitetType, ArbeidsgiverMedAnsettelseperioder } from '@types'; import ArbeidsaktivitetBlockHeader from './ArbeidsaktivitetBlockHeader'; interface Props { navn: string; type: ArbeidsaktivitetType; - arbeidsgiver?: Arbeidsgiver; + arbeidsgiver?: ArbeidsgiverMedAnsettelseperioder; endret?: { tekst: string }; erUkjent?: boolean; renderAsExpansionCard?: boolean; diff --git a/apps/endringsmelding-pleiepenger/src/app/components/arbeidsaktivitet-block/ArbeidsaktivitetBlockHeader.tsx b/apps/endringsmelding-pleiepenger/src/app/components/arbeidsaktivitet-block/ArbeidsaktivitetBlockHeader.tsx index f889eba91d..84a651e7d7 100644 --- a/apps/endringsmelding-pleiepenger/src/app/components/arbeidsaktivitet-block/ArbeidsaktivitetBlockHeader.tsx +++ b/apps/endringsmelding-pleiepenger/src/app/components/arbeidsaktivitet-block/ArbeidsaktivitetBlockHeader.tsx @@ -2,17 +2,17 @@ import './arbeidsaktivitetBlockHeader.scss'; import { Office1 } from '@navikt/ds-icons'; import { BodyLong, Box, Heading, VStack } from '@navikt/ds-react'; -import { dateFormatter } from '@navikt/sif-common-utils'; -import { ArbeidsaktivitetType, Arbeidsgiver } from '@types'; +import { ArbeidsaktivitetType, ArbeidsgiverMedAnsettelseperioder } from '@types'; import { AppText } from '../../i18n'; import EndretTag from '../tags/EndretTag'; import NyTag from '../tags/NyTag'; import TagsContainer from '../tags/tags-container/TagsContainer'; +import AnsettelsesperioderInfo from './AnsettelsesperioderInfo'; interface Props { navn: string; - arbeidsgiver?: Arbeidsgiver; + arbeidsgiver?: ArbeidsgiverMedAnsettelseperioder; type: ArbeidsaktivitetType; erUkjentAktivitet?: boolean; endret?: { @@ -34,24 +34,13 @@ const ArbeidsaktivitetBlockHeader = ({ type, arbeidsgiver, navn, endret, erUkjen {type === ArbeidsaktivitetType.arbeidstaker && arbeidsgiver !== undefined ? ( -
+ -
- {arbeidsgiver.ansattFom && ( - - )} - {arbeidsgiver.ansattTom && ( - - )} + +
) : undefined} {(endret || erUkjentAktivitet) && ( diff --git a/apps/endringsmelding-pleiepenger/src/app/components/tags/KortUkeTag.tsx b/apps/endringsmelding-pleiepenger/src/app/components/tags/KortUkeTag.tsx index 0abd638bfd..183f6aacbb 100644 --- a/apps/endringsmelding-pleiepenger/src/app/components/tags/KortUkeTag.tsx +++ b/apps/endringsmelding-pleiepenger/src/app/components/tags/KortUkeTag.tsx @@ -1,19 +1,28 @@ -import { Tag, TagProps } from '@navikt/ds-react'; +import { Tag, TagProps, Tooltip } from '@navikt/ds-react'; import React from 'react'; import { useAppIntl } from '../../i18n'; interface Props extends Omit { children?: React.ReactNode; + tooltip?: string; } -const KortUkeTag = ({ children, ...rest }: Props) => { +const KortUkeTag = ({ children, tooltip, ...rest }: Props) => { const { text } = useAppIntl(); - return ( + + const tag = ( {children || text('tags.kortUke')} ); + return tooltip ? ( + <> + {tag} + + ) : ( + tag + ); }; export default KortUkeTag; diff --git a/apps/endringsmelding-pleiepenger/src/app/dev/scenarioer.ts b/apps/endringsmelding-pleiepenger/src/app/dev/scenarioer.ts index 4fc96bd1c9..6212ec3757 100644 --- a/apps/endringsmelding-pleiepenger/src/app/dev/scenarioer.ts +++ b/apps/endringsmelding-pleiepenger/src/app/dev/scenarioer.ts @@ -4,13 +4,15 @@ export type ScenarioType = | 'arbeidsgiver-og-frilanser' | 'arbeidsgivere-og-frilanser' | 'arbeidsgiver-ikke-i-sak' - | 'flere-saker-kun-en-aktiv' + | 'arbeidsgiver-ikke-i-sak-flere-ansettelser' | 'debug' | 'selvstendig-næringsdrivende' | 'flere-saker' | 'ingen-sak' | 'arbeidsaktivitet-uten-arbeidsgiver' - | 'ugyldig-k9-format'; + | 'ugyldig-k9-format' + | 'en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold' + | 'en-arbeidsgiver-to-ansettelser-samme-uke-uten-opphold'; export interface Scenario { name: string; @@ -46,9 +48,9 @@ export const scenarioer: Scenario[] = [ harTilgang: true, }, { - name: 'Flere saker, kun én aktiv', - value: 'flere-saker-kun-en-aktiv', - harTilgang: true, + name: 'Arbeidsgiver som ikke er i sak med flere ansettelser', + value: 'arbeidsgiver-ikke-i-sak-flere-ansettelser', + harTilgang: false, }, { name: 'Selvstendig næringsdrivende', @@ -80,6 +82,16 @@ export const scenarioer: Scenario[] = [ value: 'ugyldig-k9-format', harTilgang: false, }, + { + name: 'Arbeidsgiver med to ansettelser samme uke med opphold', + value: 'en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold', + harTilgang: false, + }, + { + name: 'Arbeidsgiver med to ansettelser samme uke uten opphold', + value: 'en-arbeidsgiver-to-ansettelser-samme-uke-uten-opphold', + harTilgang: true, + }, ]; export const defaultScenario = scenarioer[0]; diff --git "a/apps/endringsmelding-pleiepenger/src/app/hooks/useS\303\270knadInitialData.ts" "b/apps/endringsmelding-pleiepenger/src/app/hooks/useS\303\270knadInitialData.ts" index 5761c19647..e9c704f9e8 100644 --- "a/apps/endringsmelding-pleiepenger/src/app/hooks/useS\303\270knadInitialData.ts" +++ "b/apps/endringsmelding-pleiepenger/src/app/hooks/useS\303\270knadInitialData.ts" @@ -3,7 +3,7 @@ import { getMaybeEnv } from '@navikt/sif-common-env'; import { useEffectOnce } from '@navikt/sif-common-hooks'; import { DateRange } from '@navikt/sif-common-utils'; import { - Arbeidsgiver, + ArbeidsgiverMedAnsettelseperioder, IngenTilgangÅrsak, K9Sak, RequestStatus, @@ -48,7 +48,7 @@ const prepInitialData = ( søker: Søker; k9saker: K9Sak[]; antallSakerFørEndringsperiode: number; - arbeidsgivere: Arbeidsgiver[]; + arbeidsgivere: ArbeidsgiverMedAnsettelseperioder[]; lagretSøknadState?: SøknadStatePersistence; }, tillattEndringsperiode: DateRange, diff --git "a/apps/endringsmelding-pleiepenger/src/app/hooks/useS\303\270knadsdataStatus.ts" "b/apps/endringsmelding-pleiepenger/src/app/hooks/useS\303\270knadsdataStatus.ts" index 70e1efb178..89384a4550 100644 --- "a/apps/endringsmelding-pleiepenger/src/app/hooks/useS\303\270knadsdataStatus.ts" +++ "b/apps/endringsmelding-pleiepenger/src/app/hooks/useS\303\270knadsdataStatus.ts" @@ -1,7 +1,7 @@ import { useSøknadContext } from '@hooks'; import { useEffectOnce } from '@navikt/sif-common-hooks'; import { SoknadStepsConfig } from '@navikt/sif-common-soknad-ds'; -import { Arbeidsgiver, Søknadsdata } from '@types'; +import { ArbeidsgiverMedAnsettelseperioder, Søknadsdata } from '@types'; import { useState } from 'react'; import isEqual from 'react-fast-compare'; @@ -19,7 +19,7 @@ const getPrecedingSteps = (currentStepIndex: number, stepConfig: SoknadStepsConf const getStepSøknadsdataFromStepFormValues = ( step: StepId, stepFormValues: StepFormValues, - arbeidsgivere: Arbeidsgiver[], + arbeidsgivere: ArbeidsgiverMedAnsettelseperioder[], ) => { const formValues = stepFormValues[step]; if (!formValues) { @@ -40,7 +40,7 @@ const isStepFormValuesAndStepSøknadsdataValid = ( step: StepId, stepFormValues: StepFormValues, søknadsdata: Søknadsdata, - arbeidsgivere: Arbeidsgiver[], + arbeidsgivere: ArbeidsgiverMedAnsettelseperioder[], ): boolean => { if (stepFormValues[step]) { const stepSøknadsdata = søknadsdata[step]; @@ -55,7 +55,7 @@ const isStepFormValuesAndStepSøknadsdataValid = ( export const useSøknadsdataStatus = ( stepId: StepId, stepConfig: SoknadStepsConfig, - arbeidsgivere: Arbeidsgiver[], + arbeidsgivere: ArbeidsgiverMedAnsettelseperioder[], ) => { const [invalidSteps, setInvalidSteps] = useState([]); diff --git a/apps/endringsmelding-pleiepenger/src/app/i18n/appMessages.ts b/apps/endringsmelding-pleiepenger/src/app/i18n/appMessages.ts index e7a47ba7f0..c5c218ab1c 100644 --- a/apps/endringsmelding-pleiepenger/src/app/i18n/appMessages.ts +++ b/apps/endringsmelding-pleiepenger/src/app/i18n/appMessages.ts @@ -32,7 +32,9 @@ const nb = { 'arbeidsaktivitetBlockHeader.nyttArbeidsforhold': 'Nytt arbeidsforhold', 'arbeidsaktivitetBlockHeader.arbeidsgiver.orgnummer': 'Organisasjonsnummer: {orgnr}', - 'arbeidsaktivitetBlockHeader.arbeidsgiver.ansattFom': 'Ansatt: {dato}.', + 'arbeidsaktivitetBlockHeader.arbeidsgiver.ansettelsesperioder': 'Ansettelsesperioder', + 'arbeidsaktivitetBlockHeader.arbeidsgiver.ansattFomTom': 'Ansatt: {fom} - {tom}.', + 'arbeidsaktivitetBlockHeader.arbeidsgiver.ansattFom': 'Ansatt: {dato} - pågående', 'arbeidsaktivitetBlockHeader.arbeidsgiver.ansattTom': ' Sluttdato: {dato}.', 'ikkeAnsattMelding.tekst': @@ -90,6 +92,11 @@ const nb = { 'Hvis du har søkt om pleiepenger for en periode frem i tid, eller for barn som ikke er folkeregistrert på deg, kan det ta tid før du kan bruke endringsmeldingen. Du kan foreløpig melde endringer i pleiepengesaken din via {SendBeskjedLink}.', 'ingenTilgangPage.harIngenSak.3': 'Hvis du ønsker at en av våre veiledere skal undersøke hvorfor du ikke kan bruke endringsmeldingen, kan du kontakte oss på telefon 55 55 33 33.', + 'ingenTilgangPage.harFlereAnsettelsesforholdHosUkjentArbeidsgiver.1': + 'Du kan ikke bruke denne tjenesten. Dette er fordi vi har funnet arbeidsforhold på deg som ikke er registrert i pleiepengesaken din, og hvor du har flere ansettelsesforhold. Du må derfor sende en ny søknad, slik at saken og utbetalingene dine blir riktige.', + + 'ingenTilgangPage.harFlereAnsettelsesforholdHosUkjentArbeidsgiver.2': + 'Hvis du mener at dette ikke stemmer, er det fint at du sender en melding til oss {SkrivTilOssLink}.', 'ingenTilgangPage.harArbeidstidSomSelvstendigNæringsdrivende.1': 'Du kan ikke bruke denne tjenesten per i dag. Dette er fordi tjenesten foreløpig ikke kan ta imot endringer fra selvstendig næringsdrivende. Vi jobber for å få det til, og selvstendig næringsdrivende blir også tilbudt denne tjenesten på et senere tidspunkt.', 'ingenTilgangPage.harMerEnnEnSak.1': @@ -98,6 +105,8 @@ const nb = { 'Du kan ikke bruke denne tjenesten fordi siste søknadsperiode gikk ut for mer enn enn {ANTALL_MÅNEDER_TILLATT_FOR_ENDRING} måneder siden. Du kan melde fra om endring i tjenesten {SendBeskjedLink}, eller sende oss en ny søknad.', 'ingenTilgangPage.utenforEndringsperiode.2': 'Hvis du mener at dette ikke stemmer, er det fint at du sender en melding til oss {SkrivTilOssLink}.', + 'ingenTilgangPage.slutterOgStarterInneforSammeUke': + 'Vi ser at du har to ansettelsesforhold hos samme arbeidsgiver som slutter og starter samme uke. Da kan du desverre ikke bruke denne løsningen for å melde fra om endringer.', 'kvitteringPage.pageTitle': 'Endringsmelding er mottatt', 'kvitteringPage.title': 'Melding om endring er lagt til saken din', diff --git a/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/ArbeidstidUker.tsx b/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/ArbeidstidUker.tsx index b943484d3b..9e43e055fe 100644 --- a/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/ArbeidstidUker.tsx +++ b/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/ArbeidstidUker.tsx @@ -36,7 +36,6 @@ const ArbeidstidUker = ({ arbeidstidKolonneTittel, triggerResetValgCounter, visEndringSomOpprinnelig, - onEndreUker, }: Props) => { const { text, intl } = useAppIntl(); diff --git a/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/arbeidstidUker.scss b/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/arbeidstidUker.scss index 06372648e8..9512a5dd9a 100644 --- a/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/arbeidstidUker.scss +++ b/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/arbeidstidUker.scss @@ -21,7 +21,6 @@ } &__info { font-size: 1.4rem; - white-space: nowrap; svg { margin: 0 0.25rem; } diff --git a/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/components/ArbeidstidUkeInfo.tsx b/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/components/ArbeidstidUkeInfo.tsx index ad794f492c..f5c4d0a403 100644 --- a/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/components/ArbeidstidUkeInfo.tsx +++ b/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/components/ArbeidstidUkeInfo.tsx @@ -33,7 +33,11 @@ const ArbeidstidUkeInfo = ({ uke, medLabels = false, visEndringSomOpprinnelig }: const { endretProsent } = uke.endret; return ( <> - {medLabels && Arbeidstimer:} + {medLabels && ( + + Arbeidstimer: + + )} diff --git a/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/components/ArbeidstidUkeListe.tsx b/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/components/ArbeidstidUkeListe.tsx index 3f561085fb..f0a2cda249 100644 --- a/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/components/ArbeidstidUkeListe.tsx +++ b/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/components/ArbeidstidUkeListe.tsx @@ -1,12 +1,14 @@ -import { BodyShort, Heading, VStack } from '@navikt/ds-react'; -import { dateFormatter } from '@navikt/sif-common-utils'; +import { BodyShort, Box, Heading, HStack, VStack } from '@navikt/ds-react'; +import { getDateRangeText } from '@navikt/sif-common-utils'; import dayjs from 'dayjs'; -import { ReactElement } from 'react'; +import React, { ReactElement } from 'react'; +import { useIntl } from 'react-intl'; import { SelectableListType } from '../../../hooks/useSelectableList'; import { AppText } from '../../../i18n'; import { ArbeidstidUkerItem } from '../types/ArbeidstidUkerItem'; import ArbeidstidUkeInfoListe from './ArbeidstidUkeInfoListe'; +import { getKortUkeTooltipText } from './UkeInfoTooltip'; import UkeTags from './UkeTags'; import VelgArbeidsukeItem from './VelgArbeidsukeItem'; @@ -17,7 +19,13 @@ interface Props { renderEditButton: (uke: ArbeidstidUkerItem, ukenummer: number, renderLabel: boolean) => ReactElement | undefined; } -const ArbeidstidUkeListe = ({ uker, visEndringSomOpprinnelig, selectableList, renderEditButton }: Props) => { +const ArbeidstidUkeListe: React.FunctionComponent = ({ + uker, + visEndringSomOpprinnelig, + selectableList, + renderEditButton, +}) => { + const intl = useIntl(); const { isItemSelected, setItemSelected, @@ -46,14 +54,19 @@ const ArbeidstidUkeListe = ({ uker, visEndringSomOpprinnelig, selectableList, re + - {dateFormatter.compact(uke.periode.from)} - {` `} - {dateFormatter.compact(uke.periode.to)} - + + {getDateRangeText(uke.periode, intl.locale)} + + + +
-
- {dateFormatter.compact(uke.periode.from)} - {` `} - {dateFormatter.compact(uke.periode.to)} -
+
{getDateRangeText(uke.periode, intl.locale)}
@@ -137,6 +134,7 @@ const ArbeidstidUkeTabell = ({ {(uke.harFeriedager || uke.harFjernetFeriedager || uke.erKortUke) && ( - {uke.erKortUke && } + {uke.erKortUke && }
diff --git a/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/components/KortUkeInfo.tsx b/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/components/KortUkeInfo.tsx new file mode 100644 index 0000000000..45da893352 --- /dev/null +++ b/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/components/KortUkeInfo.tsx @@ -0,0 +1,16 @@ +import { Box } from '@navikt/ds-react'; +import { getDagerTekst } from '../../../utils'; +import { Arbeidsuke } from '../../../types'; +import { AppText } from '../../../i18n'; + +interface Props { + arbeidsuke: Arbeidsuke; +} + +const KortUkeInfo = ({ arbeidsuke }: Props) => ( + + + +); + +export default KortUkeInfo; diff --git a/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/components/UkeInfo.tsx b/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/components/UkeInfo.tsx deleted file mode 100644 index 7a9d3774ec..0000000000 --- a/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/components/UkeInfo.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { InformationColored } from '@navikt/ds-icons'; -import { dateFormatter, DateRange } from '@navikt/sif-common-utils'; - -import { ArbeidstidUkerItem } from '../types/ArbeidstidUkerItem'; - -interface Props { - uke: ArbeidstidUkerItem; -} - -const UkeInfoIkon = ({ uke }: Props) => { - return ( - - - - ); -}; - -const getDagerPeriode = ({ from, to }: DateRange, visDato = true): string => { - const fra = visDato ? dateFormatter.dayDateMonthYear(from) : dateFormatter.day(from); - const til = visDato ? dateFormatter.dayDateMonthYear(to) : dateFormatter.day(to); - if (fra === til) { - return fra; - } - return `${fra} til ${til}`; -}; - -export default UkeInfoIkon; diff --git a/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/components/UkeInfoTooltip.tsx b/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/components/UkeInfoTooltip.tsx new file mode 100644 index 0000000000..8eaf091245 --- /dev/null +++ b/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/components/UkeInfoTooltip.tsx @@ -0,0 +1,35 @@ +import { InformationColored } from '@navikt/ds-icons'; +import { Tooltip } from '@navikt/ds-react'; +import { dateFormatter, DateRange } from '@navikt/sif-common-utils'; + +import { ArbeidstidUkerItem } from '../types/ArbeidstidUkerItem'; + +interface Props { + uke: ArbeidstidUkerItem; +} + +export const getKortUkeTooltipText = (periode: DateRange): string => `Kort uke - ${getDagerPeriode(periode, false)}`; + +const UkeInfoTooltip: React.FunctionComponent = ({ uke }) => { + const { erKortUke } = uke; + if (erKortUke) { + return ( + + + + + + ); + } +}; + +const getDagerPeriode = ({ from, to }: DateRange, visDato = true): string => { + const fra = visDato ? dateFormatter.dayDateMonthYear(from) : dateFormatter.day(from); + const til = visDato ? dateFormatter.dayDateMonthYear(to) : dateFormatter.day(to); + if (fra === til) { + return fra; + } + return `${fra} til ${til}`; +}; + +export default UkeInfoTooltip; diff --git a/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/components/UkeTags.tsx b/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/components/UkeTags.tsx index b75a10e0b3..1635244f1a 100644 --- a/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/components/UkeTags.tsx +++ b/apps/endringsmelding-pleiepenger/src/app/modules/arbeidstid-uker/components/UkeTags.tsx @@ -6,16 +6,17 @@ import KortUkeTag from '../../../components/tags/KortUkeTag'; import TagsContainer from '../../../components/tags/tags-container/TagsContainer'; interface Props { + kortUkeTooltip?: string; erKortUke?: boolean; dagerMedFerie: Date[] | undefined; dagerMedFjernetFerie?: Date[] | undefined; visDagNavn?: boolean; } -const UkeTags = ({ dagerMedFerie = [], dagerMedFjernetFerie = [], visDagNavn, erKortUke }: Props) => { +const UkeTags = ({ dagerMedFerie = [], dagerMedFjernetFerie = [], visDagNavn, erKortUke, kortUkeTooltip }: Props) => { const tags: React.ReactNode[] = []; if (erKortUke) { - tags.push(); + tags.push(); } if (dagerMedFerie?.length > 0) { tags.push( @@ -40,7 +41,7 @@ const UkeTags = ({ dagerMedFerie = [], dagerMedFjernetFerie = [], visDagNavn, er return ( <> - {erKortUke && } + {erKortUke && } {dagerMedFerie?.length > 0 && ( {visDagNavn diff --git a/apps/endringsmelding-pleiepenger/src/app/pages/ingen-tilgang/IngenTilgangPage.stories.tsx b/apps/endringsmelding-pleiepenger/src/app/pages/ingen-tilgang/IngenTilgangPage.stories.tsx index 0954b4ae4a..fb5c0fb3de 100644 --- a/apps/endringsmelding-pleiepenger/src/app/pages/ingen-tilgang/IngenTilgangPage.stories.tsx +++ b/apps/endringsmelding-pleiepenger/src/app/pages/ingen-tilgang/IngenTilgangPage.stories.tsx @@ -21,6 +21,14 @@ export default meta; type Story = StoryObj; +export const Default: Story = { + name: 'harFlereAnsettelsesforholdHosUkjentArbeidsgiver', + args: { + søker, + årsak: [IngenTilgangÅrsak.harFlereAnsettelsesforholdHosUkjentArbeidsgiver], + }, +}; + export const ArbeidstidSomSelvstendigNæringsdrivende: Story = { name: 'harArbeidstidSomSelvstendigNæringsdrivende', args: { @@ -45,6 +53,14 @@ export const IngenSak: Story = { }, }; +export const EnArbeidsgiverToAnsettelserSammeUkeMedOpphold: Story = { + name: 'enArbeidsgiverToAnsettelserSammeUkeMedOpphold', + args: { + søker, + årsak: [IngenTilgangÅrsak.enArbeidsgiverToAnsettelserSammeUkeMedOpphold], + }, +}; + export const MerEnnEnSak: Story = { name: 'harMerEnnEnSak', args: { diff --git a/apps/endringsmelding-pleiepenger/src/app/pages/ingen-tilgang/IngenTilgangPage.tsx b/apps/endringsmelding-pleiepenger/src/app/pages/ingen-tilgang/IngenTilgangPage.tsx index 079d51ce24..02e947338e 100644 --- a/apps/endringsmelding-pleiepenger/src/app/pages/ingen-tilgang/IngenTilgangPage.tsx +++ b/apps/endringsmelding-pleiepenger/src/app/pages/ingen-tilgang/IngenTilgangPage.tsx @@ -58,6 +58,20 @@ const getÅrsakMelding = (årsak: IngenTilgangÅrsak) => {

); + case IngenTilgangÅrsak.harFlereAnsettelsesforholdHosUkjentArbeidsgiver: + return ( + +

+ +

+

+ }} + /> +

+
+ ); case IngenTilgangÅrsak.harArbeidstidSomSelvstendigNæringsdrivende: return ( @@ -76,6 +90,15 @@ const getÅrsakMelding = (årsak: IngenTilgangÅrsak) => {

{beskjedTilOssGenerell}

); + case IngenTilgangÅrsak.enArbeidsgiverToAnsettelserSammeUkeMedOpphold: + return ( + +

+ +

+

{beskjedTilOssGenerell}

+
+ ); case IngenTilgangÅrsak.søknadsperioderUtenforTillattEndringsperiode: return ( @@ -91,7 +114,7 @@ const getÅrsakMelding = (årsak: IngenTilgangÅrsak) => {

}} + values={{ SkrivTilOssLink: }} />

diff --git a/apps/endringsmelding-pleiepenger/src/app/pages/kvittering/KvitteringPage.tsx b/apps/endringsmelding-pleiepenger/src/app/pages/kvittering/KvitteringPage.tsx index e613cc40a4..b0d87cfb0c 100644 --- a/apps/endringsmelding-pleiepenger/src/app/pages/kvittering/KvitteringPage.tsx +++ b/apps/endringsmelding-pleiepenger/src/app/pages/kvittering/KvitteringPage.tsx @@ -24,7 +24,11 @@ const KvitteringPage = ({ onUnmount }: Props) => { {children}, + Lenke: (children) => ( + + {children} + + ), }} /> diff --git a/apps/endringsmelding-pleiepenger/src/app/pages/velkommen/BehandlingAvPersonopplysningerContent.tsx b/apps/endringsmelding-pleiepenger/src/app/pages/velkommen/BehandlingAvPersonopplysningerContent.tsx index 70e99898c9..e60445a788 100644 --- a/apps/endringsmelding-pleiepenger/src/app/pages/velkommen/BehandlingAvPersonopplysningerContent.tsx +++ b/apps/endringsmelding-pleiepenger/src/app/pages/velkommen/BehandlingAvPersonopplysningerContent.tsx @@ -49,7 +49,7 @@ const BehandlingAvPersonopplysningerContent: React.FunctionComponent = () => { id="personopplysninger.5" values={{ Link: (children) => ( - + {children} ), diff --git a/apps/endringsmelding-pleiepenger/src/app/pages/velkommen/VelkommenPage.tsx b/apps/endringsmelding-pleiepenger/src/app/pages/velkommen/VelkommenPage.tsx index ad446c4076..c527dd79a2 100644 --- a/apps/endringsmelding-pleiepenger/src/app/pages/velkommen/VelkommenPage.tsx +++ b/apps/endringsmelding-pleiepenger/src/app/pages/velkommen/VelkommenPage.tsx @@ -56,6 +56,7 @@ const VelkommenPage = () => { }} /> + { }, ]} /> -
diff --git "a/apps/endringsmelding-pleiepenger/src/app/s\303\270knad/steps/arbeidstid/ArbeidstidForm.tsx" "b/apps/endringsmelding-pleiepenger/src/app/s\303\270knad/steps/arbeidstid/ArbeidstidForm.tsx" index 36f6c83612..3464e52e2e 100644 --- "a/apps/endringsmelding-pleiepenger/src/app/s\303\270knad/steps/arbeidstid/ArbeidstidForm.tsx" +++ "b/apps/endringsmelding-pleiepenger/src/app/s\303\270knad/steps/arbeidstid/ArbeidstidForm.tsx" @@ -7,7 +7,7 @@ import { YesOrNo, } from '@navikt/sif-common-formik-ds'; import { ArbeiderIPeriodenSvar, ArbeidsaktivitetType, ArbeidstidEndringMap, SøknadContextState } from '@types'; -import { getArbeidsaktiviteterForUkjenteArbeidsforhold } from '@utils'; +import { getArbeidsaktiviteterForUkjenteArbeidsforhold, getEndringsdato, getTillattEndringsperiode } from '@utils'; import { useIntl } from 'react-intl'; import { AppText } from '../../../i18n'; @@ -113,6 +113,7 @@ const ArbeidstidForm = ({ goBack }: Props) => { sak.søknadsperioder, sak.arbeidsgivereIkkeISak, aktiviteterValuesMap, + getTillattEndringsperiode(getEndringsdato()), søknadsdata.ukjentArbeidsforhold, ), ...getAktiviteterSomSkalEndres(sak.arbeidsaktiviteter), diff --git "a/apps/endringsmelding-pleiepenger/src/app/s\303\270knad/steps/arbeidstid/arbeidsaktivitet-form-part/components/ArbeidsaktivitetUtenforPeriodeInfo.tsx" "b/apps/endringsmelding-pleiepenger/src/app/s\303\270knad/steps/arbeidstid/arbeidsaktivitet-form-part/components/ArbeidsaktivitetUtenforPeriodeInfo.tsx" index f596a237ec..bbd4fafb14 100644 --- "a/apps/endringsmelding-pleiepenger/src/app/s\303\270knad/steps/arbeidstid/arbeidsaktivitet-form-part/components/ArbeidsaktivitetUtenforPeriodeInfo.tsx" +++ "b/apps/endringsmelding-pleiepenger/src/app/s\303\270knad/steps/arbeidstid/arbeidsaktivitet-form-part/components/ArbeidsaktivitetUtenforPeriodeInfo.tsx" @@ -20,7 +20,7 @@ const ArbeidsaktivitetUtenforPeriodeInfo = ({ const intlValues = { førDato: dateFormatter.full(tillattEndringsperiode.from), etterDato: dateFormatter.full(tillattEndringsperiode.to), - skrivTilOssLink: , + skrivTilOssLink: , }; return ( diff --git "a/apps/endringsmelding-pleiepenger/src/app/s\303\270knad/steps/oppsummering/ArbeidstidArbeidstakerOppsummering.tsx" "b/apps/endringsmelding-pleiepenger/src/app/s\303\270knad/steps/oppsummering/ArbeidstidArbeidstakerOppsummering.tsx" index 17d6b4d03e..fc87669e54 100644 --- "a/apps/endringsmelding-pleiepenger/src/app/s\303\270knad/steps/oppsummering/ArbeidstidArbeidstakerOppsummering.tsx" +++ "b/apps/endringsmelding-pleiepenger/src/app/s\303\270knad/steps/oppsummering/ArbeidstidArbeidstakerOppsummering.tsx" @@ -1,5 +1,5 @@ import { Heading, VStack } from '@navikt/ds-react'; -import { ArbeiderIPeriodenSvar, Arbeidsgiver, ArbeidstakerApiData } from '@types'; +import { ArbeiderIPeriodenSvar, ArbeidsgiverMedAnsettelseperioder, ArbeidstakerApiData } from '@types'; import { AppText } from '../../../i18n'; import ArbeidstidUker from '../../../modules/arbeidstid-uker/ArbeidstidUker'; @@ -8,7 +8,7 @@ import { oppsummeringStepUtils } from './oppsummeringStepUtils'; type Props = { arbeidstaker: ArbeidstakerApiData; - arbeidsgivere: Arbeidsgiver[]; + arbeidsgivere: ArbeidsgiverMedAnsettelseperioder[]; arbeidstidKolonneTittel?: string; }; diff --git "a/apps/endringsmelding-pleiepenger/src/app/s\303\270knad/steps/oppsummering/ArbeidstidOppsummering.tsx" "b/apps/endringsmelding-pleiepenger/src/app/s\303\270knad/steps/oppsummering/ArbeidstidOppsummering.tsx" index c16e305d1b..6feeef5a26 100644 --- "a/apps/endringsmelding-pleiepenger/src/app/s\303\270knad/steps/oppsummering/ArbeidstidOppsummering.tsx" +++ "b/apps/endringsmelding-pleiepenger/src/app/s\303\270knad/steps/oppsummering/ArbeidstidOppsummering.tsx" @@ -1,5 +1,5 @@ import { Heading, VStack } from '@navikt/ds-react'; -import { Arbeidsgiver, ArbeidstidApiData } from '@types'; +import { ArbeidsgiverMedAnsettelseperioder, ArbeidstidApiData } from '@types'; import { AppText, useAppIntl } from '../../../i18n'; import ArbeidstidUker from '../../../modules/arbeidstid-uker/ArbeidstidUker'; @@ -8,7 +8,7 @@ import { oppsummeringStepUtils } from './oppsummeringStepUtils'; interface Props { arbeidstid: ArbeidstidApiData; - arbeidsgivere: Arbeidsgiver[]; + arbeidsgivere: ArbeidsgiverMedAnsettelseperioder[]; } const ArbeidstidOppsummering = ({ arbeidstid, arbeidsgivere }: Props) => { diff --git "a/apps/endringsmelding-pleiepenger/src/app/s\303\270knad/steps/ukjent-arbeidsforhold/UkjentArbeidsforholdForm.tsx" "b/apps/endringsmelding-pleiepenger/src/app/s\303\270knad/steps/ukjent-arbeidsforhold/UkjentArbeidsforholdForm.tsx" index a3b6405428..451d682e2c 100644 --- "a/apps/endringsmelding-pleiepenger/src/app/s\303\270knad/steps/ukjent-arbeidsforhold/UkjentArbeidsforholdForm.tsx" +++ "b/apps/endringsmelding-pleiepenger/src/app/s\303\270knad/steps/ukjent-arbeidsforhold/UkjentArbeidsforholdForm.tsx" @@ -8,7 +8,12 @@ import { YesOrNo, } from '@navikt/sif-common-formik-ds'; import { FormLayout } from '@navikt/sif-common-ui'; -import { ArbeidsaktivitetType, Arbeidsgiver, SøknadContextState, UkjentArbeidsforholdSøknadsdata } from '@types'; +import { + ArbeidsaktivitetType, + ArbeidsgiverMedAnsettelseperioder, + SøknadContextState, + UkjentArbeidsforholdSøknadsdata, +} from '@types'; import { useIntl } from 'react-intl'; import ArbeidsaktivitetBlock from '../../../components/arbeidsaktivitet-block/ArbeidsaktivitetBlock'; @@ -58,8 +63,8 @@ const { FormikWrapper, Form } = getTypedFormComponents< >(); interface Props { - arbeidsgivere: Arbeidsgiver[]; - arbeidsgivereIkkeISak: Arbeidsgiver[]; + arbeidsgivere: ArbeidsgiverMedAnsettelseperioder[]; + arbeidsgivereIkkeISak: ArbeidsgiverMedAnsettelseperioder[]; ukjentArbeidsforholdSøknadsdata?: UkjentArbeidsforholdSøknadsdata; stepId: StepId; goBack?: () => void; diff --git "a/apps/endringsmelding-pleiepenger/src/app/s\303\270knad/steps/ukjent-arbeidsforhold/ukjentArbeidsforholdStepUtils.ts" "b/apps/endringsmelding-pleiepenger/src/app/s\303\270knad/steps/ukjent-arbeidsforhold/ukjentArbeidsforholdStepUtils.ts" index 0d504e52c7..ba0767ea8b 100644 --- "a/apps/endringsmelding-pleiepenger/src/app/s\303\270knad/steps/ukjent-arbeidsforhold/ukjentArbeidsforholdStepUtils.ts" +++ "b/apps/endringsmelding-pleiepenger/src/app/s\303\270knad/steps/ukjent-arbeidsforhold/ukjentArbeidsforholdStepUtils.ts" @@ -1,7 +1,7 @@ import { getNumberFromNumberInputValue, IntlErrorObject, YesOrNo } from '@navikt/sif-common-formik-ds'; import { decimalDurationToDuration, durationToDecimalDuration } from '@navikt/sif-common-utils'; import { getNumberValidator, getYesOrNoValidator } from '@navikt/sif-validation'; -import { Arbeidsforhold, Arbeidsgiver, UkjentArbeidsforholdSøknadsdata } from '@types'; +import { Arbeidsforhold, ArbeidsgiverMedAnsettelseperioder, UkjentArbeidsforholdSøknadsdata } from '@types'; import { UkjentArbeidsforholdArbeidsgiverFormValues, @@ -26,7 +26,7 @@ const arbeidsforholdSøknadsdataToFormValues = ( const ukjentArbeidsgiverFormValuesToSøknadsdata = ( formValues: UkjentArbeidsforholdArbeidsgiverFormValues, - arbeidsgiver?: Arbeidsgiver, + arbeidsgiver?: ArbeidsgiverMedAnsettelseperioder, ): Arbeidsforhold | undefined => { if (!arbeidsgiver) { return undefined; @@ -55,7 +55,7 @@ const ukjentArbeidsgiverFormValuesToSøknadsdata = ( export const getUkjentArbeidsforholdStepInitialValues = ( ukjentArbeidsforholdSøknadsdata: UkjentArbeidsforholdSøknadsdata | undefined, formValues: UkjentArbeidsforholdFormValues | undefined, - arbeidsgivereIkkeISak: Arbeidsgiver[], + arbeidsgivereIkkeISak: ArbeidsgiverMedAnsettelseperioder[], ): UkjentArbeidsforholdFormValues => { if (formValues) { return formValues; @@ -80,7 +80,7 @@ export const getUkjentArbeidsforholdStepInitialValues = ( export const getUkjentArbeidsforholdSøknadsdataFromFormValues = ( values: UkjentArbeidsforholdFormValues, - arbeidsgivere: Arbeidsgiver[], + arbeidsgivere: ArbeidsgiverMedAnsettelseperioder[], ): UkjentArbeidsforholdSøknadsdata => { const arbeidsforhold: Arbeidsforhold[] = []; Object.keys(values.arbeidsforhold).forEach((key) => { diff --git a/apps/endringsmelding-pleiepenger/src/app/types/Arbeidsgiver.ts b/apps/endringsmelding-pleiepenger/src/app/types/Arbeidsgiver.ts deleted file mode 100644 index 9eb45da42f..0000000000 --- a/apps/endringsmelding-pleiepenger/src/app/types/Arbeidsgiver.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface Arbeidsgiver { - key: string /** orgnummer prefixet med a_ */; - organisasjonsnummer: string; - navn: string; - ansattFom?: Date; - ansattTom?: Date; -} diff --git a/apps/endringsmelding-pleiepenger/src/app/types/ArbeidsgiverMedAnsettelseperioder.ts b/apps/endringsmelding-pleiepenger/src/app/types/ArbeidsgiverMedAnsettelseperioder.ts new file mode 100644 index 0000000000..4831b5f9ad --- /dev/null +++ b/apps/endringsmelding-pleiepenger/src/app/types/ArbeidsgiverMedAnsettelseperioder.ts @@ -0,0 +1,8 @@ +import { MaybeDateRange } from '@navikt/sif-common-utils'; + +export interface ArbeidsgiverMedAnsettelseperioder { + key: string /** orgnummer prefixet med a_ */; + organisasjonsnummer: string; + navn: string; + ansettelsesperioder: MaybeDateRange[]; +} diff --git "a/apps/endringsmelding-pleiepenger/src/app/types/IngenTilgang\303\205rsak.ts" "b/apps/endringsmelding-pleiepenger/src/app/types/IngenTilgang\303\205rsak.ts" index dd30569002..afeb2b4c75 100644 --- "a/apps/endringsmelding-pleiepenger/src/app/types/IngenTilgang\303\205rsak.ts" +++ "b/apps/endringsmelding-pleiepenger/src/app/types/IngenTilgang\303\205rsak.ts" @@ -4,6 +4,7 @@ export enum IngenTilgangÅrsak { 'søknadsperioderUtenforTillattEndringsperiode' = 'søknadsperioderUtenforTillattEndringsperiode', 'harMerEnnEnSak' = 'harMerEnnEnSak', 'harIngenPerioder' = 'harIngenPerioder', - 'harArbeidsgiverUtenArbeidsaktivitet' = 'harArbeidsgiverUtenArbeidsaktivitet', 'harArbeidstidSomSelvstendigNæringsdrivende' = 'harArbeidstidSomSelvstendigNæringsdrivende', + 'enArbeidsgiverToAnsettelserSammeUkeMedOpphold' = 'harAnsettelsesforholdSomSlutterOgStarterInneforSammeUke', + 'harFlereAnsettelsesforholdHosUkjentArbeidsgiver' = 'harFlereAnsettelsesforholdHosUkjentArbeidsgiver', } diff --git a/apps/endringsmelding-pleiepenger/src/app/types/Sak.ts b/apps/endringsmelding-pleiepenger/src/app/types/Sak.ts index 5d93683d80..dc9f69671c 100644 --- a/apps/endringsmelding-pleiepenger/src/app/types/Sak.ts +++ b/apps/endringsmelding-pleiepenger/src/app/types/Sak.ts @@ -1,7 +1,7 @@ import { DateRange, Duration, ISODate, ISODateRangeMap } from '@navikt/sif-common-utils'; import { FeriedagMap } from '../søknad/steps/lovbestemt-ferie/LovbestemtFerieStep'; -import { Arbeidsgiver } from './Arbeidsgiver'; +import { ArbeidsgiverMedAnsettelseperioder } from './ArbeidsgiverMedAnsettelseperioder'; import { K9SakBarn } from './K9Sak'; export interface Sak { @@ -10,7 +10,7 @@ export interface Sak { /** Settes til true hvis det finnes en arbeidsgiver som ikke har arbeidstid i sak */ harArbeidsgivereIkkeISak: boolean; /** Alle arbeidsgivere som ikke finnes i sak, men som finnes i Aa-reg */ - arbeidsgivereIkkeISak: Arbeidsgiver[]; + arbeidsgivereIkkeISak: ArbeidsgiverMedAnsettelseperioder[]; /** Alle aktiviteter som ikke har arbeidsgiver i AA-reg */ arbeidsaktivitetMedUkjentArbeidsgiver: ArbeidsaktivitetUkjentArbeidsgiver[]; /** Alle arbeidsaktiviteter i sak. Arbeidsgivere flates ut og legges sammen med evt. frilans og selvstendig */ @@ -63,6 +63,7 @@ export interface Arbeidsuke { faktisk?: ArbeidsukeTimer; normalt: ArbeidsukeTimer; antallDagerMedArbeidstid: number; + dagerSøktFor: Date[]; } export type ArbeidsukeMap = ISODateRangeMap; @@ -78,11 +79,12 @@ interface ArbeidsaktivitetBase { perioderMedArbeidstid: PeriodeMedArbeidstid[]; harPerioderFørTillattEndringsperiode: boolean; harPerioderEtterTillattEndringsperiode: boolean; + ansettelsesperioderInnenforEndringsperiode: DateRange[]; } export interface ArbeidsaktivitetArbeidstaker extends ArbeidsaktivitetBase { type: ArbeidsaktivitetType.arbeidstaker; - arbeidsgiver: Arbeidsgiver; + arbeidsgiver: ArbeidsgiverMedAnsettelseperioder; erUkjentArbeidsforhold: boolean; } export interface ArbeidsaktivitetUkjentArbeidsgiver { diff --git "a/apps/endringsmelding-pleiepenger/src/app/types/S\303\270knadContextState.ts" "b/apps/endringsmelding-pleiepenger/src/app/types/S\303\270knadContextState.ts" index 09c8cebefc..5a52f824b4 100644 --- "a/apps/endringsmelding-pleiepenger/src/app/types/S\303\270knadContextState.ts" +++ "b/apps/endringsmelding-pleiepenger/src/app/types/S\303\270knadContextState.ts" @@ -3,7 +3,7 @@ import { DateRange } from '@navikt/sif-common-utils'; import { SøknadRoutes } from '../søknad/config/SøknadRoutes'; import { StepId } from '../søknad/config/StepId'; -import { Arbeidsgiver } from './Arbeidsgiver'; +import { ArbeidsgiverMedAnsettelseperioder } from './ArbeidsgiverMedAnsettelseperioder'; import { K9Sak } from './K9Sak'; import { Sak } from './Sak'; import { Søknadsdata } from './Søknadsdata'; @@ -16,7 +16,7 @@ export interface SøknadContextState { k9saker: K9Sak[]; sak: Sak; tillattEndringsperiode: DateRange; - arbeidsgivere: Arbeidsgiver[]; + arbeidsgivere: ArbeidsgiverMedAnsettelseperioder[]; søknadsdata: Søknadsdata; søknadRoute?: SøknadRoutes; endringsmeldingSendt?: boolean; diff --git a/apps/endringsmelding-pleiepenger/src/app/types/index.ts b/apps/endringsmelding-pleiepenger/src/app/types/index.ts index 5124116167..33ec029dc6 100644 --- a/apps/endringsmelding-pleiepenger/src/app/types/index.ts +++ b/apps/endringsmelding-pleiepenger/src/app/types/index.ts @@ -1,7 +1,8 @@ export * from './ArbeiderIPeriodenSvar'; export * from './Arbeidsforhold'; -export * from './Arbeidsgiver'; export * from './ArbeidsgiverIkkeFunnetError'; +export * from './ArbeidsgiverMedAnsettelseperioder'; +export * from './ArbeidstidEndring'; export * from './ArbeidstidEndring'; export * from './ArbeidstidSøknadsdata'; export * from './EndringType'; diff --git a/apps/endringsmelding-pleiepenger/src/app/utils/__tests__/getSakFromK9Sak.test.ts b/apps/endringsmelding-pleiepenger/src/app/utils/__tests__/getSakFromK9Sak.test.ts index a89ab7524d..df7d0da499 100644 --- a/apps/endringsmelding-pleiepenger/src/app/utils/__tests__/getSakFromK9Sak.test.ts +++ b/apps/endringsmelding-pleiepenger/src/app/utils/__tests__/getSakFromK9Sak.test.ts @@ -9,7 +9,12 @@ import { ISODuration, ISODurationToDuration, } from '@navikt/sif-common-utils'; -import { Arbeidsgiver, ArbeidstidEnkeltdagMap, FaktiskOgNormalArbeidstid, K9SakArbeidstidPeriodeMap } from '@types'; +import { + ArbeidsgiverMedAnsettelseperioder, + ArbeidstidEnkeltdagMap, + FaktiskOgNormalArbeidstid, + K9SakArbeidstidPeriodeMap, +} from '@types'; import { _getSakFromK9Sak } from '../getSakFromK9Sak'; @@ -39,15 +44,15 @@ describe('getSakFromK9Sak', () => { const endringsperiode: DateRange = { from: ISODateToDate(isoFrom), to: ISODateToDate(isoTo) }; it('beholder uendret endringsperiode hvis bruker er fortsatt ansatt', () => { const result = getEndringsperiodeForArbeidsgiver(endringsperiode, { - ansattTom: undefined, - } as Arbeidsgiver); + ansettelsesperioder: [{ to: undefined }], + } as ArbeidsgiverMedAnsettelseperioder); expect(dateToISODate(result.from)).toEqual(isoFrom); expect(dateToISODate(result.to)).toEqual(isoTo); }); it('justerer endringsperiode hvis sluttdato er før endringsperiode sluttdato', () => { const result = getEndringsperiodeForArbeidsgiver(endringsperiode, { - ansattTom: ISODateToDate(isoSluttdato), - } as Arbeidsgiver); + ansettelsesperioder: [{ to: ISODateToDate(isoSluttdato) }], + } as ArbeidsgiverMedAnsettelseperioder); expect(dateToISODate(result.from)).toEqual(isoFrom); expect(dateToISODate(result.to)).toEqual(isoSluttdato); }); @@ -189,6 +194,9 @@ describe('getSakFromK9Sak', () => { }); describe('getArbeidsukerFromEnkeltdager', () => { + const ansettelsesperioder: DateRange[] = [ + { from: ISODateToDate('2022-01-01'), to: ISODateToDate('2023-01-31') }, + ]; const arbeidstid: FaktiskOgNormalArbeidstid = { faktisk: faktiskArbeidTimerPerDag, normalt: jobberNormaltTimerPerDag, @@ -214,21 +222,21 @@ describe('getSakFromK9Sak', () => { }; it('returnerer riktig for én enkeltdag', () => { - const result = getArbeidsukerFromEnkeltdager(enkeltdag); + const result = getArbeidsukerFromEnkeltdager(enkeltdag, ansettelsesperioder); expect(result.length).toEqual(1); const uke = result[0]; expect(dateRangeToISODateRange(uke.periode)).toEqual('2022-01-03/2022-01-03'); expect(uke.antallDagerMedArbeidstid).toEqual(1); }); it('returnerer riktig for dager som går over én hel uke', () => { - const result = getArbeidsukerFromEnkeltdager(helUke); + const result = getArbeidsukerFromEnkeltdager(helUke, ansettelsesperioder); expect(result.length).toEqual(1); const uke = result[0]; expect(dateRangeToISODateRange(uke.periode)).toEqual('2022-01-03/2022-01-07'); expect(uke.antallDagerMedArbeidstid).toEqual(5); }); it('returnerer riktig for dager som går mer enn én uker', () => { - const result = getArbeidsukerFromEnkeltdager(flereUker); + const result = getArbeidsukerFromEnkeltdager(flereUker, ansettelsesperioder); expect(result.length).toEqual(2); const uke1 = result[0]; const uke2 = result[1]; @@ -291,9 +299,9 @@ describe('getSakFromK9Sak', () => { ISODateRangeToDateRange('2020-01-01/2020-02-01'), ISODateRangeToDateRange('2020-04-01/2020-05-01'), ]; - const arbeidsgiver: Arbeidsgiver = { - ansattFom: ISODateToDate('2019-01-01'), - } as Arbeidsgiver; + const arbeidsgiver: ArbeidsgiverMedAnsettelseperioder = { + ansettelsesperioder: [{ from: ISODateToDate('2019-01-01') }], + } as ArbeidsgiverMedAnsettelseperioder; describe('uten ansattTom', () => { it('returnerer true når ansattFom er før søknadsperiode', () => { @@ -302,7 +310,9 @@ describe('getSakFromK9Sak', () => { it('returnerer true når ansattFom er mellom to søknadsperiode', () => { expect( erArbeidsgiverInnenforSøknadsperioder( - { ansattFom: ISODateToDate('2020-02-03') } as Arbeidsgiver, + { + ansettelsesperioder: [{ from: ISODateToDate('2020-02-03') }], + } as ArbeidsgiverMedAnsettelseperioder, søknadsperioder, ), ).toBeTruthy(); @@ -310,7 +320,9 @@ describe('getSakFromK9Sak', () => { it('returnerer true når ansattFom er i en søknadsperiode', () => { expect( erArbeidsgiverInnenforSøknadsperioder( - { ansattFom: ISODateToDate('2020-03-02') } as Arbeidsgiver, + { + ansettelsesperioder: [{ from: ISODateToDate('2020-03-02') }], + } as ArbeidsgiverMedAnsettelseperioder, søknadsperioder, ), ).toBeTruthy(); @@ -318,7 +330,9 @@ describe('getSakFromK9Sak', () => { it('returnerer false når ansattFom er etter søknadsperiode', () => { expect( erArbeidsgiverInnenforSøknadsperioder( - { ansattFom: ISODateToDate('2020-05-02') } as Arbeidsgiver, + { + ansettelsesperioder: [{ from: ISODateToDate('2020-05-02') }], + } as ArbeidsgiverMedAnsettelseperioder, søknadsperioder, ), ).toBeFalsy(); @@ -329,9 +343,10 @@ describe('getSakFromK9Sak', () => { expect( erArbeidsgiverInnenforSøknadsperioder( { - ansattFom: ISODateToDate('2019-01-01'), - ansattTom: ISODateToDate('2023-01-01'), - } as Arbeidsgiver, + ansettelsesperioder: [ + { from: ISODateToDate('2019-01-01'), to: ISODateToDate('2023-01-01') }, + ], + } as ArbeidsgiverMedAnsettelseperioder, søknadsperioder, ), ).toBeTruthy(); @@ -340,9 +355,10 @@ describe('getSakFromK9Sak', () => { expect( erArbeidsgiverInnenforSøknadsperioder( { - ansattFom: ISODateToDate('2019-01-01'), - ansattTom: ISODateToDate('2020-03-01'), - } as Arbeidsgiver, + ansettelsesperioder: [ + { from: ISODateToDate('2019-01-01'), to: ISODateToDate('2020-03-01') }, + ], + } as ArbeidsgiverMedAnsettelseperioder, søknadsperioder, ), ).toBeTruthy(); @@ -351,9 +367,13 @@ describe('getSakFromK9Sak', () => { expect( erArbeidsgiverInnenforSøknadsperioder( { - ansattFom: ISODateToDate('2019-01-01'), - ansattTom: ISODateToDate('2019-12-31'), - } as Arbeidsgiver, + ansettelsesperioder: [ + { + from: ISODateToDate('2019-01-01'), + to: ISODateToDate('2019-12-31'), + }, + ], + } as ArbeidsgiverMedAnsettelseperioder, søknadsperioder, ), ).toBeFalsy(); @@ -362,9 +382,10 @@ describe('getSakFromK9Sak', () => { expect( erArbeidsgiverInnenforSøknadsperioder( { - ansattFom: ISODateToDate('2020-03-01'), - ansattTom: ISODateToDate('2020-03-02'), - } as Arbeidsgiver, + ansettelsesperioder: [ + { from: ISODateToDate('2020-03-01'), to: ISODateToDate('2020-03-02') }, + ], + } as ArbeidsgiverMedAnsettelseperioder, søknadsperioder, ), ).toBeFalsy(); diff --git a/apps/endringsmelding-pleiepenger/src/app/utils/__tests__/tilgangskontroll.test.ts b/apps/endringsmelding-pleiepenger/src/app/utils/__tests__/tilgangskontroll.test.ts index 76acf129f3..2e1c6166bc 100644 --- a/apps/endringsmelding-pleiepenger/src/app/utils/__tests__/tilgangskontroll.test.ts +++ b/apps/endringsmelding-pleiepenger/src/app/utils/__tests__/tilgangskontroll.test.ts @@ -1,9 +1,37 @@ import { DateRange, ISODateRangeToDateRange, ISODurationToDuration } from '@navikt/sif-common-utils'; -import { K9SakArbeidstaker, K9SakArbeidstidPeriodeMap } from '@types'; +import { ArbeidsgiverMedAnsettelseperioder, K9SakArbeidstaker, K9SakArbeidstidPeriodeMap } from '@types'; import { vi } from 'vitest'; import { tilgangskontroll, tilgangskontrollUtils } from '../tilgangskontroll'; +const ansettelsesperioder: DateRange[] = [ISODateRangeToDateRange('2022-01-01/2023-03-01')]; + +const arbeidsgiver1: ArbeidsgiverMedAnsettelseperioder = { + key: 'a_1', + navn: 'a_1', + ansettelsesperioder, + organisasjonsnummer: '1', +}; +const arbeidsgiver2: ArbeidsgiverMedAnsettelseperioder = { + key: 'a_2', + navn: 'a_2', + ansettelsesperioder, + organisasjonsnummer: '2', +}; + +const arbeidsgiverFlereAnsettelsesperioder: ArbeidsgiverMedAnsettelseperioder = { + key: 'a_4', + navn: 'a_4', + ansettelsesperioder: [ + ISODateRangeToDateRange('2022-01-01/2023-02-01'), + ISODateRangeToDateRange('2023-02-01/2023-03-01'), + ], + organisasjonsnummer: '4', +} as ArbeidsgiverMedAnsettelseperioder; + +const arbeidstaker1: K9SakArbeidstaker = { organisasjonsnummer: '1' } as K9SakArbeidstaker; +const arbeidstaker2: K9SakArbeidstaker = { organisasjonsnummer: '2' } as K9SakArbeidstaker; + vi.mock('@navikt/sif-common-env', () => ({ getRequiredEnv: () => { return false; @@ -23,24 +51,49 @@ describe('tilgangskontroll', () => { const tillattEndringsperiode = ISODateRangeToDateRange('2022-01-01/2023-03-01'); it('stopper ved ingen sak', () => { - const result = tilgangskontroll([], tillattEndringsperiode); + const result = tilgangskontroll([], tillattEndringsperiode, []); expect(result.kanBrukeSøknad).toBeFalsy(); }); it('stopper hvis bruker har flere enn én sak', () => { - const result = tilgangskontroll([true, false] as any, tillattEndringsperiode); + const result = tilgangskontroll([true, false] as any, tillattEndringsperiode, []); expect(result.kanBrukeSøknad).toBeFalsy(); }); }); +describe('harFlereAnsettelsesforholdHosUkjentArbeidsgiver', () => { + /** TODO - oppdatere */ + it('returnerer true hvis arbeidsgiver ikke har arbeidsaktivitet i sak og har flere ansettelseperioder', () => { + const result = tilgangskontrollUtils.harFlereAnsettelsesforholdHosUkjentArbeidsgiver( + [arbeidsgiverFlereAnsettelsesperioder], + [arbeidstaker1, arbeidstaker2], + ); + expect(result).toBeTruthy(); + }); + it('returnerer false hvis alle arbeidsgivere har arbeidsaktivitet i sak', () => { + const result = tilgangskontrollUtils.harFlereAnsettelsesforholdHosUkjentArbeidsgiver( + [arbeidsgiver1, arbeidsgiver2], + [arbeidstaker1, arbeidstaker2], + ); + expect(result).toBeFalsy(); + }); + it('returnerer true hvis arbeidsgiver ikke har arbeidsaktivitet i sak men har kun én ansettelseperiode', () => { + const result = tilgangskontrollUtils.harFlereAnsettelsesforholdHosUkjentArbeidsgiver( + [arbeidsgiver1], + [arbeidstaker1], + ); + expect(result).toBeFalsy(); + }); +}); + describe('harSakSøknadsperiodeInnenforTillattEndringsperiode', () => { - const tillatEndringsperiode = ISODateRangeToDateRange('2022-01-02/2022-02-01'); + const tillattEndringsperiode = ISODateRangeToDateRange('2022-01-02/2022-02-01'); const søknadsperiodeUtenfor: DateRange = ISODateRangeToDateRange('2022-01-01/2022-01-01'); const søknadsperiodeInnenfor: DateRange = ISODateRangeToDateRange('2022-01-02/2022-02-01'); it('returnerer true hvis søknadsperioder er innenfor tillatt endringsperiode', () => { const result = tilgangskontrollUtils.harSøknadsperiodeInnenforTillattEndringsperiode( søknadsperiodeInnenfor, - tillatEndringsperiode, + tillattEndringsperiode, ); expect(result).toBeTruthy(); }); @@ -48,7 +101,7 @@ describe('harSakSøknadsperiodeInnenforTillattEndringsperiode', () => { it('returnerer false hvis søknadsperioder er før tillatt endringsperiode', () => { const result = tilgangskontrollUtils.harSøknadsperiodeInnenforTillattEndringsperiode( søknadsperiodeUtenfor, - tillatEndringsperiode, + tillattEndringsperiode, ); expect(result).toBeFalsy(); }); @@ -123,3 +176,32 @@ describe('ingenTilgangMeta', () => { expect(result.erSN).toBeTruthy(); }); }); + +describe('slutterOgStarterHosArbeidsgiverSammeUke', () => { + const uke2: DateRange = ISODateRangeToDateRange('2025-01-06/2025-01-12'); + const uke4: DateRange = ISODateRangeToDateRange('2025-01-20/2025-01-26'); + const uke3ManOns: DateRange = ISODateRangeToDateRange('2025-01-13/2025-01-15'); + const uke3TorFre: DateRange = ISODateRangeToDateRange('2025-01-16/2025-01-17'); + const uke3FreSøn: DateRange = ISODateRangeToDateRange('2025-01-17/2025-01-19'); + + it('returnerer false hvis det ikke er noen ansettelsesperiode', () => { + expect(tilgangskontrollUtils.perioderSlutterOgStarterSammeUkeMedOpphold([])).toBeFalsy(); + }); + it('returnerer false hvis det bare er én ansettelsesperiode', () => { + expect(tilgangskontrollUtils.perioderSlutterOgStarterSammeUkeMedOpphold([uke2])).toBeFalsy(); + }); + it('returnerer false hvis det to ansettelsesperiode med én uke mellom', () => { + expect(tilgangskontrollUtils.perioderSlutterOgStarterSammeUkeMedOpphold([uke2, uke4])).toBeFalsy(); + }); + it('returnerer false hvis det to ansettelsesperiode med er sammenhengende', () => { + expect(tilgangskontrollUtils.perioderSlutterOgStarterSammeUkeMedOpphold([uke3ManOns, uke3TorFre])).toBeFalsy(); + }); + it('returnerer true hvis to perioder slutter og starter innenfor samme uke men med opphold', () => { + expect(tilgangskontrollUtils.perioderSlutterOgStarterSammeUkeMedOpphold([uke3ManOns, uke3FreSøn])).toBeTruthy(); + }); + it('returnerer true hvis to det er mange perioder usortert og noen slutter og starter innenfor samme uke men med opphold', () => { + expect( + tilgangskontrollUtils.perioderSlutterOgStarterSammeUkeMedOpphold([uke2, uke4, uke3ManOns, uke3FreSøn]), + ).toBeTruthy(); + }); +}); diff --git a/apps/endringsmelding-pleiepenger/src/app/utils/__tests__/ukjentArbeidsgiverUtils.ts b/apps/endringsmelding-pleiepenger/src/app/utils/__tests__/ukjentArbeidsgiverUtils.test.ts similarity index 100% rename from apps/endringsmelding-pleiepenger/src/app/utils/__tests__/ukjentArbeidsgiverUtils.ts rename to apps/endringsmelding-pleiepenger/src/app/utils/__tests__/ukjentArbeidsgiverUtils.test.ts diff --git a/apps/endringsmelding-pleiepenger/src/app/utils/arbeidsukeUtils.ts b/apps/endringsmelding-pleiepenger/src/app/utils/arbeidsukeUtils.ts index 854056bf03..24f2442f21 100644 --- a/apps/endringsmelding-pleiepenger/src/app/utils/arbeidsukeUtils.ts +++ b/apps/endringsmelding-pleiepenger/src/app/utils/arbeidsukeUtils.ts @@ -1,18 +1,13 @@ import { dateFormatter, DateRange, - dateRangeToISODateRange, durationToISODuration, - durationUtils, getDatesInDateRange, ISODate, - numberDurationAsDuration, } from '@navikt/sif-common-utils'; -import { ArbeidstidEnkeltdagMap, Arbeidsuke, ArbeidsukeTimer } from '@types'; +import { ArbeidstidEnkeltdagMap, Arbeidsuke } from '@types'; import dayjs from 'dayjs'; -import { beregnSnittTimerPerDag } from './beregnUtils'; - export const sorterArbeidsuker = (a1: Arbeidsuke, a2: Arbeidsuke): number => { return dayjs(a1.periode.from).isBefore(a2.periode.from) ? -1 : 1; }; @@ -57,43 +52,3 @@ export const arbeidsukerHarLikNormaltidPerDag = (arbeidsuker: Arbeidsuke[]): boo export const getDagerFraEnkeltdagMap = (arbeidstidEnkeltdager: ArbeidstidEnkeltdagMap): ISODate[] => { return Object.keys(arbeidstidEnkeltdager).sort(); }; - -/** - * Mapper periode og enkeltdager med arbeid om til Arbeidsuke. Summerer tid per dag om til timer per uke - * @param periode DateRange for uken - * @param arbeidstidEnkeltdagerIUken Enkeltdager med arbeidstid innenfor uken - * @returns Arbeidsuke - */ -export const getArbeidsukeFromEnkeltdagerIUken = ( - uke: DateRange, - arbeidstidEnkeltdagerIUken: ArbeidstidEnkeltdagMap, -): Arbeidsuke => { - const dagerSøktFor = Object.keys(arbeidstidEnkeltdagerIUken); - const antallDagerMedArbeidstid = dagerSøktFor.length; - const normalt = dagerSøktFor.map((key) => arbeidstidEnkeltdagerIUken[key].normalt); - const normaltSummertHeleUken = numberDurationAsDuration(durationUtils.summarizeDurations(normalt)); - const faktiskEnkeltdager = dagerSøktFor.map((key) => arbeidstidEnkeltdagerIUken[key].faktisk); - const harFaktiskArbeidstid = faktiskEnkeltdager.some((f) => f !== undefined); - const faktiskSummertHeleUken = harFaktiskArbeidstid - ? numberDurationAsDuration(durationUtils.summarizeDurations(faktiskEnkeltdager)) - : undefined; - const faktisk: ArbeidsukeTimer | undefined = faktiskSummertHeleUken - ? { - uke: faktiskSummertHeleUken, - dag: beregnSnittTimerPerDag(faktiskSummertHeleUken, antallDagerMedArbeidstid), - } - : undefined; - - const arbeidsuke: Arbeidsuke = { - isoDateRange: dateRangeToISODateRange(uke), - periode: uke, - arbeidstidEnkeltdager: arbeidstidEnkeltdagerIUken, - faktisk, - normalt: { - uke: normaltSummertHeleUken, - dag: beregnSnittTimerPerDag(normaltSummertHeleUken, antallDagerMedArbeidstid), - }, - antallDagerMedArbeidstid: dagerSøktFor.length, - }; - return arbeidsuke; -}; diff --git a/apps/endringsmelding-pleiepenger/src/app/utils/getSakFromK9Sak.ts b/apps/endringsmelding-pleiepenger/src/app/utils/getSakFromK9Sak.ts index 5a49215f7c..39baedb703 100644 --- a/apps/endringsmelding-pleiepenger/src/app/utils/getSakFromK9Sak.ts +++ b/apps/endringsmelding-pleiepenger/src/app/utils/getSakFromK9Sak.ts @@ -11,10 +11,13 @@ import { getIsoWeekDateRangeForDate, getLastDateInDateRanges, isDateInDateRange, + isDateInDateRanges, ISODateRangeToDateRange, ISODateToDate, joinAdjacentDateRanges, + MaybeDateRange, numberDurationAsDuration, + sortMaybeDateRange, } from '@navikt/sif-common-utils'; import { Arbeidsaktivitet, @@ -23,7 +26,7 @@ import { ArbeidsaktivitetFrilanser, ArbeidsaktivitetSelvstendigNæringsdrivende, ArbeidsaktivitetType, - Arbeidsgiver, + ArbeidsgiverMedAnsettelseperioder, ArbeidsgiverIkkeFunnetError, ArbeidstidEnkeltdagMap, Arbeidsuke, @@ -63,7 +66,7 @@ interface _PeriodisertK9FormatArbeidstidPerioder { */ export const getSakFromK9Sak = ( k9sak: K9Sak, - alleArbeidsgivere: Arbeidsgiver[], + alleArbeidsgivere: ArbeidsgiverMedAnsettelseperioder[], tillattEndringsperiode: DateRange, ): Sak => { const { arbeidstakerList, frilanserArbeidstidInfo, selvstendigNæringsdrivendeArbeidstidInfo } = @@ -136,8 +139,8 @@ export const getSakFromK9Sak = ( /** Henter utk9SakArbeidstakere med arbeidsgiver funnet i AA-reg */ export const getArbeidsaktiviteterMedKjentArbeidsgiver = ( k9SakArbeidstakere: K9SakArbeidstaker[], - arbeidsgivere: Arbeidsgiver[], -) => { + arbeidsgivere: ArbeidsgiverMedAnsettelseperioder[], +): K9SakArbeidstaker[] => { return k9SakArbeidstakere.filter((a) => arbeidsgivere.some((arbg) => arbg.organisasjonsnummer === a.organisasjonsnummer), ); @@ -146,7 +149,7 @@ export const getArbeidsaktiviteterMedKjentArbeidsgiver = ( /** Henter utk9SakArbeidstakere hvor arbeidsgiver IKKE er funnet i AA-reg */ export const getArbeidsaktiviteterMedUkjentArbeidsgiver = ( k9SakArbeidstakere: K9SakArbeidstaker[], - arbeidsgivere: Arbeidsgiver[], + arbeidsgivere: ArbeidsgiverMedAnsettelseperioder[], ) => { return k9SakArbeidstakere.filter( (a) => arbeidsgivere.some((arbg) => arbg.organisasjonsnummer === a.organisasjonsnummer) === false, @@ -161,11 +164,13 @@ export const getArbeidsaktiviteterMedUkjentArbeidsgiver = ( */ const getEndringsperiodeForArbeidsgiver = ( tillattEndringsperiode: DateRange, - arbeidsgiver: Arbeidsgiver, + arbeidsgiver: ArbeidsgiverMedAnsettelseperioder, ): DateRange => { + const { ansettelsesperioder } = arbeidsgiver; + const sisteAnsattTom = ansettelsesperioder.sort(sortMaybeDateRange).reverse()[0]?.to; return { ...tillattEndringsperiode, - to: arbeidsgiver.ansattTom || tillattEndringsperiode.to, + to: sisteAnsattTom || tillattEndringsperiode.to, }; }; @@ -283,17 +288,25 @@ const fjernArbeidstidEnkeltdagerUtenforPeriode = ( return enkeltdagerMap; }; +const getDagerIkkeAnsattIPeriode = (periode: DateRange, ansettelsesperioder?: DateRange[]): Date[] => { + if (!ansettelsesperioder) { + return []; + } + return getDatesInDateRange(periode).filter((d) => !isDateInDateRanges(d, ansettelsesperioder)); +}; + /** * Mapper periode og enkeltdager med arbeid om til Arbeidsuke. Summerer tid per dag om til timer per uke - * @param periode DateRange for uken + * @param ansattUke DateRange for uken, justert ned til perioden en er ansatt * @param arbeidstidEnkeltdagerIUken Enkeltdager med arbeidstid * @returns Arbeidsuke */ -const getArbeidsukeFromEnkeltdagerIUken = ( - periode: DateRange, +export const getArbeidsukeFromEnkeltdagerIUken = ( + ansattUke: DateRange, arbeidstidEnkeltdager: ArbeidstidEnkeltdagMap, ): Arbeidsuke => { - const arbeidstidEnkeltdagerIUken = fjernArbeidstidEnkeltdagerUtenforPeriode(periode, arbeidstidEnkeltdager); + /** Forsikre seg om at ingen enkeltdager er utenfor uken */ + const arbeidstidEnkeltdagerIUken = fjernArbeidstidEnkeltdagerUtenforPeriode(ansattUke, arbeidstidEnkeltdager); const dagerSøktFor = Object.keys(arbeidstidEnkeltdagerIUken); const antallDagerMedArbeidstid = dagerSøktFor.length; const faktisk = dagerSøktFor.map((key) => arbeidstidEnkeltdagerIUken[key].faktisk); @@ -302,9 +315,11 @@ const getArbeidsukeFromEnkeltdagerIUken = ( const faktiskSummertHeleUken = numberDurationAsDuration(durationUtils.summarizeDurations(faktisk)); const arbeidsuke: Arbeidsuke = { - isoDateRange: dateRangeToISODateRange(periode), - periode: periode, + isoDateRange: dateRangeToISODateRange(ansattUke), + periode: ansattUke, arbeidstidEnkeltdager: arbeidstidEnkeltdagerIUken, + dagerSøktFor: dagerSøktFor.map(ISODateToDate), + antallDagerMedArbeidstid: dagerSøktFor.length, faktisk: { uke: faktiskSummertHeleUken, dag: beregnSnittTimerPerDag(faktiskSummertHeleUken, antallDagerMedArbeidstid), @@ -313,33 +328,39 @@ const getArbeidsukeFromEnkeltdagerIUken = ( uke: normaltSummertHeleUken, dag: beregnSnittTimerPerDag(normaltSummertHeleUken, antallDagerMedArbeidstid), }, - antallDagerMedArbeidstid: dagerSøktFor.length, }; return arbeidsuke; }; -const setArbeidsukeStartdatoTilFørsteDagSøktFor = (arbeidsuke: Arbeidsuke): Arbeidsuke => { - const dagerSøktFor = getDagerFraEnkeltdagMap(arbeidsuke.arbeidstidEnkeltdager); - const periode: DateRange = { ...arbeidsuke.periode, from: ISODateToDate(dagerSøktFor[0]) }; - return { - ...arbeidsuke, - periode, - isoDateRange: dateRangeToISODateRange(periode), - }; -}; - -const setArbeidsukeSluttdatoTilSisteDagSøktFor = (arbeidsuke: Arbeidsuke): Arbeidsuke => { +/** Fjerner dager det ikke er søkt for i en arbeidsuke. Men inkluderer lørdag og søndag */ +const trimArbeidsukePeriodeTilDagerSøktForEllerHelUke = ( + arbeidsuke: Arbeidsuke, + erSisteUkeIPeriode: boolean, + ansettelsesperioder: DateRange[], +): Arbeidsuke => { const dagerSøktFor = getDagerFraEnkeltdagMap(arbeidsuke.arbeidstidEnkeltdager); const periode: DateRange = { - ...arbeidsuke.periode, + from: ISODateToDate(dagerSøktFor[0]), to: ISODateToDate(dagerSøktFor[dagerSøktFor.length - 1]), }; + if (!erSisteUkeIPeriode && dayjs(periode.to).isoWeekday() === 5) { + const søndag = dayjs(periode.to).add(2, 'day').toDate(); + const lørdag = dayjs(periode.to).add(1, 'day').toDate(); + if (isDateInDateRanges(søndag, ansettelsesperioder)) { + // Kontroller om en er ansatt søndag + periode.to = søndag; + } else if (isDateInDateRanges(lørdag, ansettelsesperioder)) { + // Kontroller om en er ansatt lørdag + periode.to = lørdag; + } + } return { ...arbeidsuke, periode, isoDateRange: dateRangeToISODateRange(periode), }; }; + /** * Grupperer arbeidsdager inn i uker * Hver uke er hele uker, inklusiv helg, med unntak av første og siste uke som @@ -348,7 +369,10 @@ const setArbeidsukeSluttdatoTilSisteDagSøktFor = (arbeidsuke: Arbeidsuke): Arbe * @param enkeltdager * @returns Array av arbeidsuker */ -const getArbeidsukerFromEnkeltdager = (enkeltdager: ArbeidstidEnkeltdagMap): Arbeidsuke[] => { +const getArbeidsukerFromEnkeltdager = ( + enkeltdager: ArbeidstidEnkeltdagMap, + ansettelsesperioder: DateRange[], +): Arbeidsuke[] => { const ukerMap: { [key: string]: { dagerMap: ArbeidstidEnkeltdagMap; @@ -361,7 +385,17 @@ const getArbeidsukerFromEnkeltdager = (enkeltdager: ArbeidstidEnkeltdagMap): Arb const { faktisk, normalt } = enkeltdager[isoDate]; /** Midlertidig nøkkel som tar hele uken */ - const isoDateRange = dateRangeToISODateRange(getIsoWeekDateRangeForDate(date)); + const uke = getIsoWeekDateRangeForDate(date); + /** Litt tungvindt måte å fjerne dager på, men virker frem til hele løsningen tar bedre høyde for ansettelsesperioder */ + const dagerAnsattIUken = getDatesInDateRange(uke).filter((d) => isDateInDateRanges(d, ansettelsesperioder)); + if (dagerAnsattIUken.length === 0) { + throw new Error('Dag utenfor ansettelsesperiode'); + } + const ansattUke: DateRange = { + from: dagerAnsattIUken[0], + to: dagerAnsattIUken[dagerAnsattIUken.length - 1], + }; + const isoDateRange = dateRangeToISODateRange(ansattUke); if (ukerMap[isoDateRange] === undefined) { ukerMap[isoDateRange] = { dagerMap: {}, @@ -381,8 +415,17 @@ const getArbeidsukerFromEnkeltdager = (enkeltdager: ArbeidstidEnkeltdagMap): Arb }); /** Juster start og sluttdato til første og siste dag søkt for (dag med arbeidstid) */ - arbeidsuker[0] = setArbeidsukeStartdatoTilFørsteDagSøktFor(arbeidsuker[0]); - arbeidsuker[arbeidsuker.length - 1] = setArbeidsukeSluttdatoTilSisteDagSøktFor(arbeidsuker[arbeidsuker.length - 1]); + const antallUker = arbeidsuker.length; + if (antallUker > 0) { + arbeidsuker.forEach((arbeidsuke, index) => { + const erSisteUke = index === antallUker - 1; + arbeidsuker[index] = trimArbeidsukePeriodeTilDagerSøktForEllerHelUke( + arbeidsuke, + erSisteUke, + ansettelsesperioder, + ); + }); + } return arbeidsuker; }; @@ -395,14 +438,25 @@ const getArbeidsukerFromEnkeltdager = (enkeltdager: ArbeidstidEnkeltdagMap): Arb const getPerioderMedArbeidstid = ( arbeidstidPeriodeMap: K9SakArbeidstidPeriodeMap, tillattEndringsperiode: DateRange, + ansettelsesperioderInnenforEndringsperiode: DateRange[], ): PeriodeMedArbeidstid[] => { const perioder = trimArbeidstidTilTillattEndringsperiode(arbeidstidPeriodeMap, tillattEndringsperiode); return grupperArbeidstidPerioder(perioder).map((gruppertPeriode) => { const enkeltdagerIPeriode = getArbeidstidEnkeltdagMapFromPerioder(gruppertPeriode.arbeidstidPerioder); - const arbeidsuker = getArbeidsukerMapFromArbeidsuker(getArbeidsukerFromEnkeltdager(enkeltdagerIPeriode)); + const arbeidsdagerSomKanEndres = getArbeidsdagerInneforEndringsperiodeOgAnsettelsesperioder( + enkeltdagerIPeriode, + tillattEndringsperiode, + ansettelsesperioderInnenforEndringsperiode, + ); + const uker = getArbeidsukerFromEnkeltdager( + arbeidsdagerSomKanEndres, + ansettelsesperioderInnenforEndringsperiode, + ); + const periodeSomKanEndres: DateRange = { from: uker[0].periode.from, to: uker[uker.length - 1].periode.to }; + const arbeidsuker = getArbeidsukerMapFromArbeidsuker(uker); const periode: PeriodeMedArbeidstid = { - ...gruppertPeriode.periode, + ...periodeSomKanEndres, arbeidsuker, }; return periode; @@ -450,12 +504,17 @@ const harPerioderEtterEndringsperiode = ( const getArbeidsaktivitetPerioderPart = ( arbeidstidPerioder: K9SakArbeidstidPeriodeMap, endringsperiode: DateRange, + ansettelsesperioderInnenforEndringsperiode: DateRange[], ): Pick< Arbeidsaktivitet, 'perioderMedArbeidstid' | 'harPerioderEtterTillattEndringsperiode' | 'harPerioderFørTillattEndringsperiode' > => { return { - perioderMedArbeidstid: getPerioderMedArbeidstid(arbeidstidPerioder, endringsperiode), + perioderMedArbeidstid: getPerioderMedArbeidstid( + arbeidstidPerioder, + endringsperiode, + ansettelsesperioderInnenforEndringsperiode, + ), harPerioderFørTillattEndringsperiode: harPerioderFørEndringsperiode(arbeidstidPerioder, endringsperiode), harPerioderEtterTillattEndringsperiode: harPerioderEtterEndringsperiode(arbeidstidPerioder, endringsperiode), }; @@ -470,7 +529,7 @@ const getArbeidsaktivitetPerioderPart = ( */ const getArbeidsaktivitetArbeidstaker = ( arbeidstaker: K9SakArbeidstaker, - arbeidsgivere: Arbeidsgiver[], + arbeidsgivere: ArbeidsgiverMedAnsettelseperioder[], endringsperiode: DateRange, ): ArbeidsaktivitetArbeidstaker => { const { @@ -487,16 +546,39 @@ const getArbeidsaktivitetArbeidstaker = ( throw error; } const endringsperiodeForArbeidsgiver = getEndringsperiodeForArbeidsgiver(endringsperiode, arbeidsgiver); + const ansettelsesperioderInnenforEndringsperiode = ensureAnsettelsesperioderIsValidDateRange( + arbeidsgiver.ansettelsesperioder, + endringsperiode, + ); return { key: arbeidsgiver.key, arbeidsgiver, type: ArbeidsaktivitetType.arbeidstaker, navn: arbeidsgiver.navn, erUkjentArbeidsforhold: false, - ...getArbeidsaktivitetPerioderPart(perioder, endringsperiodeForArbeidsgiver), + ansettelsesperioderInnenforEndringsperiode, + ...getArbeidsaktivitetPerioderPart( + perioder, + endringsperiodeForArbeidsgiver, + ansettelsesperioderInnenforEndringsperiode, + ), }; }; +/** Går gjennom og endrer ansettelsesperioder til gyldig DateRange + * Bruker tillattEndringsperiode som erstatning hvis ansettelsesperiode mangler daga + */ + +const ensureAnsettelsesperioderIsValidDateRange = ( + ansettelsesperioder: MaybeDateRange[], + endringsperiode: DateRange, +): DateRange[] => { + return ansettelsesperioder.map((a) => ({ + from: a.from || endringsperiode.from, + to: a.to || endringsperiode.to, + })); +}; + /** * * @param frilanserArbeidstidInfo @@ -512,7 +594,8 @@ const getArbeidsaktivitetFrilanser = ( key: ArbeidsaktivitetType.frilanser, type: ArbeidsaktivitetType.frilanser, navn: 'Frilanser', - ...getArbeidsaktivitetPerioderPart(frilanserArbeidstidInfo.perioder, endringsperiode), + ansettelsesperioderInnenforEndringsperiode: [], // Brukes ikke for frilanser + ...getArbeidsaktivitetPerioderPart(frilanserArbeidstidInfo.perioder, endringsperiode, [endringsperiode]), } : undefined; }; @@ -532,30 +615,53 @@ const getArbeidsaktivitetSelvstendigNæringsdrivende = ( key: ArbeidsaktivitetType.selvstendigNæringsdrivende, type: ArbeidsaktivitetType.selvstendigNæringsdrivende, navn: 'Selvstendig næringsdrivende', - ...getArbeidsaktivitetPerioderPart(selvstendigNæringsdrivendeArbeidstidInfo.perioder, endringsperiode), + ansettelsesperioderInnenforEndringsperiode: [], // Brukes ikke for SN + ...getArbeidsaktivitetPerioderPart(selvstendigNæringsdrivendeArbeidstidInfo.perioder, endringsperiode, [ + endringsperiode, + ]), } : undefined; }; +/** + * Sjekker om en er ansatt hos arbeidsgiver innenfor søknadsperioder + * @param arbeidsgiver + * @param søknadsperioder + * @returns boolean + */ +const erArbeidsgiverInnenforSøknadsperioder = ( + arbeidsgiver: ArbeidsgiverMedAnsettelseperioder, + søknadsperioder: DateRange[], +): boolean => { + const { ansettelsesperioder = [] } = arbeidsgiver; + return ansettelsesperioder.some((ansettelsesperiode) => + erAnsattPeriodeInnenforSøknadsperioder(ansettelsesperiode, søknadsperioder), + ); +}; + /** * Sjekker om ansatt-periode hos arbeidsgiver er innenfor søknadsperioder * @param arbeidsgiver * @param søknadsperioder * @returns boolean */ -const erArbeidsgiverInnenforSøknadsperioder = (arbeidsgiver: Arbeidsgiver, søknadsperioder: DateRange[]): boolean => { +const erAnsattPeriodeInnenforSøknadsperioder = ( + ansettelsesperiode: MaybeDateRange, + søknadsperioder: DateRange[], +): boolean => { const sisteSøknadsdag = getLastDateInDateRanges(søknadsperioder); - if (!arbeidsgiver.ansattFom || !sisteSøknadsdag) { + + if (!ansettelsesperiode.from || !sisteSøknadsdag) { return false; } - if (!arbeidsgiver.ansattTom) { - return dayjs(arbeidsgiver.ansattFom).isSameOrBefore(sisteSøknadsdag); + if (!ansettelsesperiode.to) { + return dayjs(ansettelsesperiode.from).isSameOrBefore(sisteSøknadsdag); } - const ansattPeriode: DateRange = { - from: arbeidsgiver.ansattFom, - to: arbeidsgiver.ansattTom || sisteSøknadsdag, + const periode: DateRange = { + from: ansettelsesperiode.from, + to: ansettelsesperiode.to || sisteSøknadsdag, }; - return søknadsperioder.some((søknadsperiode) => dateRangesCollide([søknadsperiode, ansattPeriode])); + return søknadsperioder.some((søknadsperiode) => dateRangesCollide([søknadsperiode, periode])); }; /** @@ -604,4 +710,23 @@ export const _getSakFromK9Sak = { getArbeidsukeFromEnkeltdagerIUken, grupperArbeidstidPerioder, trimArbeidstidTilTillattEndringsperiode, + getDagerIkkeAnsattIPeriode, +}; + +const getArbeidsdagerInneforEndringsperiodeOgAnsettelsesperioder = ( + arbeidsdager: ArbeidstidEnkeltdagMap, + tillattEndringsperiode: DateRange, + ansettelsesperioderInnenforEndringsperiode: DateRange[], +) => { + const arbeidsdagerInnenforPerioder: ArbeidstidEnkeltdagMap = {}; + for (const [dato, info] of Object.entries(arbeidsdager)) { + const d = ISODateToDate(dato); + if ( + isDateInDateRange(d, tillattEndringsperiode) && + isDateInDateRanges(d, ansettelsesperioderInnenforEndringsperiode) + ) { + arbeidsdagerInnenforPerioder[dato] = info; + } + } + return arbeidsdagerInnenforPerioder; }; diff --git a/apps/endringsmelding-pleiepenger/src/app/utils/getSakOgArbeidsgivereDebugInfo.ts b/apps/endringsmelding-pleiepenger/src/app/utils/getSakOgArbeidsgivereDebugInfo.ts index c485c59835..6e05e46040 100644 --- a/apps/endringsmelding-pleiepenger/src/app/utils/getSakOgArbeidsgivereDebugInfo.ts +++ b/apps/endringsmelding-pleiepenger/src/app/utils/getSakOgArbeidsgivereDebugInfo.ts @@ -1,5 +1,5 @@ import { DateRange } from '@navikt/sif-common-utils'; -import { Arbeidsgiver, K9Sak, K9SakArbeidstaker, Sak } from '@types'; +import { ArbeidsgiverMedAnsettelseperioder, K9Sak, K9SakArbeidstaker, Sak } from '@types'; import { maskString } from './maskString'; @@ -40,10 +40,9 @@ const maskSak = (sak: Sak) => { }; }; -const maskArbeidsgivere = (arbeidsgivere: Arbeidsgiver[]) => { +const maskArbeidsgivere = (arbeidsgivere: ArbeidsgiverMedAnsettelseperioder[]) => { return arbeidsgivere.map((a) => ({ - ansattFom: a.ansattFom, - ansattTom: a.ansattTom, + ansettelsesperioder: a.ansettelsesperioder, a: maskString(a.key), })); }; @@ -51,7 +50,7 @@ const maskArbeidsgivere = (arbeidsgivere: Arbeidsgiver[]) => { export const getSakOgArbeidsgivereDebugInfo = ( k9sak: K9Sak, sak: Sak, - arbeidsgivere: Arbeidsgiver[], + arbeidsgivere: ArbeidsgiverMedAnsettelseperioder[], endringsperiode: DateRange, ) => { return { diff --git a/apps/endringsmelding-pleiepenger/src/app/utils/initialDataUtils.ts b/apps/endringsmelding-pleiepenger/src/app/utils/initialDataUtils.ts index 7943fbf04f..fd3034e9fe 100644 --- a/apps/endringsmelding-pleiepenger/src/app/utils/initialDataUtils.ts +++ b/apps/endringsmelding-pleiepenger/src/app/utils/initialDataUtils.ts @@ -1,5 +1,8 @@ -import { DateRange } from '@navikt/sif-common-utils'; +import { DateRange, ISODateToDate, MaybeDateRange } from '@navikt/sif-common-utils'; import dayjs from 'dayjs'; +import { ArbeidsgiverMedAnsettelseperioder } from '../types'; +import { getArbeidsgiverKey } from './arbeidsgiverUtils'; +import { AARegArbeidsgiverOrganisasjon } from '../api/endpoints/arbeidsgivereEndpoint'; export const getPeriodeForArbeidsgiverOppslag = ( dateRangeAlleSaker: DateRange, @@ -14,3 +17,28 @@ export const getPeriodeForArbeidsgiverOppslag = ( } return dateRange; }; + +export const getArbeidsgivereFromArbeidsgiverOrganisasjoner = ( + organisasjoner: AARegArbeidsgiverOrganisasjon[], +): ArbeidsgiverMedAnsettelseperioder[] => { + const aaArbeidsgivereMap = new Map(); + (organisasjoner || []).forEach((a) => { + const ansettelsesperiode: MaybeDateRange = { + from: a.ansattFom ? ISODateToDate(a.ansattFom) : undefined, + to: a.ansattTom ? ISODateToDate(a.ansattTom) : undefined, + }; + + if (aaArbeidsgivereMap.has(a.organisasjonsnummer)) { + aaArbeidsgivereMap.get(a.organisasjonsnummer)!.ansettelsesperioder!.push(ansettelsesperiode); + } else { + aaArbeidsgivereMap.set(a.organisasjonsnummer, { + key: getArbeidsgiverKey(a.organisasjonsnummer), + organisasjonsnummer: a.organisasjonsnummer, + navn: a.navn, + ansettelsesperioder: [ansettelsesperiode], + }); + } + }); + + return Array.from(aaArbeidsgivereMap.values()); +}; diff --git a/apps/endringsmelding-pleiepenger/src/app/utils/k9SakUtils.ts b/apps/endringsmelding-pleiepenger/src/app/utils/k9SakUtils.ts index 7ca7be4b32..88ced6093d 100644 --- a/apps/endringsmelding-pleiepenger/src/app/utils/k9SakUtils.ts +++ b/apps/endringsmelding-pleiepenger/src/app/utils/k9SakUtils.ts @@ -1,5 +1,5 @@ import { DateRange, dateRangeUtils, getDateRangeFromDateRanges } from '@navikt/sif-common-utils'; -import { Arbeidsgiver, K9Sak, K9SakArbeidstaker } from '@types'; +import { ArbeidsgiverMedAnsettelseperioder, K9Sak, K9SakArbeidstaker } from '@types'; import dayjs from 'dayjs'; import isSameOrAfter from 'dayjs/plugin/isSameOrAfter'; @@ -15,7 +15,7 @@ export const getSamletDateRangeForK9Saker = (saker: K9Sak[]): DateRange | undefi }; export const finnesArbeidsgiverIK9Sak = ( - arbeidsgiver: Arbeidsgiver, + arbeidsgiver: ArbeidsgiverMedAnsettelseperioder, arbeidsgivereISak: K9SakArbeidstaker[], ): boolean => { return arbeidsgivereISak.some( diff --git "a/apps/endringsmelding-pleiepenger/src/app/utils/s\303\270knadsdataToApiData/__tests__/getDataBruktTilUtledning.test.ts" "b/apps/endringsmelding-pleiepenger/src/app/utils/s\303\270knadsdataToApiData/__tests__/getDataBruktTilUtledning.test.ts" index e2baacbbfa..1bf630f16c 100644 --- "a/apps/endringsmelding-pleiepenger/src/app/utils/s\303\270knadsdataToApiData/__tests__/getDataBruktTilUtledning.test.ts" +++ "b/apps/endringsmelding-pleiepenger/src/app/utils/s\303\270knadsdataToApiData/__tests__/getDataBruktTilUtledning.test.ts" @@ -3,7 +3,7 @@ import { ISODateToDate } from '@navikt/sif-common-utils'; import { ArbeiderIPeriodenSvar, ArbeidsforholdAktivt, - Arbeidsgiver, + ArbeidsgiverMedAnsettelseperioder, ArbeidstidSøknadsdata, TimerEllerProsent, } from '../../../types'; @@ -32,12 +32,12 @@ describe('getDataBruktTilUtledningAnnetData', () => { }); describe('getUkjentArbeidsforholdApiDataFromSøknadsdata', () => { - const arbeidsgivere: Arbeidsgiver[] = [ + const arbeidsgivere: ArbeidsgiverMedAnsettelseperioder[] = [ { organisasjonsnummer: '123', key: 'a_123', navn: 'Arbeidsgibvernavn', - ansattFom: ISODateToDate('2001-01-01'), + ansettelsesperioder: [{ from: ISODateToDate('2001-01-01') }], }, ]; const arbeidstid: ArbeidstidSøknadsdata = { @@ -59,11 +59,11 @@ describe('getUkjentArbeidsforholdApiDataFromSøknadsdata', () => { }); describe('mapArbeidsforholdToArbeidsforholdApiData', () => { - const arbeidsgiver: Arbeidsgiver = { + const arbeidsgiver: ArbeidsgiverMedAnsettelseperioder = { organisasjonsnummer: '123', key: 'a_123', navn: 'Arbeidsgibvernavn', - ansattFom: ISODateToDate('2001-01-01'), + ansettelsesperioder: [{ from: ISODateToDate('2001-01-01') }], }; it('returnerer riktig hvis en ikke er ansatt i arbeidsforholdet', () => { diff --git "a/apps/endringsmelding-pleiepenger/src/app/utils/s\303\270knadsdataToApiData/getApiDataFromS\303\270knadsdata.ts" "b/apps/endringsmelding-pleiepenger/src/app/utils/s\303\270knadsdataToApiData/getApiDataFromS\303\270knadsdata.ts" index 8e527816b5..d496a53160 100644 --- "a/apps/endringsmelding-pleiepenger/src/app/utils/s\303\270knadsdataToApiData/getApiDataFromS\303\270knadsdata.ts" +++ "b/apps/endringsmelding-pleiepenger/src/app/utils/s\303\270knadsdataToApiData/getApiDataFromS\303\270knadsdata.ts" @@ -1,7 +1,8 @@ import { Locale } from '@navikt/sif-common-core-ds/src/types'; import { dateToISODate } from '@navikt/sif-common-utils'; -import { Arbeidsgiver, Sak, SøknadApiData, Søknadsdata, ValgteEndringer } from '@types'; +import { ArbeidsgiverMedAnsettelseperioder, Sak, SøknadApiData, Søknadsdata, ValgteEndringer } from '@types'; +import { getEndringsdato, getTillattEndringsperiode } from '../endringsperiode'; import { getArbeidstidApiDataFromSøknadsdata } from './getArbeidstidApiDataFromSøknadsdata'; import { getDataBruktTilUtledningAnnetDataApiData, getDataBruktTilUtledningApiData } from './getDataBruktTilUtledning'; import { getLovbestemtFerieApiDataFromSøknadsdata } from './getLovbestemtFerieApiDataFraSøknadsdata'; @@ -11,7 +12,7 @@ export const getApiDataFromSøknadsdata = ( søknadsdata: Søknadsdata, sak: Sak, valgteEndringer: ValgteEndringer, - arbeidsgivere: Arbeidsgiver[], + arbeidsgivere: ArbeidsgiverMedAnsettelseperioder[], locale: Locale, ): SøknadApiData | undefined => { const { id, arbeidstid, lovbestemtFerie, ukjentArbeidsforhold } = søknadsdata; @@ -34,6 +35,7 @@ export const getApiDataFromSøknadsdata = ( lovbestemtFerie: lovbestemtFerie ? getLovbestemtFerieApiDataFromSøknadsdata(lovbestemtFerie) : undefined, arbeidstid: arbeidstid ? getArbeidstidApiDataFromSøknadsdata( + getTillattEndringsperiode(getEndringsdato()), sak.søknadsperioder, arbeidstid.arbeidsaktivitet, sak.arbeidsaktiviteter, diff --git "a/apps/endringsmelding-pleiepenger/src/app/utils/s\303\270knadsdataToApiData/getArbeidstidApiDataFromS\303\270knadsdata.ts" "b/apps/endringsmelding-pleiepenger/src/app/utils/s\303\270knadsdataToApiData/getArbeidstidApiDataFromS\303\270knadsdata.ts" index 0f49fd198c..12966bdbd1 100644 --- "a/apps/endringsmelding-pleiepenger/src/app/utils/s\303\270knadsdataToApiData/getArbeidstidApiDataFromS\303\270knadsdata.ts" +++ "b/apps/endringsmelding-pleiepenger/src/app/utils/s\303\270knadsdataToApiData/getArbeidstidApiDataFromS\303\270knadsdata.ts" @@ -12,7 +12,7 @@ import { Arbeidsaktivitet, Arbeidsaktiviteter, ArbeidsaktivitetType, - Arbeidsgiver, + ArbeidsgiverMedAnsettelseperioder, ArbeidstakerApiData, ArbeidstidApiData, ArbeidstidArbeidsaktivitetMap, @@ -49,9 +49,9 @@ const getEndretArbeidstid = ( ): ArbeidstidPeriodeApiDataMap => { const perioderMedEndretArbeidstid: ArbeidstidPeriodeApiDataMap = {}; - const endringKeys = Object.keys(endringUkeMap).sort(); + const endringUkeKeys = Object.keys(endringUkeMap).sort(); - endringKeys.forEach((isoDateRange) => { + endringUkeKeys.forEach((isoDateRange) => { const endring = endringUkeMap[isoDateRange]; const arbeidsuker = getAlleArbeidsukerIPerioder(arbeidsaktivitet.perioderMedArbeidstid); const arbeidsuke = arbeidsuker[isoDateRange]; @@ -96,10 +96,11 @@ const getArbeidsaktivitetArbeidstidInfo = ( }; export const getArbeidstidApiDataFromSøknadsdata = ( + endringsperiode: DateRange, søknadsperioder: DateRange[], arbeidsaktivitetEndring: ArbeidstidArbeidsaktivitetMap, arbeidsaktiviteter: Arbeidsaktiviteter, - arbeidsgivereIkkeISak: Arbeidsgiver[], + arbeidsgivereIkkeISak: ArbeidsgiverMedAnsettelseperioder[], ukjentArbeidsforhold?: UkjentArbeidsforholdSøknadsdata, ): ArbeidstidApiData => { const frilansAktivitetEndring = arbeidsaktivitetEndring[ArbeidsaktivitetType.frilanser]?.endringer; @@ -149,6 +150,7 @@ export const getArbeidstidApiDataFromSøknadsdata = ( søknadsperioder, arbeidsgiver, arbeidsforhold, + endringsperiode, ); const arbeidsuker = getArbeidsukerIArbeidsaktivitet(arbeidsaktivitet); diff --git "a/apps/endringsmelding-pleiepenger/src/app/utils/s\303\270knadsdataToApiData/getDataBruktTilUtledning.ts" "b/apps/endringsmelding-pleiepenger/src/app/utils/s\303\270knadsdataToApiData/getDataBruktTilUtledning.ts" index 49af9c7ec7..09831e0df9 100644 --- "a/apps/endringsmelding-pleiepenger/src/app/utils/s\303\270knadsdataToApiData/getDataBruktTilUtledning.ts" +++ "b/apps/endringsmelding-pleiepenger/src/app/utils/s\303\270knadsdataToApiData/getDataBruktTilUtledning.ts" @@ -2,7 +2,7 @@ import { durationToISODuration } from '@navikt/sif-common-utils'; import { ArbeiderIPeriodenSvar, Arbeidsforhold, - Arbeidsgiver, + ArbeidsgiverMedAnsettelseperioder, ArbeidstidSøknadsdata, DataBruktTilUtledningApiData, DataBruktTilUtledningApiDataAnnetData as DataBruktTilUtledningAnnetDataApiData, @@ -16,7 +16,7 @@ import { getOrgNummerFromArbeidsgiverKey } from '../arbeidsgiverUtils'; export const getDataBruktTilUtledningApiData = ( ukjentArbeidsforhold: UkjentArbeidsforholdSøknadsdata | undefined, arbeidstid: ArbeidstidSøknadsdata | undefined, - arbeidsgivere: Arbeidsgiver[], + arbeidsgivere: ArbeidsgiverMedAnsettelseperioder[], ): DataBruktTilUtledningApiData => { return { ukjenteArbeidsforhold: getUkjentArbeidsforholdApiDataFromSøknadsdata( @@ -36,7 +36,7 @@ export const getDataBruktTilUtledningAnnetDataApiData = ( export const mapArbeidsforholdToArbeidsforholdApiData = ( arbeidsforhold: Arbeidsforhold, - arbeidsgiver: Arbeidsgiver, + arbeidsgiver: ArbeidsgiverMedAnsettelseperioder, arbeiderIPerioden?: ArbeiderIPeriodenSvar, ): UkjentArbeidsforholdApiData => { const organisasjonsnummer = getOrgNummerFromArbeidsgiverKey(arbeidsforhold.arbeidsgiverKey); @@ -64,7 +64,7 @@ export const mapArbeidsforholdToArbeidsforholdApiData = ( export const getUkjentArbeidsforholdApiDataFromSøknadsdata = ( ukjenteArbeidsforhold: Arbeidsforhold[] | undefined, arbeidstid: ArbeidstidSøknadsdata | undefined, - arbeidsgivere: Arbeidsgiver[], + arbeidsgivere: ArbeidsgiverMedAnsettelseperioder[], ): UkjentArbeidsforholdApiData[] => { if (ukjenteArbeidsforhold === undefined) { return []; diff --git a/apps/endringsmelding-pleiepenger/src/app/utils/tilgangskontroll.ts b/apps/endringsmelding-pleiepenger/src/app/utils/tilgangskontroll.ts index d4f1924936..a11de721f9 100644 --- a/apps/endringsmelding-pleiepenger/src/app/utils/tilgangskontroll.ts +++ b/apps/endringsmelding-pleiepenger/src/app/utils/tilgangskontroll.ts @@ -1,6 +1,6 @@ -import { DateRange, durationToDecimalDuration } from '@navikt/sif-common-utils'; +import { DateRange, durationToDecimalDuration, ensureDateRange, sortDateRange } from '@navikt/sif-common-utils'; import { - Arbeidsgiver, + ArbeidsgiverMedAnsettelseperioder, IngenTilgangÅrsak, K9Sak, K9SakArbeidstaker, @@ -27,7 +27,11 @@ type TilgangTillatt = { export type TilgangKontrollResultat = TilgangNektet | TilgangTillatt; -export const tilgangskontroll = (saker: K9Sak[], tillattEndringsperiode: DateRange): TilgangKontrollResultat => { +export const tilgangskontroll = ( + saker: K9Sak[], + tillattEndringsperiode: DateRange, + arbeidsgivere: ArbeidsgiverMedAnsettelseperioder[], +): TilgangKontrollResultat => { /** Har ingen saker */ if (saker.length === 0) { return { @@ -58,6 +62,16 @@ export const tilgangskontroll = (saker: K9Sak[], tillattEndringsperiode: DateRan ingenTilgangÅrsak.push(IngenTilgangÅrsak.harArbeidstidSomSelvstendigNæringsdrivende); } + /** Bruker har ansettelsperioder hos samme arbeidsgiver som starter og stopper samme uke, med opphold mellom */ + if (harAnsettelsesforholdSomStarterOgSlutterSammeUkeMedOpphold(sak, tillattEndringsperiode, arbeidsgivere)) { + ingenTilgangÅrsak.push(IngenTilgangÅrsak.enArbeidsgiverToAnsettelserSammeUkeMedOpphold); + } + + /** Bruker har flere ansettelsperioder hos ukjent arbeidsgiver */ + if (harFlereAnsettelsesforholdHosUkjentArbeidsgiver(arbeidsgivere, sak.ytelse.arbeidstid.arbeidstakerList)) { + ingenTilgangÅrsak.push(IngenTilgangÅrsak.harFlereAnsettelsesforholdHosUkjentArbeidsgiver); + } + if (ingenTilgangÅrsak.length > 0) { return { kanBrukeSøknad: false, @@ -92,12 +106,16 @@ const getIngenTilgangMeta = (arbeidstid: K9SakArbeidstid): IngenTilgangMeta => { }; }; -const harArbeidsgiverUtenArbeidsaktivitet = ( - arbeidsgivere: Arbeidsgiver[], +const harFlereAnsettelsesforholdHosUkjentArbeidsgiver = ( + arbeidsgivere: ArbeidsgiverMedAnsettelseperioder[], k9SakArbeidstaker: K9SakArbeidstaker[] = [], ): boolean => { return arbeidsgivere.some((arbeidsgiver) => { - return finnesArbeidsgiverIK9Sak(arbeidsgiver, k9SakArbeidstaker) === false; + const erUkjentArbeidsgiver = finnesArbeidsgiverIK9Sak(arbeidsgiver, k9SakArbeidstaker) === false; + if (!erUkjentArbeidsgiver) { + return false; + } + return arbeidsgiver.ansettelsesperioder.length > 1; }); }; @@ -115,8 +133,51 @@ const harSøknadsperiodeInnenforTillattEndringsperiode = ( : false; }; +const harAnsettelsesforholdSomStarterOgSlutterSammeUkeMedOpphold = ( + sak: K9Sak, + tillattEndringsperiode: DateRange, + arbeidsgivere: ArbeidsgiverMedAnsettelseperioder[], +): boolean => { + const orgnrISak = (sak.ytelse.arbeidstid.arbeidstakerList || []).map((a) => a.organisasjonsnummer); + return arbeidsgivere + .filter((a) => orgnrISak.includes(a.organisasjonsnummer)) + .some((arbeidsgiver) => { + const ansettelserInnenforEndringsperiode = arbeidsgiver.ansettelsesperioder.map((d) => + ensureDateRange(d, tillattEndringsperiode), + ); + return perioderSlutterOgStarterSammeUkeMedOpphold(ansettelserInnenforEndringsperiode); + }); +}; + +/** + * Går gjennom array for å se om det er perioder som slutter og starter innenfor samme + * uke, og hvor det er opphold på en dag mellom periodene. + * @param ansettelsesperioder DateRange + * @returns boolean + */ +const perioderSlutterOgStarterSammeUkeMedOpphold = (ansettelsesperioder: DateRange[]) => { + return ansettelsesperioder.sort(sortDateRange).some((periode, index) => { + if (index === 0) { + return false; + } + const forrigePeriode = ansettelsesperioder[index - 1]; + + /** Slutter og starter periodene innenfor samme uke */ + if (!dayjs(periode.from).isSame(dayjs(forrigePeriode.to), 'isoWeek')) { + return false; + } + /** Periodene er sammenhengende */ + if (dayjs(periode.from).diff(forrigePeriode.to, 'day') === 1) { + return false; + } + + return true; + }); +}; + export const tilgangskontrollUtils = { getIngenTilgangMeta, - harArbeidsgiverUtenArbeidsaktivitet, harSøknadsperiodeInnenforTillattEndringsperiode, + harFlereAnsettelsesforholdHosUkjentArbeidsgiver, + perioderSlutterOgStarterSammeUkeMedOpphold, }; diff --git a/apps/endringsmelding-pleiepenger/src/app/utils/ukjentArbeidsforholdUtils.ts b/apps/endringsmelding-pleiepenger/src/app/utils/ukjentArbeidsforholdUtils.ts index d2ecaf45e3..7b0a44accf 100644 --- a/apps/endringsmelding-pleiepenger/src/app/utils/ukjentArbeidsforholdUtils.ts +++ b/apps/endringsmelding-pleiepenger/src/app/utils/ukjentArbeidsforholdUtils.ts @@ -3,6 +3,7 @@ import { dateRangeToISODateRange, dateToISODate, Duration, + ensureDateRange, getDateRangeFromDateRanges, getDateRangesWithinDateRange, getDatesInDateRange, @@ -13,7 +14,7 @@ import { Arbeidsaktivitet, ArbeidsaktivitetType, ArbeidsforholdAktivt, - Arbeidsgiver, + ArbeidsgiverMedAnsettelseperioder, ArbeidstidEnkeltdagMap, ArbeidstidPerDag, ArbeidsukeMap, @@ -22,8 +23,9 @@ import { } from '@types'; import { ArbeidsaktivitetFormValuesMap } from '../søknad/steps/arbeidstid/ArbeidstidForm'; -import { getArbeidsukeFromEnkeltdagerIUken } from './arbeidsukeUtils'; +// import { getArbeidsukeFromEnkeltdagerIUken } from './arbeidsukeUtils'; import { beregnSnittTimerPerDag } from './beregnUtils'; +import { getArbeidsukeFromEnkeltdagerIUken } from './getSakFromK9Sak'; export const getSøknadsperioderForUkjentArbeidsforhold = ( søknadsperioder: DateRange[], @@ -31,6 +33,7 @@ export const getSøknadsperioderForUkjentArbeidsforhold = ( ansattTom: Date | undefined, ): DateRange[] => { const alleSøknadsperioder: DateRange = getDateRangeFromDateRanges(søknadsperioder); + /** TODO - sjekke denne opp mot flere ansattelsesperioder */ const ansettelsesperiode = { from: ansattFom || alleSøknadsperioder.from, to: ansattTom || alleSøknadsperioder.to, @@ -40,15 +43,16 @@ export const getSøknadsperioderForUkjentArbeidsforhold = ( export const getPerioderMedArbeidstidForUkjentArbeidsforhold = ( søknadsperioder: DateRange[], - { ansattFom, ansattTom }: Arbeidsgiver, + ansettelsesperiode: DateRange, normalarbeidstidPerUke: Duration, faktiskArbeidstidPerUke: Duration | undefined, ): PeriodeMedArbeidstid[] => { const søknadsperioderForArbeidsforhold = getSøknadsperioderForUkjentArbeidsforhold( søknadsperioder, - ansattFom, - ansattTom, + ansettelsesperiode.from, + ansettelsesperiode.to, ); + const perioderMedArbeidstid: PeriodeMedArbeidstid[] = []; const arbeidstidPerDag: ArbeidstidPerDag = { @@ -63,7 +67,9 @@ export const getPerioderMedArbeidstidForUkjentArbeidsforhold = ( getDatesInDateRange(uke, true).forEach((date) => { enkeldagerMap[dateToISODate(date)] = arbeidstidPerDag; }); - arbeidsuker[dateRangeToISODateRange(uke)] = getArbeidsukeFromEnkeltdagerIUken(uke, enkeldagerMap); + if (Object.keys(enkeldagerMap).length > 0) { + arbeidsuker[dateRangeToISODateRange(uke)] = getArbeidsukeFromEnkeltdagerIUken(uke, enkeldagerMap); + } }); perioderMedArbeidstid.push({ arbeidsuker, @@ -88,13 +94,27 @@ export const getFaktiskArbeidstidPerUkeForUkjentArbeidsforhold = ( } }; +/** + * Henter ut Arbeidsaktiviet for ukjent arbeidsforhold + * @param søknadsperioder Alle perioder som er søkt for + * @param arbeidsgiver Arbeidsgiveren det gjelder som ikke er registrert i sak + * @param arbeidsforhold Arbeidsforhold utledet tidligere - holder om en er ansatt eller ikke, og evt. normalarbeidstid. Hentes på eget steg + * @param endringsperiode tidsrommet som en kan gjøre endringer i + * @param arbeiderIPerioden om bruker sier en arbeider, arbeider delvis eller arbeider ikke i perioden + * @returns Arbeidsaktivitet + */ export const getArbeidsaktivitetForUkjentArbeidsforhold = ( søknadsperioder: DateRange[], - arbeidsgiver: Arbeidsgiver, + arbeidsgiver: ArbeidsgiverMedAnsettelseperioder, arbeidsforhold: ArbeidsforholdAktivt, + endringsperiode: DateRange, arbeiderIPerioden?: ArbeiderIPeriodenSvar, ): Arbeidsaktivitet => { const faktiskArbeidstid = getFaktiskArbeidstidPerUkeForUkjentArbeidsforhold(arbeidsforhold, arbeiderIPerioden); + if (arbeidsgiver.ansettelsesperioder.length !== 1) { + throw 'Ukjent arbeidsforhold kan kun ha en ansettelsesperiode'; + } + const ansettelsesperiode = ensureDateRange(arbeidsgiver.ansettelsesperioder[0], endringsperiode); const aktivitet: Arbeidsaktivitet = { key: arbeidsgiver.key, @@ -104,9 +124,10 @@ export const getArbeidsaktivitetForUkjentArbeidsforhold = ( navn: arbeidsgiver.navn, harPerioderEtterTillattEndringsperiode: false, harPerioderFørTillattEndringsperiode: false, + ansettelsesperioderInnenforEndringsperiode: [ansettelsesperiode], perioderMedArbeidstid: getPerioderMedArbeidstidForUkjentArbeidsforhold( søknadsperioder, - arbeidsgiver, + ansettelsesperiode, arbeidsforhold.normalarbeidstid.timerPerUke, faktiskArbeidstid, ), @@ -116,8 +137,9 @@ export const getArbeidsaktivitetForUkjentArbeidsforhold = ( export const getArbeidsaktiviteterForUkjenteArbeidsforhold = ( søknadsperioder: DateRange[], - arbeidsgivereIkkeISak: Arbeidsgiver[], + arbeidsgivereIkkeISak: ArbeidsgiverMedAnsettelseperioder[], arbeidsaktivitetFormValues: ArbeidsaktivitetFormValuesMap, + endringsperiode: DateRange, ukjentArbeidsforhold?: UkjentArbeidsforholdSøknadsdata, ): Arbeidsaktivitet[] => { const aktiviteter: Arbeidsaktivitet[] = []; @@ -135,6 +157,7 @@ export const getArbeidsaktiviteterForUkjenteArbeidsforhold = ( søknadsperioder, arbeidsgiver, arbeidsforhold, + endringsperiode, arbeiderIPerioden, ), ); diff --git a/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/arbeidsgiver-ikke-i-sak-flere-ansettelser/ArbeidsgiverIkkeISakFlereAnsettelser.ts b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/arbeidsgiver-ikke-i-sak-flere-ansettelser/ArbeidsgiverIkkeISakFlereAnsettelser.ts new file mode 100644 index 0000000000..acb4dd2797 --- /dev/null +++ b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/arbeidsgiver-ikke-i-sak-flere-ansettelser/ArbeidsgiverIkkeISakFlereAnsettelser.ts @@ -0,0 +1,10 @@ +import { ScenarioData } from '..'; +import arbeidsgiver from './arbeidsgiver-mock'; +import sak from './sak-mock'; +import søker from './søker-mock'; + +export const ArbeidsgiverIkkeISakFlereAnsettelser: ScenarioData = { + sak, + arbeidsgiver, + søker, +}; diff --git a/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/arbeidsgiver-ikke-i-sak-flere-ansettelser/arbeidsgiver-mock.ts b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/arbeidsgiver-ikke-i-sak-flere-ansettelser/arbeidsgiver-mock.ts new file mode 100644 index 0000000000..a45b295c82 --- /dev/null +++ b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/arbeidsgiver-ikke-i-sak-flere-ansettelser/arbeidsgiver-mock.ts @@ -0,0 +1,8 @@ +export default { + organisasjoner: [ + { navn: 'Dykkert svømmeutstyr', organisasjonsnummer: '947064649', ansattFom: '2008-10-01' }, + { navn: 'Vinge flyfly', organisasjonsnummer: '947064640', ansattFom: '2008-10-01' }, + { navn: 'IKKE-I-SAK-AS 1', organisasjonsnummer: '947064642', ansattFom: '2023-02-05', ansattTom: '2023-04-05' }, + { navn: 'IKKE-I-SAK-AS 1', organisasjonsnummer: '947064642', ansattFom: '2023-04-06' }, + ], +}; diff --git a/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/arbeidsgiver-ikke-i-sak-flere-ansettelser/sak-mock.ts b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/arbeidsgiver-ikke-i-sak-flere-ansettelser/sak-mock.ts new file mode 100644 index 0000000000..5f9c1a3f8f --- /dev/null +++ b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/arbeidsgiver-ikke-i-sak-flere-ansettelser/sak-mock.ts @@ -0,0 +1,343 @@ +export default [ + { + barn: { + fødselsdato: '2017-03-03', + fornavn: 'NORA', + mellomnavn: null, + etternavn: 'Nordmann', + aktørId: '2559652436225', + identitetsnummer: '03831799748', + }, + søknad: { + søknadId: 'generert', + versjon: '1.0.0.', + mottattDato: '2023-01-18T08:13:37.525Z', + søker: { norskIdentitetsnummer: '00000000000' }, + ytelse: { + type: 'PLEIEPENGER_SYKT_BARN', + barn: { norskIdentitetsnummer: '00000000000', fødselsdato: null }, + søknadsperiode: ['2022-01-01/2024-09-31'], + endringsperiode: [], + trekkKravPerioder: [], + opptjeningAktivitet: {}, + dataBruktTilUtledning: null, + infoFraPunsj: null, + bosteder: { perioder: {}, perioderSomSkalSlettes: {} }, + utenlandsopphold: { perioder: {}, perioderSomSkalSlettes: {} }, + beredskap: { perioder: {}, perioderSomSkalSlettes: {} }, + nattevåk: { perioder: {}, perioderSomSkalSlettes: {} }, + tilsynsordning: { + perioder: { + '2022-12-01/2023-01-31': { etablertTilsynTimerPerDag: 'PT8H' }, + '2023-02-14/2023-03-16': { etablertTilsynTimerPerDag: 'PT8H' }, + }, + }, + lovbestemtFerie: { + perioder: { + '2023-01-12/2023-01-15': { + skalHaFerie: false, + }, + }, + }, + arbeidstid: { + arbeidstakerList: [ + { + norskIdentitetsnummer: null, + organisasjonsnummer: '947064649', + arbeidstidInfo: { + perioder: { + '2022-01-01/2022-03-25': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-03-28/2022-04-01': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-04-04/2022-04-08': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-04-11/2022-04-15': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-04-18/2022-04-22': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-04-25/2022-04-29': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-05-02/2022-05-06': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-05-09/2022-05-13': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-05-16/2022-05-20': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-05-23/2022-05-27': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-05-30/2022-06-03': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-06-06/2022-06-10': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-06-13/2022-06-17': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-06-20/2022-06-24': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-06-27/2022-06-30': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-07-01/2022-07-01': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT7H30M', + }, + '2022-07-04/2022-07-07': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-07-08/2022-07-08': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT7H30M', + }, + '2022-07-11/2022-07-14': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-07-15/2022-07-15': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT7H30M', + }, + '2022-07-18/2022-07-21': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-07-22/2022-07-22': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT7H30M', + }, + '2022-07-25/2022-07-28': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-07-29/2022-07-29': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT7H30M', + }, + '2022-08-01/2022-08-04': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-08-05/2022-08-05': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT7H30M', + }, + '2022-08-08/2022-08-11': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-08-12/2022-08-12': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT7H30M', + }, + '2022-08-15/2022-08-18': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-08-19/2022-08-19': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT7H30M', + }, + '2022-08-22/2022-08-25': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-08-26/2022-08-26': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT7H30M', + }, + '2022-08-29/2022-08-31': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-09-01/2022-09-01': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT3H', + }, + '2022-09-02/2022-09-02': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT4H30M', + }, + '2022-09-05/2022-09-05': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-09-06/2022-09-06': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT2H30M', + }, + '2022-09-07/2022-09-08': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-09-09/2022-09-09': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT5H', + }, + '2022-09-12/2022-09-13': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-09-14/2022-09-14': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT4H', + }, + '2022-09-15/2022-09-15': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT3H30M', + }, + '2022-09-16/2022-09-16': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT7H30M', + }, + '2022-09-19/2022-09-22': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-09-23/2022-09-23': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT7H30M', + }, + '2022-09-26/2022-09-29': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2022-09-30/2022-09-30': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT7H30M', + }, + '2022-10-03/2024-12-30': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + }, + }, + }, + { + norskIdentitetsnummer: null, + organisasjonsnummer: '947064640', + arbeidstidInfo: { + perioder: { + '2022-09-01/2022-09-30': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2022-10-03/2022-12-30': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2023-01-01/2023-01-15': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + '2023-01-16/2023-03-12': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT4H30M', + }, + '2023-03-13/2023-09-31': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT1H30M', + }, + }, + }, + }, + ], + frilanserArbeidstidInfo: { + perioder: { + '2022-06-25/2022-12-31': { + jobberNormaltTimerPerDag: 'PT0S', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2023-01-02/2023-01-06': { + jobberNormaltTimerPerDag: 'PT3H', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2023-01-09/2023-01-13': { + jobberNormaltTimerPerDag: 'PT3H', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2023-01-16/2023-01-20': { + jobberNormaltTimerPerDag: 'PT3H', + faktiskArbeidTimerPerDag: 'PT3H', + }, + '2023-01-23/2023-01-27': { + jobberNormaltTimerPerDag: 'PT3H', + faktiskArbeidTimerPerDag: 'PT3H', + }, + '2023-01-30/2023-02-03': { + jobberNormaltTimerPerDag: 'PT3H', + faktiskArbeidTimerPerDag: 'PT3H', + }, + '2023-02-06/2023-02-10': { + jobberNormaltTimerPerDag: 'PT3H', + faktiskArbeidTimerPerDag: 'PT3H', + }, + '2023-02-13/2023-02-17': { + jobberNormaltTimerPerDag: 'PT3H', + faktiskArbeidTimerPerDag: 'PT3H', + }, + '2023-02-20/2023-02-24': { + jobberNormaltTimerPerDag: 'PT3H', + faktiskArbeidTimerPerDag: 'PT3H', + }, + '2023-02-27/2023-03-03': { + jobberNormaltTimerPerDag: 'PT3H', + faktiskArbeidTimerPerDag: 'PT3H', + }, + '2023-03-06/2023-03-10': { + jobberNormaltTimerPerDag: 'PT3H', + faktiskArbeidTimerPerDag: 'PT3H', + }, + '2023-03-13/2023-03-17': { + jobberNormaltTimerPerDag: 'PT3H', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2023-03-20/2023-03-24': { + jobberNormaltTimerPerDag: 'PT3H', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2023-03-27/2023-09-31': { + jobberNormaltTimerPerDag: 'PT3H', + faktiskArbeidTimerPerDag: 'PT0S', + }, + }, + }, + selvstendigNæringsdrivendeArbeidstidInfo: {}, + }, + uttak: { perioder: {} }, + omsorg: { relasjonTilBarnet: null, beskrivelseAvOmsorgsrollen: null }, + }, + språk: 'nb', + journalposter: [], + begrunnelseForInnsending: { tekst: null }, + }, + }, +]; diff --git "a/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/arbeidsgiver-ikke-i-sak-flere-ansettelser/s\303\270ker-mock.ts" "b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/arbeidsgiver-ikke-i-sak-flere-ansettelser/s\303\270ker-mock.ts" new file mode 100644 index 0000000000..2dd3e1c484 --- /dev/null +++ "b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/arbeidsgiver-ikke-i-sak-flere-ansettelser/s\303\270ker-mock.ts" @@ -0,0 +1,8 @@ +export default { + aktørId: '234', + fødselsnummer: '30086421581', + fødselsdato: '2001-02-01', + fornavn: 'NORA', + mellomnavn: null, + etternavn: 'KRONJUVEL', +}; diff --git a/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold/EnArbeidsgiverToAnsettelserSammeUkeMedOpphold.ts b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold/EnArbeidsgiverToAnsettelserSammeUkeMedOpphold.ts new file mode 100644 index 0000000000..64031f82f0 --- /dev/null +++ b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold/EnArbeidsgiverToAnsettelserSammeUkeMedOpphold.ts @@ -0,0 +1,10 @@ +import { ScenarioData } from '..'; +import arbeidsgiver from './arbeidsgiver-mock'; +import sak from './sak-mock'; +import søker from './søker-mock'; + +export const EnArbeidsgiverToAnsettelserSammeUkeMedOpphold: ScenarioData = { + sak, + arbeidsgiver, + søker, +}; diff --git a/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold/arbeidsgiver-mock.ts b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold/arbeidsgiver-mock.ts new file mode 100644 index 0000000000..a148bdd78a --- /dev/null +++ b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold/arbeidsgiver-mock.ts @@ -0,0 +1,18 @@ +export default { + organisasjoner: [ + { + organisasjonsnummer: '947064649', + navn: 'Norsk bedrift AS', + ansattFom: '2003-01-16', + ansattTom: '2022-01-11', + }, + { + organisasjonsnummer: '947064649', + navn: 'Norsk bedrift AS', + ansattFom: '2022-01-13', + ansattTom: null, + }, + ], + privateArbeidsgivere: null, + frilansoppdrag: null, +}; diff --git a/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold/sak-mock.ts b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold/sak-mock.ts new file mode 100644 index 0000000000..8b2cc9fe4d --- /dev/null +++ b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold/sak-mock.ts @@ -0,0 +1,114 @@ +export default [ + { + barn: { + fødselsdato: '2017-03-03', + fornavn: 'NORA', + mellomnavn: null, + etternavn: 'Nordmann', + aktørId: '2559652436225', + identitetsnummer: '03831799748', + }, + søknad: { + søknadId: 'generert', + versjon: '1.0.0.', + mottattDato: '2023-01-18T08:13:37.525Z', + søker: { norskIdentitetsnummer: '00000000000' }, + ytelse: { + type: 'PLEIEPENGER_SYKT_BARN', + barn: { norskIdentitetsnummer: '00000000000', fødselsdato: null }, + søknadsperiode: ['2022-12-01/2024-05-31'], + endringsperiode: [], + trekkKravPerioder: [], + opptjeningAktivitet: {}, + dataBruktTilUtledning: null, + infoFraPunsj: null, + bosteder: { perioder: {}, perioderSomSkalSlettes: {} }, + utenlandsopphold: { + perioder: { + '2018-12-30/2019-10-20': { + land: 'DNK', + årsak: 'barnetInnlagtIHelseinstitusjonForNorskOffentligRegning', + }, + }, + }, + beredskap: { perioder: {}, perioderSomSkalSlettes: {} }, + nattevåk: { perioder: {}, perioderSomSkalSlettes: {} }, + tilsynsordning: { + perioder: { + '2022-12-01/2023-01-31': { etablertTilsynTimerPerDag: 'PT8H' }, + '2023-02-14/2023-03-16': { etablertTilsynTimerPerDag: 'PT8H' }, + }, + }, + lovbestemtFerie: { + perioder: { + '2023-01-01/2023-01-10': { + skalHaFerie: true, + }, + '2023-01-12/2023-01-15': { + skalHaFerie: false, + }, + }, + }, + arbeidstid: { + arbeidstakerList: [ + { + norskIdentitetsnummer: null, + organisasjonsnummer: '947064649', + arbeidstidInfo: { + perioder: { + '2022-12-01/2022-12-02': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2022-12-05/2022-12-09': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2022-12-12/2022-12-16': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2022-12-19/2022-12-23': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2022-12-26/2022-12-30': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2023-01-02/2023-01-06': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2023-01-09/2023-01-13': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2023-01-16/2023-01-20': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2023-01-23/2023-01-27': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2023-01-30/2024-05-31': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + }, + }, + }, + ], + frilanserArbeidstidInfo: {}, + selvstendigNæringsdrivendeArbeidstidInfo: {}, + }, + uttak: { perioder: {} }, + omsorg: { relasjonTilBarnet: null, beskrivelseAvOmsorgsrollen: null }, + }, + språk: 'nb', + journalposter: [], + begrunnelseForInnsending: { tekst: null }, + }, + }, +]; diff --git "a/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold/s\303\270ker-mock.ts" "b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold/s\303\270ker-mock.ts" new file mode 100644 index 0000000000..b80d44748e --- /dev/null +++ "b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-med-opphold/s\303\270ker-mock.ts" @@ -0,0 +1,9 @@ +export default { + aktørId: '2486083225079', + fødselsdato: '1987-10-09', + fødselsnummer: '09908799647', + fornavn: 'NORA', + mellomnavn: null, + etternavn: 'Etternavn', + myndig: true, +}; diff --git a/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-uten-opphold/EnArbeidsgiverToAnsettelserSammeUkeUtenOpphold.ts b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-uten-opphold/EnArbeidsgiverToAnsettelserSammeUkeUtenOpphold.ts new file mode 100644 index 0000000000..579142c282 --- /dev/null +++ b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-uten-opphold/EnArbeidsgiverToAnsettelserSammeUkeUtenOpphold.ts @@ -0,0 +1,10 @@ +import { ScenarioData } from '..'; +import arbeidsgiver from './arbeidsgiver-mock'; +import sak from './sak-mock'; +import søker from './søker-mock'; + +export const EnArbeidsgiverToAnsettelserSammeUkeUtenOpphold: ScenarioData = { + sak, + arbeidsgiver, + søker, +}; diff --git a/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-uten-opphold/arbeidsgiver-mock.ts b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-uten-opphold/arbeidsgiver-mock.ts new file mode 100644 index 0000000000..049ad63a0c --- /dev/null +++ b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-uten-opphold/arbeidsgiver-mock.ts @@ -0,0 +1,18 @@ +export default { + organisasjoner: [ + { + organisasjonsnummer: '947064649', + navn: 'Norsk bedrift AS', + ansattFom: '2003-01-16', + ansattTom: '2022-12-05', + }, + { + organisasjonsnummer: '947064649', + navn: 'Norsk bedrift AS', + ansattFom: '2023-01-01', + ansattTom: null, + }, + ], + privateArbeidsgivere: null, + frilansoppdrag: null, +}; diff --git a/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-uten-opphold/sak-mock.ts b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-uten-opphold/sak-mock.ts new file mode 100644 index 0000000000..8b2cc9fe4d --- /dev/null +++ b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-uten-opphold/sak-mock.ts @@ -0,0 +1,114 @@ +export default [ + { + barn: { + fødselsdato: '2017-03-03', + fornavn: 'NORA', + mellomnavn: null, + etternavn: 'Nordmann', + aktørId: '2559652436225', + identitetsnummer: '03831799748', + }, + søknad: { + søknadId: 'generert', + versjon: '1.0.0.', + mottattDato: '2023-01-18T08:13:37.525Z', + søker: { norskIdentitetsnummer: '00000000000' }, + ytelse: { + type: 'PLEIEPENGER_SYKT_BARN', + barn: { norskIdentitetsnummer: '00000000000', fødselsdato: null }, + søknadsperiode: ['2022-12-01/2024-05-31'], + endringsperiode: [], + trekkKravPerioder: [], + opptjeningAktivitet: {}, + dataBruktTilUtledning: null, + infoFraPunsj: null, + bosteder: { perioder: {}, perioderSomSkalSlettes: {} }, + utenlandsopphold: { + perioder: { + '2018-12-30/2019-10-20': { + land: 'DNK', + årsak: 'barnetInnlagtIHelseinstitusjonForNorskOffentligRegning', + }, + }, + }, + beredskap: { perioder: {}, perioderSomSkalSlettes: {} }, + nattevåk: { perioder: {}, perioderSomSkalSlettes: {} }, + tilsynsordning: { + perioder: { + '2022-12-01/2023-01-31': { etablertTilsynTimerPerDag: 'PT8H' }, + '2023-02-14/2023-03-16': { etablertTilsynTimerPerDag: 'PT8H' }, + }, + }, + lovbestemtFerie: { + perioder: { + '2023-01-01/2023-01-10': { + skalHaFerie: true, + }, + '2023-01-12/2023-01-15': { + skalHaFerie: false, + }, + }, + }, + arbeidstid: { + arbeidstakerList: [ + { + norskIdentitetsnummer: null, + organisasjonsnummer: '947064649', + arbeidstidInfo: { + perioder: { + '2022-12-01/2022-12-02': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2022-12-05/2022-12-09': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2022-12-12/2022-12-16': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2022-12-19/2022-12-23': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2022-12-26/2022-12-30': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2023-01-02/2023-01-06': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2023-01-09/2023-01-13': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2023-01-16/2023-01-20': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2023-01-23/2023-01-27': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + '2023-01-30/2024-05-31': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT4H32M24S', + }, + }, + }, + }, + ], + frilanserArbeidstidInfo: {}, + selvstendigNæringsdrivendeArbeidstidInfo: {}, + }, + uttak: { perioder: {} }, + omsorg: { relasjonTilBarnet: null, beskrivelseAvOmsorgsrollen: null }, + }, + språk: 'nb', + journalposter: [], + begrunnelseForInnsending: { tekst: null }, + }, + }, +]; diff --git "a/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-uten-opphold/s\303\270ker-mock.ts" "b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-uten-opphold/s\303\270ker-mock.ts" new file mode 100644 index 0000000000..b80d44748e --- /dev/null +++ "b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/en-arbeidsgiver-to-ansettelser-samme-uke-uten-opphold/s\303\270ker-mock.ts" @@ -0,0 +1,9 @@ +export default { + aktørId: '2486083225079', + fødselsdato: '1987-10-09', + fødselsnummer: '09908799647', + fornavn: 'NORA', + mellomnavn: null, + etternavn: 'Etternavn', + myndig: true, +}; diff --git a/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/opphold/ikke-ansatt-mandag-midt-i/IkkeAnsattMandagMidt.ts b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/opphold/ikke-ansatt-mandag-midt-i/IkkeAnsattMandagMidt.ts new file mode 100644 index 0000000000..01172f41fa --- /dev/null +++ b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/opphold/ikke-ansatt-mandag-midt-i/IkkeAnsattMandagMidt.ts @@ -0,0 +1,10 @@ +import { ScenarioData } from '../../'; +import arbeidsgiver from './arbeidsgiver-mock'; +import sak from './sak-mock'; +import søker from './søker-mock'; + +export const IkkeAnsattMandagMidtI: ScenarioData = { + sak, + arbeidsgiver, + søker, +}; diff --git a/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/opphold/ikke-ansatt-mandag-midt-i/arbeidsgiver-mock.ts b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/opphold/ikke-ansatt-mandag-midt-i/arbeidsgiver-mock.ts new file mode 100644 index 0000000000..ec99dc2658 --- /dev/null +++ b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/opphold/ikke-ansatt-mandag-midt-i/arbeidsgiver-mock.ts @@ -0,0 +1,9 @@ +/** Første periode viser tom søndag 3.11, selv om en slutter før 1.11 */ +export default { + frilansoppdrag: [], + organisasjoner: [ + { ansattFom: '2005-01-09', ansattTom: '2024-11-01', navn: 'SAUEFABRIKK', organisasjonsnummer: '896929119' }, + { ansattFom: '2024-12-05', ansattTom: null, navn: 'SAUEFABRIKK', organisasjonsnummer: '896929119' }, + ], + privateArbeidsgivere: [], +}; diff --git a/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/opphold/ikke-ansatt-mandag-midt-i/sak-mock.ts b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/opphold/ikke-ansatt-mandag-midt-i/sak-mock.ts new file mode 100644 index 0000000000..23b0466153 --- /dev/null +++ b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/opphold/ikke-ansatt-mandag-midt-i/sak-mock.ts @@ -0,0 +1,104 @@ +export default [ + { + barn: { + fødselsdato: '2023-01-24', + fornavn: 'GEOMETRISK', + mellomnavn: null, + etternavn: 'RIST', + aktørId: '2487158514882', + identitetsnummer: '24412358038', + }, + søknad: { + søknadId: 'generert', + versjon: '1.0.0', + mottattDato: '2025-01-24T07:51:23.794Z', + søker: { + norskIdentitetsnummer: '00000000000', + }, + språk: 'nb', + ytelse: { + type: 'PLEIEPENGER_SYKT_BARN', + barn: { + norskIdentitetsnummer: '00000000000', + fødselsdato: null, + }, + søknadsperiode: ['2024-11-01/2025-02-28'], + endringsperiode: [], + trekkKravPerioder: [], + opptjeningAktivitet: {}, + dataBruktTilUtledning: null, + annetDataBruktTilUtledning: null, + infoFraPunsj: null, + bosteder: { + perioder: {}, + perioderSomSkalSlettes: {}, + }, + utenlandsopphold: { + perioder: {}, + perioderSomSkalSlettes: {}, + }, + beredskap: { + perioder: {}, + perioderSomSkalSlettes: {}, + }, + nattevåk: { + perioder: {}, + perioderSomSkalSlettes: {}, + }, + tilsynsordning: { + perioder: { + '2024-11-01/2025-02-28': { + etablertTilsynTimerPerDag: 'PT0S', + }, + }, + }, + lovbestemtFerie: { + perioder: {}, + }, + arbeidstid: { + arbeidstakerList: [ + { + norskIdentitetsnummer: null, + organisasjonsnummer: '896929119', + organisasjonsnavn: null, + arbeidstidInfo: { + perioder: { + '2024-11-01/2024-11-30': { + jobberNormaltTimerPerDag: 'PT7H30M', + faktiskArbeidTimerPerDag: 'PT0S', + }, + '2024-12-01/2025-02-28': { + jobberNormaltTimerPerDag: 'PT8H', + faktiskArbeidTimerPerDag: 'PT0S', + }, + }, + }, + }, + ], + frilanserArbeidstidInfo: { + perioder: { + '2024-11-01/2025-02-28': { + jobberNormaltTimerPerDag: 'PT0S', + faktiskArbeidTimerPerDag: 'PT0S', + }, + }, + }, + selvstendigNæringsdrivendeArbeidstidInfo: null, + }, + uttak: { + perioder: {}, + }, + omsorg: { + relasjonTilBarnet: null, + beskrivelseAvOmsorgsrollen: null, + }, + erSammenMedBarnet: null, + }, + journalposter: [], + begrunnelseForInnsending: { + tekst: null, + }, + kildesystem: null, + }, + }, +]; diff --git "a/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/opphold/ikke-ansatt-mandag-midt-i/s\303\270ker-mock.ts" "b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/opphold/ikke-ansatt-mandag-midt-i/s\303\270ker-mock.ts" new file mode 100644 index 0000000000..0921da2df9 --- /dev/null +++ "b/apps/endringsmelding-pleiepenger/src/mocks/data/scenario/opphold/ikke-ansatt-mandag-midt-i/s\303\270ker-mock.ts" @@ -0,0 +1,8 @@ +export default { + aktørId: '2912771641580', + etternavn: 'FJORD', + fornavn: 'TØFF', + fødselsdato: '1983-05-26', + fødselsnummer: '26458341337', + mellomnavn: null, +}; diff --git a/apps/endringsmelding-pleiepenger/src/storybook/data/arbeidsgivereMock.ts b/apps/endringsmelding-pleiepenger/src/storybook/data/arbeidsgivereMock.ts index 5c987052fa..d75de02677 100644 --- a/apps/endringsmelding-pleiepenger/src/storybook/data/arbeidsgivereMock.ts +++ b/apps/endringsmelding-pleiepenger/src/storybook/data/arbeidsgivereMock.ts @@ -1,16 +1,16 @@ -import { Arbeidsgiver } from '../../app/types/Arbeidsgiver'; +import { ArbeidsgiverMedAnsettelseperioder } from '../../app/types/ArbeidsgiverMedAnsettelseperioder'; -export const arbeidsgivereMock: Arbeidsgiver[] = [ +export const arbeidsgivereMock: ArbeidsgiverMedAnsettelseperioder[] = [ { key: 'a_805824352', navn: 'Dykkert svømmeutstyr', organisasjonsnummer: '805824352', - ansattFom: new Date('2008-10-01'), + ansettelsesperioder: [{ from: new Date('2008-10-01') }], }, { key: 'a_839942907', navn: 'Flaks og fly', organisasjonsnummer: '839942907', - ansattFom: new Date('2008-10-01'), + ansettelsesperioder: [{ from: new Date('2008-10-01') }], }, ]; diff --git a/apps/endringsmelding-pleiepenger/src/storybook/data/sakMock.ts b/apps/endringsmelding-pleiepenger/src/storybook/data/sakMock.ts index 1a32ad2d86..f781c87b5f 100644 --- a/apps/endringsmelding-pleiepenger/src/storybook/data/sakMock.ts +++ b/apps/endringsmelding-pleiepenger/src/storybook/data/sakMock.ts @@ -9,13 +9,13 @@ export const sakMock: Sak = { key: 'a_947064642', organisasjonsnummer: '947064642', navn: 'IKKE-I-SAK-AS 1', - ansattFom: new Date('2023-02-01T00:00:00.000Z'), + ansettelsesperioder: [{ from: new Date('2023-02-01T00:00:00.000Z') }], }, { key: 'a_947064643', organisasjonsnummer: '947064643', navn: 'IKKE-I-SAK-AS 2', - ansattFom: new Date('2023-02-01T00:00:00.000Z'), + ansettelsesperioder: [{ from: new Date('2023-02-01T00:00:00.000Z') }], }, ], harArbeidsgivereIkkeISak: false, @@ -49,11 +49,14 @@ export const sakMock: Sak = { key: 'a_839942907', organisasjonsnummer: '839942907', navn: 'HÅRREISENDE FRISØR', - ansattFom: new Date('2002-05-09T00:00:00.000Z'), + ansettelsesperioder: [{ from: new Date('2002-05-09T00:00:00.000Z') }], }, type: ArbeidsaktivitetType.arbeidstaker, navn: 'HÅRREISENDE FRISØR', erUkjentArbeidsforhold: false, + ansettelsesperioderInnenforEndringsperiode: [ + { from: new Date('2002-05-09T00:00:00.000Z'), to: new Date('2025-05-09T00:00:00.000Z') }, + ], perioderMedArbeidstid: [ { from: new Date('2024-02-26T00:00:00.000Z'), @@ -65,6 +68,7 @@ export const sakMock: Sak = { from: new Date('2024-02-26T00:00:00.000Z'), to: new Date('2024-02-29T00:00:00.000Z'), }, + dagerSøktFor: [], arbeidstidEnkeltdager: { '2024-02-26': { faktisk: { @@ -141,6 +145,7 @@ export const sakMock: Sak = { from: new Date('2024-03-25T00:00:00.000Z'), to: new Date('2024-03-31T00:00:00.000Z'), }, + dagerSøktFor: [], arbeidstidEnkeltdager: { '2024-03-25': { faktisk: { @@ -221,6 +226,7 @@ export const sakMock: Sak = { from: new Date('2024-04-01T00:00:00.000Z'), to: new Date('2024-04-07T00:00:00.000Z'), }, + dagerSøktFor: [], arbeidstidEnkeltdager: { '2024-04-01': { faktisk: { @@ -301,6 +307,7 @@ export const sakMock: Sak = { from: new Date('2024-04-08T00:00:00.000Z'), to: new Date('2024-04-14T00:00:00.000Z'), }, + dagerSøktFor: [], arbeidstidEnkeltdager: { '2024-04-08': { faktisk: { @@ -381,6 +388,7 @@ export const sakMock: Sak = { from: new Date('2024-04-15T00:00:00.000Z'), to: new Date('2024-04-21T00:00:00.000Z'), }, + dagerSøktFor: [], arbeidstidEnkeltdager: { '2024-04-15': { faktisk: { @@ -461,6 +469,7 @@ export const sakMock: Sak = { from: new Date('2024-04-22T00:00:00.000Z'), to: new Date('2024-04-28T00:00:00.000Z'), }, + dagerSøktFor: [], arbeidstidEnkeltdager: { '2024-04-22': { faktisk: { @@ -541,6 +550,7 @@ export const sakMock: Sak = { from: new Date('2024-04-29T00:00:00.000Z'), to: new Date('2024-05-05T00:00:00.000Z'), }, + dagerSøktFor: [], arbeidstidEnkeltdager: { '2024-04-29': { faktisk: { @@ -621,6 +631,7 @@ export const sakMock: Sak = { from: new Date('2024-05-06T00:00:00.000Z'), to: new Date('2024-05-12T00:00:00.000Z'), }, + dagerSøktFor: [], arbeidstidEnkeltdager: { '2024-05-06': { faktisk: { @@ -701,6 +712,7 @@ export const sakMock: Sak = { from: new Date('2024-05-13T00:00:00.000Z'), to: new Date('2024-05-19T00:00:00.000Z'), }, + dagerSøktFor: [], arbeidstidEnkeltdager: { '2024-05-13': { faktisk: { @@ -781,6 +793,7 @@ export const sakMock: Sak = { from: new Date('2024-05-20T00:00:00.000Z'), to: new Date('2024-05-26T00:00:00.000Z'), }, + dagerSøktFor: [], arbeidstidEnkeltdager: { '2024-05-20': { faktisk: { @@ -861,6 +874,7 @@ export const sakMock: Sak = { from: new Date('2024-05-27T00:00:00.000Z'), to: new Date('2024-05-31T00:00:00.000Z'), }, + dagerSøktFor: [], arbeidstidEnkeltdager: { '2024-05-27': { faktisk: { @@ -946,6 +960,9 @@ export const sakMock: Sak = { key: 'selvstendigNæringsdrivende', type: ArbeidsaktivitetType.selvstendigNæringsdrivende, navn: 'Selvstendig næringsdrivende', + ansettelsesperioderInnenforEndringsperiode: [ + { from: new Date('2024-04-08T00:00:00.000Z'), to: new Date('2024-04-09T00:00:00.000Z') }, + ], perioderMedArbeidstid: [ { from: new Date('2024-04-08T00:00:00.000Z'), @@ -957,6 +974,7 @@ export const sakMock: Sak = { from: new Date('2024-04-08T00:00:00.000Z'), to: new Date('2024-04-09T00:00:00.000Z'), }, + dagerSøktFor: [], arbeidstidEnkeltdager: { '2024-04-08': { faktisk: { @@ -1030,11 +1048,14 @@ export const sakMock: Sak = { key: 'a_839942907', organisasjonsnummer: '839942907', navn: 'HÅRREISENDE FRISØR', - ansattFom: new Date('2002-05-09T00:00:00.000Z'), + ansettelsesperioder: [{ from: new Date('2002-05-09T00:00:00.000Z') }], }, type: ArbeidsaktivitetType.arbeidstaker, navn: 'HÅRREISENDE FRISØR', erUkjentArbeidsforhold: false, + ansettelsesperioderInnenforEndringsperiode: [ + { from: new Date('2002-05-09T00:00:00.000Z'), to: new Date('2025-05-09T00:00:00.000Z') }, + ], perioderMedArbeidstid: [ { from: new Date('2024-02-26T00:00:00.000Z'), @@ -1046,6 +1067,7 @@ export const sakMock: Sak = { from: new Date('2024-02-26T00:00:00.000Z'), to: new Date('2024-02-29T00:00:00.000Z'), }, + dagerSøktFor: [], arbeidstidEnkeltdager: { '2024-02-26': { faktisk: { @@ -1122,6 +1144,7 @@ export const sakMock: Sak = { from: new Date('2024-03-25T00:00:00.000Z'), to: new Date('2024-03-31T00:00:00.000Z'), }, + dagerSøktFor: [], arbeidstidEnkeltdager: { '2024-03-25': { faktisk: { @@ -1202,6 +1225,7 @@ export const sakMock: Sak = { from: new Date('2024-04-01T00:00:00.000Z'), to: new Date('2024-04-07T00:00:00.000Z'), }, + dagerSøktFor: [], arbeidstidEnkeltdager: { '2024-04-01': { faktisk: { @@ -1282,6 +1306,7 @@ export const sakMock: Sak = { from: new Date('2024-04-08T00:00:00.000Z'), to: new Date('2024-04-14T00:00:00.000Z'), }, + dagerSøktFor: [], arbeidstidEnkeltdager: { '2024-04-08': { faktisk: { @@ -1362,6 +1387,7 @@ export const sakMock: Sak = { from: new Date('2024-04-15T00:00:00.000Z'), to: new Date('2024-04-21T00:00:00.000Z'), }, + dagerSøktFor: [], arbeidstidEnkeltdager: { '2024-04-15': { faktisk: { @@ -1442,6 +1468,7 @@ export const sakMock: Sak = { from: new Date('2024-04-22T00:00:00.000Z'), to: new Date('2024-04-28T00:00:00.000Z'), }, + dagerSøktFor: [], arbeidstidEnkeltdager: { '2024-04-22': { faktisk: { @@ -1522,6 +1549,7 @@ export const sakMock: Sak = { from: new Date('2024-04-29T00:00:00.000Z'), to: new Date('2024-05-05T00:00:00.000Z'), }, + dagerSøktFor: [], arbeidstidEnkeltdager: { '2024-04-29': { faktisk: { @@ -1602,6 +1630,7 @@ export const sakMock: Sak = { from: new Date('2024-05-06T00:00:00.000Z'), to: new Date('2024-05-12T00:00:00.000Z'), }, + dagerSøktFor: [], arbeidstidEnkeltdager: { '2024-05-06': { faktisk: { @@ -1682,6 +1711,7 @@ export const sakMock: Sak = { from: new Date('2024-05-13T00:00:00.000Z'), to: new Date('2024-05-19T00:00:00.000Z'), }, + dagerSøktFor: [], arbeidstidEnkeltdager: { '2024-05-13': { faktisk: { @@ -1762,6 +1792,7 @@ export const sakMock: Sak = { from: new Date('2024-05-20T00:00:00.000Z'), to: new Date('2024-05-26T00:00:00.000Z'), }, + dagerSøktFor: [], arbeidstidEnkeltdager: { '2024-05-20': { faktisk: { @@ -1842,6 +1873,7 @@ export const sakMock: Sak = { from: new Date('2024-05-27T00:00:00.000Z'), to: new Date('2024-05-31T00:00:00.000Z'), }, + dagerSøktFor: [], arbeidstidEnkeltdager: { '2024-05-27': { faktisk: { @@ -1926,6 +1958,9 @@ export const sakMock: Sak = { key: 'selvstendigNæringsdrivende', type: ArbeidsaktivitetType.selvstendigNæringsdrivende, navn: 'Selvstendig næringsdrivende', + ansettelsesperioderInnenforEndringsperiode: [ + { from: new Date('2024-04-08T00:00:00.000Z'), to: new Date('2024-04-09T00:00:00.000Z') }, + ], perioderMedArbeidstid: [ { from: new Date('2024-04-08T00:00:00.000Z'), @@ -1937,6 +1972,7 @@ export const sakMock: Sak = { from: new Date('2024-04-08T00:00:00.000Z'), to: new Date('2024-04-09T00:00:00.000Z'), }, + dagerSøktFor: [], arbeidstidEnkeltdager: { '2024-04-08': { faktisk: { diff --git a/apps/omsorgsdager-aleneomsorg-dialog/mockServiceWorker.js b/apps/omsorgsdager-aleneomsorg-dialog/mockServiceWorker.js index be4527c7ee..fff922cccf 100644 --- a/apps/omsorgsdager-aleneomsorg-dialog/mockServiceWorker.js +++ b/apps/omsorgsdager-aleneomsorg-dialog/mockServiceWorker.js @@ -7,160 +7,157 @@ * - Please do NOT modify this file. */ -const PACKAGE_VERSION = '2.10.4' -const INTEGRITY_CHECKSUM = 'f5825c521429caf22a4dd13b66e243af' -const IS_MOCKED_RESPONSE = Symbol('isMockedResponse') -const activeClientIds = new Set() +const PACKAGE_VERSION = '2.10.4'; +const INTEGRITY_CHECKSUM = 'f5825c521429caf22a4dd13b66e243af'; +const IS_MOCKED_RESPONSE = Symbol('isMockedResponse'); +const activeClientIds = new Set(); addEventListener('install', function () { - self.skipWaiting() -}) + self.skipWaiting(); +}); addEventListener('activate', function (event) { - event.waitUntil(self.clients.claim()) -}) + event.waitUntil(self.clients.claim()); +}); addEventListener('message', async function (event) { - const clientId = Reflect.get(event.source || {}, 'id') + const clientId = Reflect.get(event.source || {}, 'id'); - if (!clientId || !self.clients) { - return - } - - const client = await self.clients.get(clientId) - - if (!client) { - return - } + if (!clientId || !self.clients) { + return; + } - const allClients = await self.clients.matchAll({ - type: 'window', - }) + const client = await self.clients.get(clientId); - switch (event.data) { - case 'KEEPALIVE_REQUEST': { - sendToClient(client, { - type: 'KEEPALIVE_RESPONSE', - }) - break + if (!client) { + return; } - case 'INTEGRITY_CHECK_REQUEST': { - sendToClient(client, { - type: 'INTEGRITY_CHECK_RESPONSE', - payload: { - packageVersion: PACKAGE_VERSION, - checksum: INTEGRITY_CHECKSUM, - }, - }) - break + const allClients = await self.clients.matchAll({ + type: 'window', + }); + + switch (event.data) { + case 'KEEPALIVE_REQUEST': { + sendToClient(client, { + type: 'KEEPALIVE_RESPONSE', + }); + break; + } + + case 'INTEGRITY_CHECK_REQUEST': { + sendToClient(client, { + type: 'INTEGRITY_CHECK_RESPONSE', + payload: { + packageVersion: PACKAGE_VERSION, + checksum: INTEGRITY_CHECKSUM, + }, + }); + break; + } + + case 'MOCK_ACTIVATE': { + activeClientIds.add(clientId); + + sendToClient(client, { + type: 'MOCKING_ENABLED', + payload: { + client: { + id: client.id, + frameType: client.frameType, + }, + }, + }); + break; + } + + case 'MOCK_DEACTIVATE': { + activeClientIds.delete(clientId); + break; + } + + case 'CLIENT_CLOSED': { + activeClientIds.delete(clientId); + + const remainingClients = allClients.filter((client) => { + return client.id !== clientId; + }); + + // Unregister itself when there are no more clients + if (remainingClients.length === 0) { + self.registration.unregister(); + } + + break; + } } +}); - case 'MOCK_ACTIVATE': { - activeClientIds.add(clientId) - - sendToClient(client, { - type: 'MOCKING_ENABLED', - payload: { - client: { - id: client.id, - frameType: client.frameType, - }, - }, - }) - break +addEventListener('fetch', function (event) { + // Bypass navigation requests. + if (event.request.mode === 'navigate') { + return; } - case 'MOCK_DEACTIVATE': { - activeClientIds.delete(clientId) - break + // Opening the DevTools triggers the "only-if-cached" request + // that cannot be handled by the worker. Bypass such requests. + if (event.request.cache === 'only-if-cached' && event.request.mode !== 'same-origin') { + return; } - case 'CLIENT_CLOSED': { - activeClientIds.delete(clientId) - - const remainingClients = allClients.filter((client) => { - return client.id !== clientId - }) - - // Unregister itself when there are no more clients - if (remainingClients.length === 0) { - self.registration.unregister() - } - - break + // Bypass all requests when there are no active clients. + // Prevents the self-unregistered worked from handling requests + // after it's been deleted (still remains active until the next reload). + if (activeClientIds.size === 0) { + return; } - } -}) -addEventListener('fetch', function (event) { - // Bypass navigation requests. - if (event.request.mode === 'navigate') { - return - } - - // Opening the DevTools triggers the "only-if-cached" request - // that cannot be handled by the worker. Bypass such requests. - if ( - event.request.cache === 'only-if-cached' && - event.request.mode !== 'same-origin' - ) { - return - } - - // Bypass all requests when there are no active clients. - // Prevents the self-unregistered worked from handling requests - // after it's been deleted (still remains active until the next reload). - if (activeClientIds.size === 0) { - return - } - - const requestId = crypto.randomUUID() - event.respondWith(handleRequest(event, requestId)) -}) + const requestId = crypto.randomUUID(); + event.respondWith(handleRequest(event, requestId)); +}); /** * @param {FetchEvent} event * @param {string} requestId */ async function handleRequest(event, requestId) { - const client = await resolveMainClient(event) - const requestCloneForEvents = event.request.clone() - const response = await getResponse(event, client, requestId) - - // Send back the response clone for the "response:*" life-cycle events. - // Ensure MSW is active and ready to handle the message, otherwise - // this message will pend indefinitely. - if (client && activeClientIds.has(client.id)) { - const serializedRequest = await serializeRequest(requestCloneForEvents) - - // Clone the response so both the client and the library could consume it. - const responseClone = response.clone() - - sendToClient( - client, - { - type: 'RESPONSE', - payload: { - isMockedResponse: IS_MOCKED_RESPONSE in response, - request: { - id: requestId, - ...serializedRequest, - }, - response: { - type: responseClone.type, - status: responseClone.status, - statusText: responseClone.statusText, - headers: Object.fromEntries(responseClone.headers.entries()), - body: responseClone.body, - }, - }, - }, - responseClone.body ? [serializedRequest.body, responseClone.body] : [], - ) - } + const client = await resolveMainClient(event); + const requestCloneForEvents = event.request.clone(); + const response = await getResponse(event, client, requestId); + + // Send back the response clone for the "response:*" life-cycle events. + // Ensure MSW is active and ready to handle the message, otherwise + // this message will pend indefinitely. + if (client && activeClientIds.has(client.id)) { + const serializedRequest = await serializeRequest(requestCloneForEvents); + + // Clone the response so both the client and the library could consume it. + const responseClone = response.clone(); + + sendToClient( + client, + { + type: 'RESPONSE', + payload: { + isMockedResponse: IS_MOCKED_RESPONSE in response, + request: { + id: requestId, + ...serializedRequest, + }, + response: { + type: responseClone.type, + status: responseClone.status, + statusText: responseClone.statusText, + headers: Object.fromEntries(responseClone.headers.entries()), + body: responseClone.body, + }, + }, + }, + responseClone.body ? [serializedRequest.body, responseClone.body] : [], + ); + } - return response + return response; } /** @@ -172,30 +169,30 @@ async function handleRequest(event, requestId) { * @returns {Promise} */ async function resolveMainClient(event) { - const client = await self.clients.get(event.clientId) - - if (activeClientIds.has(event.clientId)) { - return client - } - - if (client?.frameType === 'top-level') { - return client - } - - const allClients = await self.clients.matchAll({ - type: 'window', - }) - - return allClients - .filter((client) => { - // Get only those clients that are currently visible. - return client.visibilityState === 'visible' - }) - .find((client) => { - // Find the client ID that's recorded in the - // set of clients that have registered the worker. - return activeClientIds.has(client.id) - }) + const client = await self.clients.get(event.clientId); + + if (activeClientIds.has(event.clientId)) { + return client; + } + + if (client?.frameType === 'top-level') { + return client; + } + + const allClients = await self.clients.matchAll({ + type: 'window', + }); + + return allClients + .filter((client) => { + // Get only those clients that are currently visible. + return client.visibilityState === 'visible'; + }) + .find((client) => { + // Find the client ID that's recorded in the + // set of clients that have registered the worker. + return activeClientIds.has(client.id); + }); } /** @@ -205,73 +202,71 @@ async function resolveMainClient(event) { * @returns {Promise} */ async function getResponse(event, client, requestId) { - // Clone the request because it might've been already used - // (i.e. its body has been read and sent to the client). - const requestClone = event.request.clone() - - function passthrough() { - // Cast the request headers to a new Headers instance - // so the headers can be manipulated with. - const headers = new Headers(requestClone.headers) - - // Remove the "accept" header value that marked this request as passthrough. - // This prevents request alteration and also keeps it compliant with the - // user-defined CORS policies. - const acceptHeader = headers.get('accept') - if (acceptHeader) { - const values = acceptHeader.split(',').map((value) => value.trim()) - const filteredValues = values.filter( - (value) => value !== 'msw/passthrough', - ) - - if (filteredValues.length > 0) { - headers.set('accept', filteredValues.join(', ')) - } else { - headers.delete('accept') - } + // Clone the request because it might've been already used + // (i.e. its body has been read and sent to the client). + const requestClone = event.request.clone(); + + function passthrough() { + // Cast the request headers to a new Headers instance + // so the headers can be manipulated with. + const headers = new Headers(requestClone.headers); + + // Remove the "accept" header value that marked this request as passthrough. + // This prevents request alteration and also keeps it compliant with the + // user-defined CORS policies. + const acceptHeader = headers.get('accept'); + if (acceptHeader) { + const values = acceptHeader.split(',').map((value) => value.trim()); + const filteredValues = values.filter((value) => value !== 'msw/passthrough'); + + if (filteredValues.length > 0) { + headers.set('accept', filteredValues.join(', ')); + } else { + headers.delete('accept'); + } + } + + return fetch(requestClone, { headers }); } - return fetch(requestClone, { headers }) - } - - // Bypass mocking when the client is not active. - if (!client) { - return passthrough() - } - - // Bypass initial page load requests (i.e. static assets). - // The absence of the immediate/parent client in the map of the active clients - // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet - // and is not ready to handle requests. - if (!activeClientIds.has(client.id)) { - return passthrough() - } - - // Notify the client that a request has been intercepted. - const serializedRequest = await serializeRequest(event.request) - const clientMessage = await sendToClient( - client, - { - type: 'REQUEST', - payload: { - id: requestId, - ...serializedRequest, - }, - }, - [serializedRequest.body], - ) - - switch (clientMessage.type) { - case 'MOCK_RESPONSE': { - return respondWithMock(clientMessage.data) + // Bypass mocking when the client is not active. + if (!client) { + return passthrough(); } - case 'PASSTHROUGH': { - return passthrough() + // Bypass initial page load requests (i.e. static assets). + // The absence of the immediate/parent client in the map of the active clients + // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet + // and is not ready to handle requests. + if (!activeClientIds.has(client.id)) { + return passthrough(); + } + + // Notify the client that a request has been intercepted. + const serializedRequest = await serializeRequest(event.request); + const clientMessage = await sendToClient( + client, + { + type: 'REQUEST', + payload: { + id: requestId, + ...serializedRequest, + }, + }, + [serializedRequest.body], + ); + + switch (clientMessage.type) { + case 'MOCK_RESPONSE': { + return respondWithMock(clientMessage.data); + } + + case 'PASSTHROUGH': { + return passthrough(); + } } - } - return passthrough() + return passthrough(); } /** @@ -281,22 +276,19 @@ async function getResponse(event, client, requestId) { * @returns {Promise} */ function sendToClient(client, message, transferrables = []) { - return new Promise((resolve, reject) => { - const channel = new MessageChannel() + return new Promise((resolve, reject) => { + const channel = new MessageChannel(); - channel.port1.onmessage = (event) => { - if (event.data && event.data.error) { - return reject(event.data.error) - } + channel.port1.onmessage = (event) => { + if (event.data && event.data.error) { + return reject(event.data.error); + } - resolve(event.data) - } + resolve(event.data); + }; - client.postMessage(message, [ - channel.port2, - ...transferrables.filter(Boolean), - ]) - }) + client.postMessage(message, [channel.port2, ...transferrables.filter(Boolean)]); + }); } /** @@ -304,41 +296,41 @@ function sendToClient(client, message, transferrables = []) { * @returns {Response} */ function respondWithMock(response) { - // Setting response status code to 0 is a no-op. - // However, when responding with a "Response.error()", the produced Response - // instance will have status code set to 0. Since it's not possible to create - // a Response instance with status code 0, handle that use-case separately. - if (response.status === 0) { - return Response.error() - } - - const mockedResponse = new Response(response.body, response) - - Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, { - value: true, - enumerable: true, - }) - - return mockedResponse + // Setting response status code to 0 is a no-op. + // However, when responding with a "Response.error()", the produced Response + // instance will have status code set to 0. Since it's not possible to create + // a Response instance with status code 0, handle that use-case separately. + if (response.status === 0) { + return Response.error(); + } + + const mockedResponse = new Response(response.body, response); + + Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, { + value: true, + enumerable: true, + }); + + return mockedResponse; } /** * @param {Request} request */ async function serializeRequest(request) { - return { - url: request.url, - mode: request.mode, - method: request.method, - headers: Object.fromEntries(request.headers.entries()), - cache: request.cache, - credentials: request.credentials, - destination: request.destination, - integrity: request.integrity, - redirect: request.redirect, - referrer: request.referrer, - referrerPolicy: request.referrerPolicy, - body: await request.arrayBuffer(), - keepalive: request.keepalive, - } + return { + url: request.url, + mode: request.mode, + method: request.method, + headers: Object.fromEntries(request.headers.entries()), + cache: request.cache, + credentials: request.credentials, + destination: request.destination, + integrity: request.integrity, + redirect: request.redirect, + referrer: request.referrer, + referrerPolicy: request.referrerPolicy, + body: await request.arrayBuffer(), + keepalive: request.keepalive, + }; } diff --git a/apps/omsorgspengerutbetaling-arbeidstaker-soknad/mockServiceWorker.js b/apps/omsorgspengerutbetaling-arbeidstaker-soknad/mockServiceWorker.js index be4527c7ee..fff922cccf 100644 --- a/apps/omsorgspengerutbetaling-arbeidstaker-soknad/mockServiceWorker.js +++ b/apps/omsorgspengerutbetaling-arbeidstaker-soknad/mockServiceWorker.js @@ -7,160 +7,157 @@ * - Please do NOT modify this file. */ -const PACKAGE_VERSION = '2.10.4' -const INTEGRITY_CHECKSUM = 'f5825c521429caf22a4dd13b66e243af' -const IS_MOCKED_RESPONSE = Symbol('isMockedResponse') -const activeClientIds = new Set() +const PACKAGE_VERSION = '2.10.4'; +const INTEGRITY_CHECKSUM = 'f5825c521429caf22a4dd13b66e243af'; +const IS_MOCKED_RESPONSE = Symbol('isMockedResponse'); +const activeClientIds = new Set(); addEventListener('install', function () { - self.skipWaiting() -}) + self.skipWaiting(); +}); addEventListener('activate', function (event) { - event.waitUntil(self.clients.claim()) -}) + event.waitUntil(self.clients.claim()); +}); addEventListener('message', async function (event) { - const clientId = Reflect.get(event.source || {}, 'id') + const clientId = Reflect.get(event.source || {}, 'id'); - if (!clientId || !self.clients) { - return - } - - const client = await self.clients.get(clientId) - - if (!client) { - return - } + if (!clientId || !self.clients) { + return; + } - const allClients = await self.clients.matchAll({ - type: 'window', - }) + const client = await self.clients.get(clientId); - switch (event.data) { - case 'KEEPALIVE_REQUEST': { - sendToClient(client, { - type: 'KEEPALIVE_RESPONSE', - }) - break + if (!client) { + return; } - case 'INTEGRITY_CHECK_REQUEST': { - sendToClient(client, { - type: 'INTEGRITY_CHECK_RESPONSE', - payload: { - packageVersion: PACKAGE_VERSION, - checksum: INTEGRITY_CHECKSUM, - }, - }) - break + const allClients = await self.clients.matchAll({ + type: 'window', + }); + + switch (event.data) { + case 'KEEPALIVE_REQUEST': { + sendToClient(client, { + type: 'KEEPALIVE_RESPONSE', + }); + break; + } + + case 'INTEGRITY_CHECK_REQUEST': { + sendToClient(client, { + type: 'INTEGRITY_CHECK_RESPONSE', + payload: { + packageVersion: PACKAGE_VERSION, + checksum: INTEGRITY_CHECKSUM, + }, + }); + break; + } + + case 'MOCK_ACTIVATE': { + activeClientIds.add(clientId); + + sendToClient(client, { + type: 'MOCKING_ENABLED', + payload: { + client: { + id: client.id, + frameType: client.frameType, + }, + }, + }); + break; + } + + case 'MOCK_DEACTIVATE': { + activeClientIds.delete(clientId); + break; + } + + case 'CLIENT_CLOSED': { + activeClientIds.delete(clientId); + + const remainingClients = allClients.filter((client) => { + return client.id !== clientId; + }); + + // Unregister itself when there are no more clients + if (remainingClients.length === 0) { + self.registration.unregister(); + } + + break; + } } +}); - case 'MOCK_ACTIVATE': { - activeClientIds.add(clientId) - - sendToClient(client, { - type: 'MOCKING_ENABLED', - payload: { - client: { - id: client.id, - frameType: client.frameType, - }, - }, - }) - break +addEventListener('fetch', function (event) { + // Bypass navigation requests. + if (event.request.mode === 'navigate') { + return; } - case 'MOCK_DEACTIVATE': { - activeClientIds.delete(clientId) - break + // Opening the DevTools triggers the "only-if-cached" request + // that cannot be handled by the worker. Bypass such requests. + if (event.request.cache === 'only-if-cached' && event.request.mode !== 'same-origin') { + return; } - case 'CLIENT_CLOSED': { - activeClientIds.delete(clientId) - - const remainingClients = allClients.filter((client) => { - return client.id !== clientId - }) - - // Unregister itself when there are no more clients - if (remainingClients.length === 0) { - self.registration.unregister() - } - - break + // Bypass all requests when there are no active clients. + // Prevents the self-unregistered worked from handling requests + // after it's been deleted (still remains active until the next reload). + if (activeClientIds.size === 0) { + return; } - } -}) -addEventListener('fetch', function (event) { - // Bypass navigation requests. - if (event.request.mode === 'navigate') { - return - } - - // Opening the DevTools triggers the "only-if-cached" request - // that cannot be handled by the worker. Bypass such requests. - if ( - event.request.cache === 'only-if-cached' && - event.request.mode !== 'same-origin' - ) { - return - } - - // Bypass all requests when there are no active clients. - // Prevents the self-unregistered worked from handling requests - // after it's been deleted (still remains active until the next reload). - if (activeClientIds.size === 0) { - return - } - - const requestId = crypto.randomUUID() - event.respondWith(handleRequest(event, requestId)) -}) + const requestId = crypto.randomUUID(); + event.respondWith(handleRequest(event, requestId)); +}); /** * @param {FetchEvent} event * @param {string} requestId */ async function handleRequest(event, requestId) { - const client = await resolveMainClient(event) - const requestCloneForEvents = event.request.clone() - const response = await getResponse(event, client, requestId) - - // Send back the response clone for the "response:*" life-cycle events. - // Ensure MSW is active and ready to handle the message, otherwise - // this message will pend indefinitely. - if (client && activeClientIds.has(client.id)) { - const serializedRequest = await serializeRequest(requestCloneForEvents) - - // Clone the response so both the client and the library could consume it. - const responseClone = response.clone() - - sendToClient( - client, - { - type: 'RESPONSE', - payload: { - isMockedResponse: IS_MOCKED_RESPONSE in response, - request: { - id: requestId, - ...serializedRequest, - }, - response: { - type: responseClone.type, - status: responseClone.status, - statusText: responseClone.statusText, - headers: Object.fromEntries(responseClone.headers.entries()), - body: responseClone.body, - }, - }, - }, - responseClone.body ? [serializedRequest.body, responseClone.body] : [], - ) - } + const client = await resolveMainClient(event); + const requestCloneForEvents = event.request.clone(); + const response = await getResponse(event, client, requestId); + + // Send back the response clone for the "response:*" life-cycle events. + // Ensure MSW is active and ready to handle the message, otherwise + // this message will pend indefinitely. + if (client && activeClientIds.has(client.id)) { + const serializedRequest = await serializeRequest(requestCloneForEvents); + + // Clone the response so both the client and the library could consume it. + const responseClone = response.clone(); + + sendToClient( + client, + { + type: 'RESPONSE', + payload: { + isMockedResponse: IS_MOCKED_RESPONSE in response, + request: { + id: requestId, + ...serializedRequest, + }, + response: { + type: responseClone.type, + status: responseClone.status, + statusText: responseClone.statusText, + headers: Object.fromEntries(responseClone.headers.entries()), + body: responseClone.body, + }, + }, + }, + responseClone.body ? [serializedRequest.body, responseClone.body] : [], + ); + } - return response + return response; } /** @@ -172,30 +169,30 @@ async function handleRequest(event, requestId) { * @returns {Promise} */ async function resolveMainClient(event) { - const client = await self.clients.get(event.clientId) - - if (activeClientIds.has(event.clientId)) { - return client - } - - if (client?.frameType === 'top-level') { - return client - } - - const allClients = await self.clients.matchAll({ - type: 'window', - }) - - return allClients - .filter((client) => { - // Get only those clients that are currently visible. - return client.visibilityState === 'visible' - }) - .find((client) => { - // Find the client ID that's recorded in the - // set of clients that have registered the worker. - return activeClientIds.has(client.id) - }) + const client = await self.clients.get(event.clientId); + + if (activeClientIds.has(event.clientId)) { + return client; + } + + if (client?.frameType === 'top-level') { + return client; + } + + const allClients = await self.clients.matchAll({ + type: 'window', + }); + + return allClients + .filter((client) => { + // Get only those clients that are currently visible. + return client.visibilityState === 'visible'; + }) + .find((client) => { + // Find the client ID that's recorded in the + // set of clients that have registered the worker. + return activeClientIds.has(client.id); + }); } /** @@ -205,73 +202,71 @@ async function resolveMainClient(event) { * @returns {Promise} */ async function getResponse(event, client, requestId) { - // Clone the request because it might've been already used - // (i.e. its body has been read and sent to the client). - const requestClone = event.request.clone() - - function passthrough() { - // Cast the request headers to a new Headers instance - // so the headers can be manipulated with. - const headers = new Headers(requestClone.headers) - - // Remove the "accept" header value that marked this request as passthrough. - // This prevents request alteration and also keeps it compliant with the - // user-defined CORS policies. - const acceptHeader = headers.get('accept') - if (acceptHeader) { - const values = acceptHeader.split(',').map((value) => value.trim()) - const filteredValues = values.filter( - (value) => value !== 'msw/passthrough', - ) - - if (filteredValues.length > 0) { - headers.set('accept', filteredValues.join(', ')) - } else { - headers.delete('accept') - } + // Clone the request because it might've been already used + // (i.e. its body has been read and sent to the client). + const requestClone = event.request.clone(); + + function passthrough() { + // Cast the request headers to a new Headers instance + // so the headers can be manipulated with. + const headers = new Headers(requestClone.headers); + + // Remove the "accept" header value that marked this request as passthrough. + // This prevents request alteration and also keeps it compliant with the + // user-defined CORS policies. + const acceptHeader = headers.get('accept'); + if (acceptHeader) { + const values = acceptHeader.split(',').map((value) => value.trim()); + const filteredValues = values.filter((value) => value !== 'msw/passthrough'); + + if (filteredValues.length > 0) { + headers.set('accept', filteredValues.join(', ')); + } else { + headers.delete('accept'); + } + } + + return fetch(requestClone, { headers }); } - return fetch(requestClone, { headers }) - } - - // Bypass mocking when the client is not active. - if (!client) { - return passthrough() - } - - // Bypass initial page load requests (i.e. static assets). - // The absence of the immediate/parent client in the map of the active clients - // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet - // and is not ready to handle requests. - if (!activeClientIds.has(client.id)) { - return passthrough() - } - - // Notify the client that a request has been intercepted. - const serializedRequest = await serializeRequest(event.request) - const clientMessage = await sendToClient( - client, - { - type: 'REQUEST', - payload: { - id: requestId, - ...serializedRequest, - }, - }, - [serializedRequest.body], - ) - - switch (clientMessage.type) { - case 'MOCK_RESPONSE': { - return respondWithMock(clientMessage.data) + // Bypass mocking when the client is not active. + if (!client) { + return passthrough(); } - case 'PASSTHROUGH': { - return passthrough() + // Bypass initial page load requests (i.e. static assets). + // The absence of the immediate/parent client in the map of the active clients + // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet + // and is not ready to handle requests. + if (!activeClientIds.has(client.id)) { + return passthrough(); + } + + // Notify the client that a request has been intercepted. + const serializedRequest = await serializeRequest(event.request); + const clientMessage = await sendToClient( + client, + { + type: 'REQUEST', + payload: { + id: requestId, + ...serializedRequest, + }, + }, + [serializedRequest.body], + ); + + switch (clientMessage.type) { + case 'MOCK_RESPONSE': { + return respondWithMock(clientMessage.data); + } + + case 'PASSTHROUGH': { + return passthrough(); + } } - } - return passthrough() + return passthrough(); } /** @@ -281,22 +276,19 @@ async function getResponse(event, client, requestId) { * @returns {Promise} */ function sendToClient(client, message, transferrables = []) { - return new Promise((resolve, reject) => { - const channel = new MessageChannel() + return new Promise((resolve, reject) => { + const channel = new MessageChannel(); - channel.port1.onmessage = (event) => { - if (event.data && event.data.error) { - return reject(event.data.error) - } + channel.port1.onmessage = (event) => { + if (event.data && event.data.error) { + return reject(event.data.error); + } - resolve(event.data) - } + resolve(event.data); + }; - client.postMessage(message, [ - channel.port2, - ...transferrables.filter(Boolean), - ]) - }) + client.postMessage(message, [channel.port2, ...transferrables.filter(Boolean)]); + }); } /** @@ -304,41 +296,41 @@ function sendToClient(client, message, transferrables = []) { * @returns {Response} */ function respondWithMock(response) { - // Setting response status code to 0 is a no-op. - // However, when responding with a "Response.error()", the produced Response - // instance will have status code set to 0. Since it's not possible to create - // a Response instance with status code 0, handle that use-case separately. - if (response.status === 0) { - return Response.error() - } - - const mockedResponse = new Response(response.body, response) - - Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, { - value: true, - enumerable: true, - }) - - return mockedResponse + // Setting response status code to 0 is a no-op. + // However, when responding with a "Response.error()", the produced Response + // instance will have status code set to 0. Since it's not possible to create + // a Response instance with status code 0, handle that use-case separately. + if (response.status === 0) { + return Response.error(); + } + + const mockedResponse = new Response(response.body, response); + + Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, { + value: true, + enumerable: true, + }); + + return mockedResponse; } /** * @param {Request} request */ async function serializeRequest(request) { - return { - url: request.url, - mode: request.mode, - method: request.method, - headers: Object.fromEntries(request.headers.entries()), - cache: request.cache, - credentials: request.credentials, - destination: request.destination, - integrity: request.integrity, - redirect: request.redirect, - referrer: request.referrer, - referrerPolicy: request.referrerPolicy, - body: await request.arrayBuffer(), - keepalive: request.keepalive, - } + return { + url: request.url, + mode: request.mode, + method: request.method, + headers: Object.fromEntries(request.headers.entries()), + cache: request.cache, + credentials: request.credentials, + destination: request.destination, + integrity: request.integrity, + redirect: request.redirect, + referrer: request.referrer, + referrerPolicy: request.referrerPolicy, + body: await request.arrayBuffer(), + keepalive: request.keepalive, + }; } diff --git a/apps/omsorgspengerutbetaling-soknad/mockServiceWorker.js b/apps/omsorgspengerutbetaling-soknad/mockServiceWorker.js index be4527c7ee..fff922cccf 100644 --- a/apps/omsorgspengerutbetaling-soknad/mockServiceWorker.js +++ b/apps/omsorgspengerutbetaling-soknad/mockServiceWorker.js @@ -7,160 +7,157 @@ * - Please do NOT modify this file. */ -const PACKAGE_VERSION = '2.10.4' -const INTEGRITY_CHECKSUM = 'f5825c521429caf22a4dd13b66e243af' -const IS_MOCKED_RESPONSE = Symbol('isMockedResponse') -const activeClientIds = new Set() +const PACKAGE_VERSION = '2.10.4'; +const INTEGRITY_CHECKSUM = 'f5825c521429caf22a4dd13b66e243af'; +const IS_MOCKED_RESPONSE = Symbol('isMockedResponse'); +const activeClientIds = new Set(); addEventListener('install', function () { - self.skipWaiting() -}) + self.skipWaiting(); +}); addEventListener('activate', function (event) { - event.waitUntil(self.clients.claim()) -}) + event.waitUntil(self.clients.claim()); +}); addEventListener('message', async function (event) { - const clientId = Reflect.get(event.source || {}, 'id') + const clientId = Reflect.get(event.source || {}, 'id'); - if (!clientId || !self.clients) { - return - } - - const client = await self.clients.get(clientId) - - if (!client) { - return - } + if (!clientId || !self.clients) { + return; + } - const allClients = await self.clients.matchAll({ - type: 'window', - }) + const client = await self.clients.get(clientId); - switch (event.data) { - case 'KEEPALIVE_REQUEST': { - sendToClient(client, { - type: 'KEEPALIVE_RESPONSE', - }) - break + if (!client) { + return; } - case 'INTEGRITY_CHECK_REQUEST': { - sendToClient(client, { - type: 'INTEGRITY_CHECK_RESPONSE', - payload: { - packageVersion: PACKAGE_VERSION, - checksum: INTEGRITY_CHECKSUM, - }, - }) - break + const allClients = await self.clients.matchAll({ + type: 'window', + }); + + switch (event.data) { + case 'KEEPALIVE_REQUEST': { + sendToClient(client, { + type: 'KEEPALIVE_RESPONSE', + }); + break; + } + + case 'INTEGRITY_CHECK_REQUEST': { + sendToClient(client, { + type: 'INTEGRITY_CHECK_RESPONSE', + payload: { + packageVersion: PACKAGE_VERSION, + checksum: INTEGRITY_CHECKSUM, + }, + }); + break; + } + + case 'MOCK_ACTIVATE': { + activeClientIds.add(clientId); + + sendToClient(client, { + type: 'MOCKING_ENABLED', + payload: { + client: { + id: client.id, + frameType: client.frameType, + }, + }, + }); + break; + } + + case 'MOCK_DEACTIVATE': { + activeClientIds.delete(clientId); + break; + } + + case 'CLIENT_CLOSED': { + activeClientIds.delete(clientId); + + const remainingClients = allClients.filter((client) => { + return client.id !== clientId; + }); + + // Unregister itself when there are no more clients + if (remainingClients.length === 0) { + self.registration.unregister(); + } + + break; + } } +}); - case 'MOCK_ACTIVATE': { - activeClientIds.add(clientId) - - sendToClient(client, { - type: 'MOCKING_ENABLED', - payload: { - client: { - id: client.id, - frameType: client.frameType, - }, - }, - }) - break +addEventListener('fetch', function (event) { + // Bypass navigation requests. + if (event.request.mode === 'navigate') { + return; } - case 'MOCK_DEACTIVATE': { - activeClientIds.delete(clientId) - break + // Opening the DevTools triggers the "only-if-cached" request + // that cannot be handled by the worker. Bypass such requests. + if (event.request.cache === 'only-if-cached' && event.request.mode !== 'same-origin') { + return; } - case 'CLIENT_CLOSED': { - activeClientIds.delete(clientId) - - const remainingClients = allClients.filter((client) => { - return client.id !== clientId - }) - - // Unregister itself when there are no more clients - if (remainingClients.length === 0) { - self.registration.unregister() - } - - break + // Bypass all requests when there are no active clients. + // Prevents the self-unregistered worked from handling requests + // after it's been deleted (still remains active until the next reload). + if (activeClientIds.size === 0) { + return; } - } -}) -addEventListener('fetch', function (event) { - // Bypass navigation requests. - if (event.request.mode === 'navigate') { - return - } - - // Opening the DevTools triggers the "only-if-cached" request - // that cannot be handled by the worker. Bypass such requests. - if ( - event.request.cache === 'only-if-cached' && - event.request.mode !== 'same-origin' - ) { - return - } - - // Bypass all requests when there are no active clients. - // Prevents the self-unregistered worked from handling requests - // after it's been deleted (still remains active until the next reload). - if (activeClientIds.size === 0) { - return - } - - const requestId = crypto.randomUUID() - event.respondWith(handleRequest(event, requestId)) -}) + const requestId = crypto.randomUUID(); + event.respondWith(handleRequest(event, requestId)); +}); /** * @param {FetchEvent} event * @param {string} requestId */ async function handleRequest(event, requestId) { - const client = await resolveMainClient(event) - const requestCloneForEvents = event.request.clone() - const response = await getResponse(event, client, requestId) - - // Send back the response clone for the "response:*" life-cycle events. - // Ensure MSW is active and ready to handle the message, otherwise - // this message will pend indefinitely. - if (client && activeClientIds.has(client.id)) { - const serializedRequest = await serializeRequest(requestCloneForEvents) - - // Clone the response so both the client and the library could consume it. - const responseClone = response.clone() - - sendToClient( - client, - { - type: 'RESPONSE', - payload: { - isMockedResponse: IS_MOCKED_RESPONSE in response, - request: { - id: requestId, - ...serializedRequest, - }, - response: { - type: responseClone.type, - status: responseClone.status, - statusText: responseClone.statusText, - headers: Object.fromEntries(responseClone.headers.entries()), - body: responseClone.body, - }, - }, - }, - responseClone.body ? [serializedRequest.body, responseClone.body] : [], - ) - } + const client = await resolveMainClient(event); + const requestCloneForEvents = event.request.clone(); + const response = await getResponse(event, client, requestId); + + // Send back the response clone for the "response:*" life-cycle events. + // Ensure MSW is active and ready to handle the message, otherwise + // this message will pend indefinitely. + if (client && activeClientIds.has(client.id)) { + const serializedRequest = await serializeRequest(requestCloneForEvents); + + // Clone the response so both the client and the library could consume it. + const responseClone = response.clone(); + + sendToClient( + client, + { + type: 'RESPONSE', + payload: { + isMockedResponse: IS_MOCKED_RESPONSE in response, + request: { + id: requestId, + ...serializedRequest, + }, + response: { + type: responseClone.type, + status: responseClone.status, + statusText: responseClone.statusText, + headers: Object.fromEntries(responseClone.headers.entries()), + body: responseClone.body, + }, + }, + }, + responseClone.body ? [serializedRequest.body, responseClone.body] : [], + ); + } - return response + return response; } /** @@ -172,30 +169,30 @@ async function handleRequest(event, requestId) { * @returns {Promise} */ async function resolveMainClient(event) { - const client = await self.clients.get(event.clientId) - - if (activeClientIds.has(event.clientId)) { - return client - } - - if (client?.frameType === 'top-level') { - return client - } - - const allClients = await self.clients.matchAll({ - type: 'window', - }) - - return allClients - .filter((client) => { - // Get only those clients that are currently visible. - return client.visibilityState === 'visible' - }) - .find((client) => { - // Find the client ID that's recorded in the - // set of clients that have registered the worker. - return activeClientIds.has(client.id) - }) + const client = await self.clients.get(event.clientId); + + if (activeClientIds.has(event.clientId)) { + return client; + } + + if (client?.frameType === 'top-level') { + return client; + } + + const allClients = await self.clients.matchAll({ + type: 'window', + }); + + return allClients + .filter((client) => { + // Get only those clients that are currently visible. + return client.visibilityState === 'visible'; + }) + .find((client) => { + // Find the client ID that's recorded in the + // set of clients that have registered the worker. + return activeClientIds.has(client.id); + }); } /** @@ -205,73 +202,71 @@ async function resolveMainClient(event) { * @returns {Promise} */ async function getResponse(event, client, requestId) { - // Clone the request because it might've been already used - // (i.e. its body has been read and sent to the client). - const requestClone = event.request.clone() - - function passthrough() { - // Cast the request headers to a new Headers instance - // so the headers can be manipulated with. - const headers = new Headers(requestClone.headers) - - // Remove the "accept" header value that marked this request as passthrough. - // This prevents request alteration and also keeps it compliant with the - // user-defined CORS policies. - const acceptHeader = headers.get('accept') - if (acceptHeader) { - const values = acceptHeader.split(',').map((value) => value.trim()) - const filteredValues = values.filter( - (value) => value !== 'msw/passthrough', - ) - - if (filteredValues.length > 0) { - headers.set('accept', filteredValues.join(', ')) - } else { - headers.delete('accept') - } + // Clone the request because it might've been already used + // (i.e. its body has been read and sent to the client). + const requestClone = event.request.clone(); + + function passthrough() { + // Cast the request headers to a new Headers instance + // so the headers can be manipulated with. + const headers = new Headers(requestClone.headers); + + // Remove the "accept" header value that marked this request as passthrough. + // This prevents request alteration and also keeps it compliant with the + // user-defined CORS policies. + const acceptHeader = headers.get('accept'); + if (acceptHeader) { + const values = acceptHeader.split(',').map((value) => value.trim()); + const filteredValues = values.filter((value) => value !== 'msw/passthrough'); + + if (filteredValues.length > 0) { + headers.set('accept', filteredValues.join(', ')); + } else { + headers.delete('accept'); + } + } + + return fetch(requestClone, { headers }); } - return fetch(requestClone, { headers }) - } - - // Bypass mocking when the client is not active. - if (!client) { - return passthrough() - } - - // Bypass initial page load requests (i.e. static assets). - // The absence of the immediate/parent client in the map of the active clients - // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet - // and is not ready to handle requests. - if (!activeClientIds.has(client.id)) { - return passthrough() - } - - // Notify the client that a request has been intercepted. - const serializedRequest = await serializeRequest(event.request) - const clientMessage = await sendToClient( - client, - { - type: 'REQUEST', - payload: { - id: requestId, - ...serializedRequest, - }, - }, - [serializedRequest.body], - ) - - switch (clientMessage.type) { - case 'MOCK_RESPONSE': { - return respondWithMock(clientMessage.data) + // Bypass mocking when the client is not active. + if (!client) { + return passthrough(); } - case 'PASSTHROUGH': { - return passthrough() + // Bypass initial page load requests (i.e. static assets). + // The absence of the immediate/parent client in the map of the active clients + // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet + // and is not ready to handle requests. + if (!activeClientIds.has(client.id)) { + return passthrough(); + } + + // Notify the client that a request has been intercepted. + const serializedRequest = await serializeRequest(event.request); + const clientMessage = await sendToClient( + client, + { + type: 'REQUEST', + payload: { + id: requestId, + ...serializedRequest, + }, + }, + [serializedRequest.body], + ); + + switch (clientMessage.type) { + case 'MOCK_RESPONSE': { + return respondWithMock(clientMessage.data); + } + + case 'PASSTHROUGH': { + return passthrough(); + } } - } - return passthrough() + return passthrough(); } /** @@ -281,22 +276,19 @@ async function getResponse(event, client, requestId) { * @returns {Promise} */ function sendToClient(client, message, transferrables = []) { - return new Promise((resolve, reject) => { - const channel = new MessageChannel() + return new Promise((resolve, reject) => { + const channel = new MessageChannel(); - channel.port1.onmessage = (event) => { - if (event.data && event.data.error) { - return reject(event.data.error) - } + channel.port1.onmessage = (event) => { + if (event.data && event.data.error) { + return reject(event.data.error); + } - resolve(event.data) - } + resolve(event.data); + }; - client.postMessage(message, [ - channel.port2, - ...transferrables.filter(Boolean), - ]) - }) + client.postMessage(message, [channel.port2, ...transferrables.filter(Boolean)]); + }); } /** @@ -304,41 +296,41 @@ function sendToClient(client, message, transferrables = []) { * @returns {Response} */ function respondWithMock(response) { - // Setting response status code to 0 is a no-op. - // However, when responding with a "Response.error()", the produced Response - // instance will have status code set to 0. Since it's not possible to create - // a Response instance with status code 0, handle that use-case separately. - if (response.status === 0) { - return Response.error() - } - - const mockedResponse = new Response(response.body, response) - - Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, { - value: true, - enumerable: true, - }) - - return mockedResponse + // Setting response status code to 0 is a no-op. + // However, when responding with a "Response.error()", the produced Response + // instance will have status code set to 0. Since it's not possible to create + // a Response instance with status code 0, handle that use-case separately. + if (response.status === 0) { + return Response.error(); + } + + const mockedResponse = new Response(response.body, response); + + Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, { + value: true, + enumerable: true, + }); + + return mockedResponse; } /** * @param {Request} request */ async function serializeRequest(request) { - return { - url: request.url, - mode: request.mode, - method: request.method, - headers: Object.fromEntries(request.headers.entries()), - cache: request.cache, - credentials: request.credentials, - destination: request.destination, - integrity: request.integrity, - redirect: request.redirect, - referrer: request.referrer, - referrerPolicy: request.referrerPolicy, - body: await request.arrayBuffer(), - keepalive: request.keepalive, - } + return { + url: request.url, + mode: request.mode, + method: request.method, + headers: Object.fromEntries(request.headers.entries()), + cache: request.cache, + credentials: request.credentials, + destination: request.destination, + integrity: request.integrity, + redirect: request.redirect, + referrer: request.referrer, + referrerPolicy: request.referrerPolicy, + body: await request.arrayBuffer(), + keepalive: request.keepalive, + }; } diff --git a/apps/omsorgspengesoknad/mockServiceWorker.js b/apps/omsorgspengesoknad/mockServiceWorker.js index de7bc0f292..66e2da9409 100644 --- a/apps/omsorgspengesoknad/mockServiceWorker.js +++ b/apps/omsorgspengesoknad/mockServiceWorker.js @@ -7,160 +7,157 @@ * - Please do NOT modify this file. */ -const PACKAGE_VERSION = '2.10.2' -const INTEGRITY_CHECKSUM = 'f5825c521429caf22a4dd13b66e243af' -const IS_MOCKED_RESPONSE = Symbol('isMockedResponse') -const activeClientIds = new Set() +const PACKAGE_VERSION = '2.10.2'; +const INTEGRITY_CHECKSUM = 'f5825c521429caf22a4dd13b66e243af'; +const IS_MOCKED_RESPONSE = Symbol('isMockedResponse'); +const activeClientIds = new Set(); addEventListener('install', function () { - self.skipWaiting() -}) + self.skipWaiting(); +}); addEventListener('activate', function (event) { - event.waitUntil(self.clients.claim()) -}) + event.waitUntil(self.clients.claim()); +}); addEventListener('message', async function (event) { - const clientId = Reflect.get(event.source || {}, 'id') + const clientId = Reflect.get(event.source || {}, 'id'); - if (!clientId || !self.clients) { - return - } - - const client = await self.clients.get(clientId) - - if (!client) { - return - } + if (!clientId || !self.clients) { + return; + } - const allClients = await self.clients.matchAll({ - type: 'window', - }) + const client = await self.clients.get(clientId); - switch (event.data) { - case 'KEEPALIVE_REQUEST': { - sendToClient(client, { - type: 'KEEPALIVE_RESPONSE', - }) - break + if (!client) { + return; } - case 'INTEGRITY_CHECK_REQUEST': { - sendToClient(client, { - type: 'INTEGRITY_CHECK_RESPONSE', - payload: { - packageVersion: PACKAGE_VERSION, - checksum: INTEGRITY_CHECKSUM, - }, - }) - break + const allClients = await self.clients.matchAll({ + type: 'window', + }); + + switch (event.data) { + case 'KEEPALIVE_REQUEST': { + sendToClient(client, { + type: 'KEEPALIVE_RESPONSE', + }); + break; + } + + case 'INTEGRITY_CHECK_REQUEST': { + sendToClient(client, { + type: 'INTEGRITY_CHECK_RESPONSE', + payload: { + packageVersion: PACKAGE_VERSION, + checksum: INTEGRITY_CHECKSUM, + }, + }); + break; + } + + case 'MOCK_ACTIVATE': { + activeClientIds.add(clientId); + + sendToClient(client, { + type: 'MOCKING_ENABLED', + payload: { + client: { + id: client.id, + frameType: client.frameType, + }, + }, + }); + break; + } + + case 'MOCK_DEACTIVATE': { + activeClientIds.delete(clientId); + break; + } + + case 'CLIENT_CLOSED': { + activeClientIds.delete(clientId); + + const remainingClients = allClients.filter((client) => { + return client.id !== clientId; + }); + + // Unregister itself when there are no more clients + if (remainingClients.length === 0) { + self.registration.unregister(); + } + + break; + } } +}); - case 'MOCK_ACTIVATE': { - activeClientIds.add(clientId) - - sendToClient(client, { - type: 'MOCKING_ENABLED', - payload: { - client: { - id: client.id, - frameType: client.frameType, - }, - }, - }) - break +addEventListener('fetch', function (event) { + // Bypass navigation requests. + if (event.request.mode === 'navigate') { + return; } - case 'MOCK_DEACTIVATE': { - activeClientIds.delete(clientId) - break + // Opening the DevTools triggers the "only-if-cached" request + // that cannot be handled by the worker. Bypass such requests. + if (event.request.cache === 'only-if-cached' && event.request.mode !== 'same-origin') { + return; } - case 'CLIENT_CLOSED': { - activeClientIds.delete(clientId) - - const remainingClients = allClients.filter((client) => { - return client.id !== clientId - }) - - // Unregister itself when there are no more clients - if (remainingClients.length === 0) { - self.registration.unregister() - } - - break + // Bypass all requests when there are no active clients. + // Prevents the self-unregistered worked from handling requests + // after it's been deleted (still remains active until the next reload). + if (activeClientIds.size === 0) { + return; } - } -}) -addEventListener('fetch', function (event) { - // Bypass navigation requests. - if (event.request.mode === 'navigate') { - return - } - - // Opening the DevTools triggers the "only-if-cached" request - // that cannot be handled by the worker. Bypass such requests. - if ( - event.request.cache === 'only-if-cached' && - event.request.mode !== 'same-origin' - ) { - return - } - - // Bypass all requests when there are no active clients. - // Prevents the self-unregistered worked from handling requests - // after it's been deleted (still remains active until the next reload). - if (activeClientIds.size === 0) { - return - } - - const requestId = crypto.randomUUID() - event.respondWith(handleRequest(event, requestId)) -}) + const requestId = crypto.randomUUID(); + event.respondWith(handleRequest(event, requestId)); +}); /** * @param {FetchEvent} event * @param {string} requestId */ async function handleRequest(event, requestId) { - const client = await resolveMainClient(event) - const requestCloneForEvents = event.request.clone() - const response = await getResponse(event, client, requestId) - - // Send back the response clone for the "response:*" life-cycle events. - // Ensure MSW is active and ready to handle the message, otherwise - // this message will pend indefinitely. - if (client && activeClientIds.has(client.id)) { - const serializedRequest = await serializeRequest(requestCloneForEvents) - - // Clone the response so both the client and the library could consume it. - const responseClone = response.clone() - - sendToClient( - client, - { - type: 'RESPONSE', - payload: { - isMockedResponse: IS_MOCKED_RESPONSE in response, - request: { - id: requestId, - ...serializedRequest, - }, - response: { - type: responseClone.type, - status: responseClone.status, - statusText: responseClone.statusText, - headers: Object.fromEntries(responseClone.headers.entries()), - body: responseClone.body, - }, - }, - }, - responseClone.body ? [serializedRequest.body, responseClone.body] : [], - ) - } + const client = await resolveMainClient(event); + const requestCloneForEvents = event.request.clone(); + const response = await getResponse(event, client, requestId); + + // Send back the response clone for the "response:*" life-cycle events. + // Ensure MSW is active and ready to handle the message, otherwise + // this message will pend indefinitely. + if (client && activeClientIds.has(client.id)) { + const serializedRequest = await serializeRequest(requestCloneForEvents); + + // Clone the response so both the client and the library could consume it. + const responseClone = response.clone(); + + sendToClient( + client, + { + type: 'RESPONSE', + payload: { + isMockedResponse: IS_MOCKED_RESPONSE in response, + request: { + id: requestId, + ...serializedRequest, + }, + response: { + type: responseClone.type, + status: responseClone.status, + statusText: responseClone.statusText, + headers: Object.fromEntries(responseClone.headers.entries()), + body: responseClone.body, + }, + }, + }, + responseClone.body ? [serializedRequest.body, responseClone.body] : [], + ); + } - return response + return response; } /** @@ -172,30 +169,30 @@ async function handleRequest(event, requestId) { * @returns {Promise} */ async function resolveMainClient(event) { - const client = await self.clients.get(event.clientId) - - if (activeClientIds.has(event.clientId)) { - return client - } - - if (client?.frameType === 'top-level') { - return client - } - - const allClients = await self.clients.matchAll({ - type: 'window', - }) - - return allClients - .filter((client) => { - // Get only those clients that are currently visible. - return client.visibilityState === 'visible' - }) - .find((client) => { - // Find the client ID that's recorded in the - // set of clients that have registered the worker. - return activeClientIds.has(client.id) - }) + const client = await self.clients.get(event.clientId); + + if (activeClientIds.has(event.clientId)) { + return client; + } + + if (client?.frameType === 'top-level') { + return client; + } + + const allClients = await self.clients.matchAll({ + type: 'window', + }); + + return allClients + .filter((client) => { + // Get only those clients that are currently visible. + return client.visibilityState === 'visible'; + }) + .find((client) => { + // Find the client ID that's recorded in the + // set of clients that have registered the worker. + return activeClientIds.has(client.id); + }); } /** @@ -205,73 +202,71 @@ async function resolveMainClient(event) { * @returns {Promise} */ async function getResponse(event, client, requestId) { - // Clone the request because it might've been already used - // (i.e. its body has been read and sent to the client). - const requestClone = event.request.clone() - - function passthrough() { - // Cast the request headers to a new Headers instance - // so the headers can be manipulated with. - const headers = new Headers(requestClone.headers) - - // Remove the "accept" header value that marked this request as passthrough. - // This prevents request alteration and also keeps it compliant with the - // user-defined CORS policies. - const acceptHeader = headers.get('accept') - if (acceptHeader) { - const values = acceptHeader.split(',').map((value) => value.trim()) - const filteredValues = values.filter( - (value) => value !== 'msw/passthrough', - ) - - if (filteredValues.length > 0) { - headers.set('accept', filteredValues.join(', ')) - } else { - headers.delete('accept') - } + // Clone the request because it might've been already used + // (i.e. its body has been read and sent to the client). + const requestClone = event.request.clone(); + + function passthrough() { + // Cast the request headers to a new Headers instance + // so the headers can be manipulated with. + const headers = new Headers(requestClone.headers); + + // Remove the "accept" header value that marked this request as passthrough. + // This prevents request alteration and also keeps it compliant with the + // user-defined CORS policies. + const acceptHeader = headers.get('accept'); + if (acceptHeader) { + const values = acceptHeader.split(',').map((value) => value.trim()); + const filteredValues = values.filter((value) => value !== 'msw/passthrough'); + + if (filteredValues.length > 0) { + headers.set('accept', filteredValues.join(', ')); + } else { + headers.delete('accept'); + } + } + + return fetch(requestClone, { headers }); } - return fetch(requestClone, { headers }) - } - - // Bypass mocking when the client is not active. - if (!client) { - return passthrough() - } - - // Bypass initial page load requests (i.e. static assets). - // The absence of the immediate/parent client in the map of the active clients - // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet - // and is not ready to handle requests. - if (!activeClientIds.has(client.id)) { - return passthrough() - } - - // Notify the client that a request has been intercepted. - const serializedRequest = await serializeRequest(event.request) - const clientMessage = await sendToClient( - client, - { - type: 'REQUEST', - payload: { - id: requestId, - ...serializedRequest, - }, - }, - [serializedRequest.body], - ) - - switch (clientMessage.type) { - case 'MOCK_RESPONSE': { - return respondWithMock(clientMessage.data) + // Bypass mocking when the client is not active. + if (!client) { + return passthrough(); } - case 'PASSTHROUGH': { - return passthrough() + // Bypass initial page load requests (i.e. static assets). + // The absence of the immediate/parent client in the map of the active clients + // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet + // and is not ready to handle requests. + if (!activeClientIds.has(client.id)) { + return passthrough(); + } + + // Notify the client that a request has been intercepted. + const serializedRequest = await serializeRequest(event.request); + const clientMessage = await sendToClient( + client, + { + type: 'REQUEST', + payload: { + id: requestId, + ...serializedRequest, + }, + }, + [serializedRequest.body], + ); + + switch (clientMessage.type) { + case 'MOCK_RESPONSE': { + return respondWithMock(clientMessage.data); + } + + case 'PASSTHROUGH': { + return passthrough(); + } } - } - return passthrough() + return passthrough(); } /** @@ -281,22 +276,19 @@ async function getResponse(event, client, requestId) { * @returns {Promise} */ function sendToClient(client, message, transferrables = []) { - return new Promise((resolve, reject) => { - const channel = new MessageChannel() + return new Promise((resolve, reject) => { + const channel = new MessageChannel(); - channel.port1.onmessage = (event) => { - if (event.data && event.data.error) { - return reject(event.data.error) - } + channel.port1.onmessage = (event) => { + if (event.data && event.data.error) { + return reject(event.data.error); + } - resolve(event.data) - } + resolve(event.data); + }; - client.postMessage(message, [ - channel.port2, - ...transferrables.filter(Boolean), - ]) - }) + client.postMessage(message, [channel.port2, ...transferrables.filter(Boolean)]); + }); } /** @@ -304,41 +296,41 @@ function sendToClient(client, message, transferrables = []) { * @returns {Response} */ function respondWithMock(response) { - // Setting response status code to 0 is a no-op. - // However, when responding with a "Response.error()", the produced Response - // instance will have status code set to 0. Since it's not possible to create - // a Response instance with status code 0, handle that use-case separately. - if (response.status === 0) { - return Response.error() - } - - const mockedResponse = new Response(response.body, response) - - Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, { - value: true, - enumerable: true, - }) - - return mockedResponse + // Setting response status code to 0 is a no-op. + // However, when responding with a "Response.error()", the produced Response + // instance will have status code set to 0. Since it's not possible to create + // a Response instance with status code 0, handle that use-case separately. + if (response.status === 0) { + return Response.error(); + } + + const mockedResponse = new Response(response.body, response); + + Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, { + value: true, + enumerable: true, + }); + + return mockedResponse; } /** * @param {Request} request */ async function serializeRequest(request) { - return { - url: request.url, - mode: request.mode, - method: request.method, - headers: Object.fromEntries(request.headers.entries()), - cache: request.cache, - credentials: request.credentials, - destination: request.destination, - integrity: request.integrity, - redirect: request.redirect, - referrer: request.referrer, - referrerPolicy: request.referrerPolicy, - body: await request.arrayBuffer(), - keepalive: request.keepalive, - } + return { + url: request.url, + mode: request.mode, + method: request.method, + headers: Object.fromEntries(request.headers.entries()), + cache: request.cache, + credentials: request.credentials, + destination: request.destination, + integrity: request.integrity, + redirect: request.redirect, + referrer: request.referrer, + referrerPolicy: request.referrerPolicy, + body: await request.arrayBuffer(), + keepalive: request.keepalive, + }; } diff --git a/apps/pleiepenger-i-livets-sluttfase-soknad/mockServiceWorker.js b/apps/pleiepenger-i-livets-sluttfase-soknad/mockServiceWorker.js index be4527c7ee..fff922cccf 100644 --- a/apps/pleiepenger-i-livets-sluttfase-soknad/mockServiceWorker.js +++ b/apps/pleiepenger-i-livets-sluttfase-soknad/mockServiceWorker.js @@ -7,160 +7,157 @@ * - Please do NOT modify this file. */ -const PACKAGE_VERSION = '2.10.4' -const INTEGRITY_CHECKSUM = 'f5825c521429caf22a4dd13b66e243af' -const IS_MOCKED_RESPONSE = Symbol('isMockedResponse') -const activeClientIds = new Set() +const PACKAGE_VERSION = '2.10.4'; +const INTEGRITY_CHECKSUM = 'f5825c521429caf22a4dd13b66e243af'; +const IS_MOCKED_RESPONSE = Symbol('isMockedResponse'); +const activeClientIds = new Set(); addEventListener('install', function () { - self.skipWaiting() -}) + self.skipWaiting(); +}); addEventListener('activate', function (event) { - event.waitUntil(self.clients.claim()) -}) + event.waitUntil(self.clients.claim()); +}); addEventListener('message', async function (event) { - const clientId = Reflect.get(event.source || {}, 'id') + const clientId = Reflect.get(event.source || {}, 'id'); - if (!clientId || !self.clients) { - return - } - - const client = await self.clients.get(clientId) - - if (!client) { - return - } + if (!clientId || !self.clients) { + return; + } - const allClients = await self.clients.matchAll({ - type: 'window', - }) + const client = await self.clients.get(clientId); - switch (event.data) { - case 'KEEPALIVE_REQUEST': { - sendToClient(client, { - type: 'KEEPALIVE_RESPONSE', - }) - break + if (!client) { + return; } - case 'INTEGRITY_CHECK_REQUEST': { - sendToClient(client, { - type: 'INTEGRITY_CHECK_RESPONSE', - payload: { - packageVersion: PACKAGE_VERSION, - checksum: INTEGRITY_CHECKSUM, - }, - }) - break + const allClients = await self.clients.matchAll({ + type: 'window', + }); + + switch (event.data) { + case 'KEEPALIVE_REQUEST': { + sendToClient(client, { + type: 'KEEPALIVE_RESPONSE', + }); + break; + } + + case 'INTEGRITY_CHECK_REQUEST': { + sendToClient(client, { + type: 'INTEGRITY_CHECK_RESPONSE', + payload: { + packageVersion: PACKAGE_VERSION, + checksum: INTEGRITY_CHECKSUM, + }, + }); + break; + } + + case 'MOCK_ACTIVATE': { + activeClientIds.add(clientId); + + sendToClient(client, { + type: 'MOCKING_ENABLED', + payload: { + client: { + id: client.id, + frameType: client.frameType, + }, + }, + }); + break; + } + + case 'MOCK_DEACTIVATE': { + activeClientIds.delete(clientId); + break; + } + + case 'CLIENT_CLOSED': { + activeClientIds.delete(clientId); + + const remainingClients = allClients.filter((client) => { + return client.id !== clientId; + }); + + // Unregister itself when there are no more clients + if (remainingClients.length === 0) { + self.registration.unregister(); + } + + break; + } } +}); - case 'MOCK_ACTIVATE': { - activeClientIds.add(clientId) - - sendToClient(client, { - type: 'MOCKING_ENABLED', - payload: { - client: { - id: client.id, - frameType: client.frameType, - }, - }, - }) - break +addEventListener('fetch', function (event) { + // Bypass navigation requests. + if (event.request.mode === 'navigate') { + return; } - case 'MOCK_DEACTIVATE': { - activeClientIds.delete(clientId) - break + // Opening the DevTools triggers the "only-if-cached" request + // that cannot be handled by the worker. Bypass such requests. + if (event.request.cache === 'only-if-cached' && event.request.mode !== 'same-origin') { + return; } - case 'CLIENT_CLOSED': { - activeClientIds.delete(clientId) - - const remainingClients = allClients.filter((client) => { - return client.id !== clientId - }) - - // Unregister itself when there are no more clients - if (remainingClients.length === 0) { - self.registration.unregister() - } - - break + // Bypass all requests when there are no active clients. + // Prevents the self-unregistered worked from handling requests + // after it's been deleted (still remains active until the next reload). + if (activeClientIds.size === 0) { + return; } - } -}) -addEventListener('fetch', function (event) { - // Bypass navigation requests. - if (event.request.mode === 'navigate') { - return - } - - // Opening the DevTools triggers the "only-if-cached" request - // that cannot be handled by the worker. Bypass such requests. - if ( - event.request.cache === 'only-if-cached' && - event.request.mode !== 'same-origin' - ) { - return - } - - // Bypass all requests when there are no active clients. - // Prevents the self-unregistered worked from handling requests - // after it's been deleted (still remains active until the next reload). - if (activeClientIds.size === 0) { - return - } - - const requestId = crypto.randomUUID() - event.respondWith(handleRequest(event, requestId)) -}) + const requestId = crypto.randomUUID(); + event.respondWith(handleRequest(event, requestId)); +}); /** * @param {FetchEvent} event * @param {string} requestId */ async function handleRequest(event, requestId) { - const client = await resolveMainClient(event) - const requestCloneForEvents = event.request.clone() - const response = await getResponse(event, client, requestId) - - // Send back the response clone for the "response:*" life-cycle events. - // Ensure MSW is active and ready to handle the message, otherwise - // this message will pend indefinitely. - if (client && activeClientIds.has(client.id)) { - const serializedRequest = await serializeRequest(requestCloneForEvents) - - // Clone the response so both the client and the library could consume it. - const responseClone = response.clone() - - sendToClient( - client, - { - type: 'RESPONSE', - payload: { - isMockedResponse: IS_MOCKED_RESPONSE in response, - request: { - id: requestId, - ...serializedRequest, - }, - response: { - type: responseClone.type, - status: responseClone.status, - statusText: responseClone.statusText, - headers: Object.fromEntries(responseClone.headers.entries()), - body: responseClone.body, - }, - }, - }, - responseClone.body ? [serializedRequest.body, responseClone.body] : [], - ) - } + const client = await resolveMainClient(event); + const requestCloneForEvents = event.request.clone(); + const response = await getResponse(event, client, requestId); + + // Send back the response clone for the "response:*" life-cycle events. + // Ensure MSW is active and ready to handle the message, otherwise + // this message will pend indefinitely. + if (client && activeClientIds.has(client.id)) { + const serializedRequest = await serializeRequest(requestCloneForEvents); + + // Clone the response so both the client and the library could consume it. + const responseClone = response.clone(); + + sendToClient( + client, + { + type: 'RESPONSE', + payload: { + isMockedResponse: IS_MOCKED_RESPONSE in response, + request: { + id: requestId, + ...serializedRequest, + }, + response: { + type: responseClone.type, + status: responseClone.status, + statusText: responseClone.statusText, + headers: Object.fromEntries(responseClone.headers.entries()), + body: responseClone.body, + }, + }, + }, + responseClone.body ? [serializedRequest.body, responseClone.body] : [], + ); + } - return response + return response; } /** @@ -172,30 +169,30 @@ async function handleRequest(event, requestId) { * @returns {Promise} */ async function resolveMainClient(event) { - const client = await self.clients.get(event.clientId) - - if (activeClientIds.has(event.clientId)) { - return client - } - - if (client?.frameType === 'top-level') { - return client - } - - const allClients = await self.clients.matchAll({ - type: 'window', - }) - - return allClients - .filter((client) => { - // Get only those clients that are currently visible. - return client.visibilityState === 'visible' - }) - .find((client) => { - // Find the client ID that's recorded in the - // set of clients that have registered the worker. - return activeClientIds.has(client.id) - }) + const client = await self.clients.get(event.clientId); + + if (activeClientIds.has(event.clientId)) { + return client; + } + + if (client?.frameType === 'top-level') { + return client; + } + + const allClients = await self.clients.matchAll({ + type: 'window', + }); + + return allClients + .filter((client) => { + // Get only those clients that are currently visible. + return client.visibilityState === 'visible'; + }) + .find((client) => { + // Find the client ID that's recorded in the + // set of clients that have registered the worker. + return activeClientIds.has(client.id); + }); } /** @@ -205,73 +202,71 @@ async function resolveMainClient(event) { * @returns {Promise} */ async function getResponse(event, client, requestId) { - // Clone the request because it might've been already used - // (i.e. its body has been read and sent to the client). - const requestClone = event.request.clone() - - function passthrough() { - // Cast the request headers to a new Headers instance - // so the headers can be manipulated with. - const headers = new Headers(requestClone.headers) - - // Remove the "accept" header value that marked this request as passthrough. - // This prevents request alteration and also keeps it compliant with the - // user-defined CORS policies. - const acceptHeader = headers.get('accept') - if (acceptHeader) { - const values = acceptHeader.split(',').map((value) => value.trim()) - const filteredValues = values.filter( - (value) => value !== 'msw/passthrough', - ) - - if (filteredValues.length > 0) { - headers.set('accept', filteredValues.join(', ')) - } else { - headers.delete('accept') - } + // Clone the request because it might've been already used + // (i.e. its body has been read and sent to the client). + const requestClone = event.request.clone(); + + function passthrough() { + // Cast the request headers to a new Headers instance + // so the headers can be manipulated with. + const headers = new Headers(requestClone.headers); + + // Remove the "accept" header value that marked this request as passthrough. + // This prevents request alteration and also keeps it compliant with the + // user-defined CORS policies. + const acceptHeader = headers.get('accept'); + if (acceptHeader) { + const values = acceptHeader.split(',').map((value) => value.trim()); + const filteredValues = values.filter((value) => value !== 'msw/passthrough'); + + if (filteredValues.length > 0) { + headers.set('accept', filteredValues.join(', ')); + } else { + headers.delete('accept'); + } + } + + return fetch(requestClone, { headers }); } - return fetch(requestClone, { headers }) - } - - // Bypass mocking when the client is not active. - if (!client) { - return passthrough() - } - - // Bypass initial page load requests (i.e. static assets). - // The absence of the immediate/parent client in the map of the active clients - // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet - // and is not ready to handle requests. - if (!activeClientIds.has(client.id)) { - return passthrough() - } - - // Notify the client that a request has been intercepted. - const serializedRequest = await serializeRequest(event.request) - const clientMessage = await sendToClient( - client, - { - type: 'REQUEST', - payload: { - id: requestId, - ...serializedRequest, - }, - }, - [serializedRequest.body], - ) - - switch (clientMessage.type) { - case 'MOCK_RESPONSE': { - return respondWithMock(clientMessage.data) + // Bypass mocking when the client is not active. + if (!client) { + return passthrough(); } - case 'PASSTHROUGH': { - return passthrough() + // Bypass initial page load requests (i.e. static assets). + // The absence of the immediate/parent client in the map of the active clients + // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet + // and is not ready to handle requests. + if (!activeClientIds.has(client.id)) { + return passthrough(); + } + + // Notify the client that a request has been intercepted. + const serializedRequest = await serializeRequest(event.request); + const clientMessage = await sendToClient( + client, + { + type: 'REQUEST', + payload: { + id: requestId, + ...serializedRequest, + }, + }, + [serializedRequest.body], + ); + + switch (clientMessage.type) { + case 'MOCK_RESPONSE': { + return respondWithMock(clientMessage.data); + } + + case 'PASSTHROUGH': { + return passthrough(); + } } - } - return passthrough() + return passthrough(); } /** @@ -281,22 +276,19 @@ async function getResponse(event, client, requestId) { * @returns {Promise} */ function sendToClient(client, message, transferrables = []) { - return new Promise((resolve, reject) => { - const channel = new MessageChannel() + return new Promise((resolve, reject) => { + const channel = new MessageChannel(); - channel.port1.onmessage = (event) => { - if (event.data && event.data.error) { - return reject(event.data.error) - } + channel.port1.onmessage = (event) => { + if (event.data && event.data.error) { + return reject(event.data.error); + } - resolve(event.data) - } + resolve(event.data); + }; - client.postMessage(message, [ - channel.port2, - ...transferrables.filter(Boolean), - ]) - }) + client.postMessage(message, [channel.port2, ...transferrables.filter(Boolean)]); + }); } /** @@ -304,41 +296,41 @@ function sendToClient(client, message, transferrables = []) { * @returns {Response} */ function respondWithMock(response) { - // Setting response status code to 0 is a no-op. - // However, when responding with a "Response.error()", the produced Response - // instance will have status code set to 0. Since it's not possible to create - // a Response instance with status code 0, handle that use-case separately. - if (response.status === 0) { - return Response.error() - } - - const mockedResponse = new Response(response.body, response) - - Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, { - value: true, - enumerable: true, - }) - - return mockedResponse + // Setting response status code to 0 is a no-op. + // However, when responding with a "Response.error()", the produced Response + // instance will have status code set to 0. Since it's not possible to create + // a Response instance with status code 0, handle that use-case separately. + if (response.status === 0) { + return Response.error(); + } + + const mockedResponse = new Response(response.body, response); + + Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, { + value: true, + enumerable: true, + }); + + return mockedResponse; } /** * @param {Request} request */ async function serializeRequest(request) { - return { - url: request.url, - mode: request.mode, - method: request.method, - headers: Object.fromEntries(request.headers.entries()), - cache: request.cache, - credentials: request.credentials, - destination: request.destination, - integrity: request.integrity, - redirect: request.redirect, - referrer: request.referrer, - referrerPolicy: request.referrerPolicy, - body: await request.arrayBuffer(), - keepalive: request.keepalive, - } + return { + url: request.url, + mode: request.mode, + method: request.method, + headers: Object.fromEntries(request.headers.entries()), + cache: request.cache, + credentials: request.credentials, + destination: request.destination, + integrity: request.integrity, + redirect: request.redirect, + referrer: request.referrer, + referrerPolicy: request.referrerPolicy, + body: await request.arrayBuffer(), + keepalive: request.keepalive, + }; } diff --git a/apps/pleiepenger-sykt-barn/eslint.config.js b/apps/pleiepenger-sykt-barn/eslint.config.js index 0c73cfb2c2..1b86b5e95f 100644 --- a/apps/pleiepenger-sykt-barn/eslint.config.js +++ b/apps/pleiepenger-sykt-barn/eslint.config.js @@ -1,5 +1,5 @@ // For more info, see https://github.com/storybookjs/eslint-plugin-storybook#configuration-flat-config-format -import storybook from "eslint-plugin-storybook"; +import storybook from 'eslint-plugin-storybook'; import commonConfig from '@sif/eslint-config'; diff --git a/apps/pleiepenger-sykt-barn/mockServiceWorker.js b/apps/pleiepenger-sykt-barn/mockServiceWorker.js index be4527c7ee..fff922cccf 100644 --- a/apps/pleiepenger-sykt-barn/mockServiceWorker.js +++ b/apps/pleiepenger-sykt-barn/mockServiceWorker.js @@ -7,160 +7,157 @@ * - Please do NOT modify this file. */ -const PACKAGE_VERSION = '2.10.4' -const INTEGRITY_CHECKSUM = 'f5825c521429caf22a4dd13b66e243af' -const IS_MOCKED_RESPONSE = Symbol('isMockedResponse') -const activeClientIds = new Set() +const PACKAGE_VERSION = '2.10.4'; +const INTEGRITY_CHECKSUM = 'f5825c521429caf22a4dd13b66e243af'; +const IS_MOCKED_RESPONSE = Symbol('isMockedResponse'); +const activeClientIds = new Set(); addEventListener('install', function () { - self.skipWaiting() -}) + self.skipWaiting(); +}); addEventListener('activate', function (event) { - event.waitUntil(self.clients.claim()) -}) + event.waitUntil(self.clients.claim()); +}); addEventListener('message', async function (event) { - const clientId = Reflect.get(event.source || {}, 'id') + const clientId = Reflect.get(event.source || {}, 'id'); - if (!clientId || !self.clients) { - return - } - - const client = await self.clients.get(clientId) - - if (!client) { - return - } + if (!clientId || !self.clients) { + return; + } - const allClients = await self.clients.matchAll({ - type: 'window', - }) + const client = await self.clients.get(clientId); - switch (event.data) { - case 'KEEPALIVE_REQUEST': { - sendToClient(client, { - type: 'KEEPALIVE_RESPONSE', - }) - break + if (!client) { + return; } - case 'INTEGRITY_CHECK_REQUEST': { - sendToClient(client, { - type: 'INTEGRITY_CHECK_RESPONSE', - payload: { - packageVersion: PACKAGE_VERSION, - checksum: INTEGRITY_CHECKSUM, - }, - }) - break + const allClients = await self.clients.matchAll({ + type: 'window', + }); + + switch (event.data) { + case 'KEEPALIVE_REQUEST': { + sendToClient(client, { + type: 'KEEPALIVE_RESPONSE', + }); + break; + } + + case 'INTEGRITY_CHECK_REQUEST': { + sendToClient(client, { + type: 'INTEGRITY_CHECK_RESPONSE', + payload: { + packageVersion: PACKAGE_VERSION, + checksum: INTEGRITY_CHECKSUM, + }, + }); + break; + } + + case 'MOCK_ACTIVATE': { + activeClientIds.add(clientId); + + sendToClient(client, { + type: 'MOCKING_ENABLED', + payload: { + client: { + id: client.id, + frameType: client.frameType, + }, + }, + }); + break; + } + + case 'MOCK_DEACTIVATE': { + activeClientIds.delete(clientId); + break; + } + + case 'CLIENT_CLOSED': { + activeClientIds.delete(clientId); + + const remainingClients = allClients.filter((client) => { + return client.id !== clientId; + }); + + // Unregister itself when there are no more clients + if (remainingClients.length === 0) { + self.registration.unregister(); + } + + break; + } } +}); - case 'MOCK_ACTIVATE': { - activeClientIds.add(clientId) - - sendToClient(client, { - type: 'MOCKING_ENABLED', - payload: { - client: { - id: client.id, - frameType: client.frameType, - }, - }, - }) - break +addEventListener('fetch', function (event) { + // Bypass navigation requests. + if (event.request.mode === 'navigate') { + return; } - case 'MOCK_DEACTIVATE': { - activeClientIds.delete(clientId) - break + // Opening the DevTools triggers the "only-if-cached" request + // that cannot be handled by the worker. Bypass such requests. + if (event.request.cache === 'only-if-cached' && event.request.mode !== 'same-origin') { + return; } - case 'CLIENT_CLOSED': { - activeClientIds.delete(clientId) - - const remainingClients = allClients.filter((client) => { - return client.id !== clientId - }) - - // Unregister itself when there are no more clients - if (remainingClients.length === 0) { - self.registration.unregister() - } - - break + // Bypass all requests when there are no active clients. + // Prevents the self-unregistered worked from handling requests + // after it's been deleted (still remains active until the next reload). + if (activeClientIds.size === 0) { + return; } - } -}) -addEventListener('fetch', function (event) { - // Bypass navigation requests. - if (event.request.mode === 'navigate') { - return - } - - // Opening the DevTools triggers the "only-if-cached" request - // that cannot be handled by the worker. Bypass such requests. - if ( - event.request.cache === 'only-if-cached' && - event.request.mode !== 'same-origin' - ) { - return - } - - // Bypass all requests when there are no active clients. - // Prevents the self-unregistered worked from handling requests - // after it's been deleted (still remains active until the next reload). - if (activeClientIds.size === 0) { - return - } - - const requestId = crypto.randomUUID() - event.respondWith(handleRequest(event, requestId)) -}) + const requestId = crypto.randomUUID(); + event.respondWith(handleRequest(event, requestId)); +}); /** * @param {FetchEvent} event * @param {string} requestId */ async function handleRequest(event, requestId) { - const client = await resolveMainClient(event) - const requestCloneForEvents = event.request.clone() - const response = await getResponse(event, client, requestId) - - // Send back the response clone for the "response:*" life-cycle events. - // Ensure MSW is active and ready to handle the message, otherwise - // this message will pend indefinitely. - if (client && activeClientIds.has(client.id)) { - const serializedRequest = await serializeRequest(requestCloneForEvents) - - // Clone the response so both the client and the library could consume it. - const responseClone = response.clone() - - sendToClient( - client, - { - type: 'RESPONSE', - payload: { - isMockedResponse: IS_MOCKED_RESPONSE in response, - request: { - id: requestId, - ...serializedRequest, - }, - response: { - type: responseClone.type, - status: responseClone.status, - statusText: responseClone.statusText, - headers: Object.fromEntries(responseClone.headers.entries()), - body: responseClone.body, - }, - }, - }, - responseClone.body ? [serializedRequest.body, responseClone.body] : [], - ) - } + const client = await resolveMainClient(event); + const requestCloneForEvents = event.request.clone(); + const response = await getResponse(event, client, requestId); + + // Send back the response clone for the "response:*" life-cycle events. + // Ensure MSW is active and ready to handle the message, otherwise + // this message will pend indefinitely. + if (client && activeClientIds.has(client.id)) { + const serializedRequest = await serializeRequest(requestCloneForEvents); + + // Clone the response so both the client and the library could consume it. + const responseClone = response.clone(); + + sendToClient( + client, + { + type: 'RESPONSE', + payload: { + isMockedResponse: IS_MOCKED_RESPONSE in response, + request: { + id: requestId, + ...serializedRequest, + }, + response: { + type: responseClone.type, + status: responseClone.status, + statusText: responseClone.statusText, + headers: Object.fromEntries(responseClone.headers.entries()), + body: responseClone.body, + }, + }, + }, + responseClone.body ? [serializedRequest.body, responseClone.body] : [], + ); + } - return response + return response; } /** @@ -172,30 +169,30 @@ async function handleRequest(event, requestId) { * @returns {Promise} */ async function resolveMainClient(event) { - const client = await self.clients.get(event.clientId) - - if (activeClientIds.has(event.clientId)) { - return client - } - - if (client?.frameType === 'top-level') { - return client - } - - const allClients = await self.clients.matchAll({ - type: 'window', - }) - - return allClients - .filter((client) => { - // Get only those clients that are currently visible. - return client.visibilityState === 'visible' - }) - .find((client) => { - // Find the client ID that's recorded in the - // set of clients that have registered the worker. - return activeClientIds.has(client.id) - }) + const client = await self.clients.get(event.clientId); + + if (activeClientIds.has(event.clientId)) { + return client; + } + + if (client?.frameType === 'top-level') { + return client; + } + + const allClients = await self.clients.matchAll({ + type: 'window', + }); + + return allClients + .filter((client) => { + // Get only those clients that are currently visible. + return client.visibilityState === 'visible'; + }) + .find((client) => { + // Find the client ID that's recorded in the + // set of clients that have registered the worker. + return activeClientIds.has(client.id); + }); } /** @@ -205,73 +202,71 @@ async function resolveMainClient(event) { * @returns {Promise} */ async function getResponse(event, client, requestId) { - // Clone the request because it might've been already used - // (i.e. its body has been read and sent to the client). - const requestClone = event.request.clone() - - function passthrough() { - // Cast the request headers to a new Headers instance - // so the headers can be manipulated with. - const headers = new Headers(requestClone.headers) - - // Remove the "accept" header value that marked this request as passthrough. - // This prevents request alteration and also keeps it compliant with the - // user-defined CORS policies. - const acceptHeader = headers.get('accept') - if (acceptHeader) { - const values = acceptHeader.split(',').map((value) => value.trim()) - const filteredValues = values.filter( - (value) => value !== 'msw/passthrough', - ) - - if (filteredValues.length > 0) { - headers.set('accept', filteredValues.join(', ')) - } else { - headers.delete('accept') - } + // Clone the request because it might've been already used + // (i.e. its body has been read and sent to the client). + const requestClone = event.request.clone(); + + function passthrough() { + // Cast the request headers to a new Headers instance + // so the headers can be manipulated with. + const headers = new Headers(requestClone.headers); + + // Remove the "accept" header value that marked this request as passthrough. + // This prevents request alteration and also keeps it compliant with the + // user-defined CORS policies. + const acceptHeader = headers.get('accept'); + if (acceptHeader) { + const values = acceptHeader.split(',').map((value) => value.trim()); + const filteredValues = values.filter((value) => value !== 'msw/passthrough'); + + if (filteredValues.length > 0) { + headers.set('accept', filteredValues.join(', ')); + } else { + headers.delete('accept'); + } + } + + return fetch(requestClone, { headers }); } - return fetch(requestClone, { headers }) - } - - // Bypass mocking when the client is not active. - if (!client) { - return passthrough() - } - - // Bypass initial page load requests (i.e. static assets). - // The absence of the immediate/parent client in the map of the active clients - // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet - // and is not ready to handle requests. - if (!activeClientIds.has(client.id)) { - return passthrough() - } - - // Notify the client that a request has been intercepted. - const serializedRequest = await serializeRequest(event.request) - const clientMessage = await sendToClient( - client, - { - type: 'REQUEST', - payload: { - id: requestId, - ...serializedRequest, - }, - }, - [serializedRequest.body], - ) - - switch (clientMessage.type) { - case 'MOCK_RESPONSE': { - return respondWithMock(clientMessage.data) + // Bypass mocking when the client is not active. + if (!client) { + return passthrough(); } - case 'PASSTHROUGH': { - return passthrough() + // Bypass initial page load requests (i.e. static assets). + // The absence of the immediate/parent client in the map of the active clients + // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet + // and is not ready to handle requests. + if (!activeClientIds.has(client.id)) { + return passthrough(); + } + + // Notify the client that a request has been intercepted. + const serializedRequest = await serializeRequest(event.request); + const clientMessage = await sendToClient( + client, + { + type: 'REQUEST', + payload: { + id: requestId, + ...serializedRequest, + }, + }, + [serializedRequest.body], + ); + + switch (clientMessage.type) { + case 'MOCK_RESPONSE': { + return respondWithMock(clientMessage.data); + } + + case 'PASSTHROUGH': { + return passthrough(); + } } - } - return passthrough() + return passthrough(); } /** @@ -281,22 +276,19 @@ async function getResponse(event, client, requestId) { * @returns {Promise} */ function sendToClient(client, message, transferrables = []) { - return new Promise((resolve, reject) => { - const channel = new MessageChannel() + return new Promise((resolve, reject) => { + const channel = new MessageChannel(); - channel.port1.onmessage = (event) => { - if (event.data && event.data.error) { - return reject(event.data.error) - } + channel.port1.onmessage = (event) => { + if (event.data && event.data.error) { + return reject(event.data.error); + } - resolve(event.data) - } + resolve(event.data); + }; - client.postMessage(message, [ - channel.port2, - ...transferrables.filter(Boolean), - ]) - }) + client.postMessage(message, [channel.port2, ...transferrables.filter(Boolean)]); + }); } /** @@ -304,41 +296,41 @@ function sendToClient(client, message, transferrables = []) { * @returns {Response} */ function respondWithMock(response) { - // Setting response status code to 0 is a no-op. - // However, when responding with a "Response.error()", the produced Response - // instance will have status code set to 0. Since it's not possible to create - // a Response instance with status code 0, handle that use-case separately. - if (response.status === 0) { - return Response.error() - } - - const mockedResponse = new Response(response.body, response) - - Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, { - value: true, - enumerable: true, - }) - - return mockedResponse + // Setting response status code to 0 is a no-op. + // However, when responding with a "Response.error()", the produced Response + // instance will have status code set to 0. Since it's not possible to create + // a Response instance with status code 0, handle that use-case separately. + if (response.status === 0) { + return Response.error(); + } + + const mockedResponse = new Response(response.body, response); + + Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, { + value: true, + enumerable: true, + }); + + return mockedResponse; } /** * @param {Request} request */ async function serializeRequest(request) { - return { - url: request.url, - mode: request.mode, - method: request.method, - headers: Object.fromEntries(request.headers.entries()), - cache: request.cache, - credentials: request.credentials, - destination: request.destination, - integrity: request.integrity, - redirect: request.redirect, - referrer: request.referrer, - referrerPolicy: request.referrerPolicy, - body: await request.arrayBuffer(), - keepalive: request.keepalive, - } + return { + url: request.url, + mode: request.mode, + method: request.method, + headers: Object.fromEntries(request.headers.entries()), + cache: request.cache, + credentials: request.credentials, + destination: request.destination, + integrity: request.integrity, + redirect: request.redirect, + referrer: request.referrer, + referrerPolicy: request.referrerPolicy, + body: await request.arrayBuffer(), + keepalive: request.keepalive, + }; } diff --git a/apps/sif-ettersending/mockServiceWorker.js b/apps/sif-ettersending/mockServiceWorker.js index be4527c7ee..fff922cccf 100644 --- a/apps/sif-ettersending/mockServiceWorker.js +++ b/apps/sif-ettersending/mockServiceWorker.js @@ -7,160 +7,157 @@ * - Please do NOT modify this file. */ -const PACKAGE_VERSION = '2.10.4' -const INTEGRITY_CHECKSUM = 'f5825c521429caf22a4dd13b66e243af' -const IS_MOCKED_RESPONSE = Symbol('isMockedResponse') -const activeClientIds = new Set() +const PACKAGE_VERSION = '2.10.4'; +const INTEGRITY_CHECKSUM = 'f5825c521429caf22a4dd13b66e243af'; +const IS_MOCKED_RESPONSE = Symbol('isMockedResponse'); +const activeClientIds = new Set(); addEventListener('install', function () { - self.skipWaiting() -}) + self.skipWaiting(); +}); addEventListener('activate', function (event) { - event.waitUntil(self.clients.claim()) -}) + event.waitUntil(self.clients.claim()); +}); addEventListener('message', async function (event) { - const clientId = Reflect.get(event.source || {}, 'id') + const clientId = Reflect.get(event.source || {}, 'id'); - if (!clientId || !self.clients) { - return - } - - const client = await self.clients.get(clientId) - - if (!client) { - return - } + if (!clientId || !self.clients) { + return; + } - const allClients = await self.clients.matchAll({ - type: 'window', - }) + const client = await self.clients.get(clientId); - switch (event.data) { - case 'KEEPALIVE_REQUEST': { - sendToClient(client, { - type: 'KEEPALIVE_RESPONSE', - }) - break + if (!client) { + return; } - case 'INTEGRITY_CHECK_REQUEST': { - sendToClient(client, { - type: 'INTEGRITY_CHECK_RESPONSE', - payload: { - packageVersion: PACKAGE_VERSION, - checksum: INTEGRITY_CHECKSUM, - }, - }) - break + const allClients = await self.clients.matchAll({ + type: 'window', + }); + + switch (event.data) { + case 'KEEPALIVE_REQUEST': { + sendToClient(client, { + type: 'KEEPALIVE_RESPONSE', + }); + break; + } + + case 'INTEGRITY_CHECK_REQUEST': { + sendToClient(client, { + type: 'INTEGRITY_CHECK_RESPONSE', + payload: { + packageVersion: PACKAGE_VERSION, + checksum: INTEGRITY_CHECKSUM, + }, + }); + break; + } + + case 'MOCK_ACTIVATE': { + activeClientIds.add(clientId); + + sendToClient(client, { + type: 'MOCKING_ENABLED', + payload: { + client: { + id: client.id, + frameType: client.frameType, + }, + }, + }); + break; + } + + case 'MOCK_DEACTIVATE': { + activeClientIds.delete(clientId); + break; + } + + case 'CLIENT_CLOSED': { + activeClientIds.delete(clientId); + + const remainingClients = allClients.filter((client) => { + return client.id !== clientId; + }); + + // Unregister itself when there are no more clients + if (remainingClients.length === 0) { + self.registration.unregister(); + } + + break; + } } +}); - case 'MOCK_ACTIVATE': { - activeClientIds.add(clientId) - - sendToClient(client, { - type: 'MOCKING_ENABLED', - payload: { - client: { - id: client.id, - frameType: client.frameType, - }, - }, - }) - break +addEventListener('fetch', function (event) { + // Bypass navigation requests. + if (event.request.mode === 'navigate') { + return; } - case 'MOCK_DEACTIVATE': { - activeClientIds.delete(clientId) - break + // Opening the DevTools triggers the "only-if-cached" request + // that cannot be handled by the worker. Bypass such requests. + if (event.request.cache === 'only-if-cached' && event.request.mode !== 'same-origin') { + return; } - case 'CLIENT_CLOSED': { - activeClientIds.delete(clientId) - - const remainingClients = allClients.filter((client) => { - return client.id !== clientId - }) - - // Unregister itself when there are no more clients - if (remainingClients.length === 0) { - self.registration.unregister() - } - - break + // Bypass all requests when there are no active clients. + // Prevents the self-unregistered worked from handling requests + // after it's been deleted (still remains active until the next reload). + if (activeClientIds.size === 0) { + return; } - } -}) -addEventListener('fetch', function (event) { - // Bypass navigation requests. - if (event.request.mode === 'navigate') { - return - } - - // Opening the DevTools triggers the "only-if-cached" request - // that cannot be handled by the worker. Bypass such requests. - if ( - event.request.cache === 'only-if-cached' && - event.request.mode !== 'same-origin' - ) { - return - } - - // Bypass all requests when there are no active clients. - // Prevents the self-unregistered worked from handling requests - // after it's been deleted (still remains active until the next reload). - if (activeClientIds.size === 0) { - return - } - - const requestId = crypto.randomUUID() - event.respondWith(handleRequest(event, requestId)) -}) + const requestId = crypto.randomUUID(); + event.respondWith(handleRequest(event, requestId)); +}); /** * @param {FetchEvent} event * @param {string} requestId */ async function handleRequest(event, requestId) { - const client = await resolveMainClient(event) - const requestCloneForEvents = event.request.clone() - const response = await getResponse(event, client, requestId) - - // Send back the response clone for the "response:*" life-cycle events. - // Ensure MSW is active and ready to handle the message, otherwise - // this message will pend indefinitely. - if (client && activeClientIds.has(client.id)) { - const serializedRequest = await serializeRequest(requestCloneForEvents) - - // Clone the response so both the client and the library could consume it. - const responseClone = response.clone() - - sendToClient( - client, - { - type: 'RESPONSE', - payload: { - isMockedResponse: IS_MOCKED_RESPONSE in response, - request: { - id: requestId, - ...serializedRequest, - }, - response: { - type: responseClone.type, - status: responseClone.status, - statusText: responseClone.statusText, - headers: Object.fromEntries(responseClone.headers.entries()), - body: responseClone.body, - }, - }, - }, - responseClone.body ? [serializedRequest.body, responseClone.body] : [], - ) - } + const client = await resolveMainClient(event); + const requestCloneForEvents = event.request.clone(); + const response = await getResponse(event, client, requestId); + + // Send back the response clone for the "response:*" life-cycle events. + // Ensure MSW is active and ready to handle the message, otherwise + // this message will pend indefinitely. + if (client && activeClientIds.has(client.id)) { + const serializedRequest = await serializeRequest(requestCloneForEvents); + + // Clone the response so both the client and the library could consume it. + const responseClone = response.clone(); + + sendToClient( + client, + { + type: 'RESPONSE', + payload: { + isMockedResponse: IS_MOCKED_RESPONSE in response, + request: { + id: requestId, + ...serializedRequest, + }, + response: { + type: responseClone.type, + status: responseClone.status, + statusText: responseClone.statusText, + headers: Object.fromEntries(responseClone.headers.entries()), + body: responseClone.body, + }, + }, + }, + responseClone.body ? [serializedRequest.body, responseClone.body] : [], + ); + } - return response + return response; } /** @@ -172,30 +169,30 @@ async function handleRequest(event, requestId) { * @returns {Promise} */ async function resolveMainClient(event) { - const client = await self.clients.get(event.clientId) - - if (activeClientIds.has(event.clientId)) { - return client - } - - if (client?.frameType === 'top-level') { - return client - } - - const allClients = await self.clients.matchAll({ - type: 'window', - }) - - return allClients - .filter((client) => { - // Get only those clients that are currently visible. - return client.visibilityState === 'visible' - }) - .find((client) => { - // Find the client ID that's recorded in the - // set of clients that have registered the worker. - return activeClientIds.has(client.id) - }) + const client = await self.clients.get(event.clientId); + + if (activeClientIds.has(event.clientId)) { + return client; + } + + if (client?.frameType === 'top-level') { + return client; + } + + const allClients = await self.clients.matchAll({ + type: 'window', + }); + + return allClients + .filter((client) => { + // Get only those clients that are currently visible. + return client.visibilityState === 'visible'; + }) + .find((client) => { + // Find the client ID that's recorded in the + // set of clients that have registered the worker. + return activeClientIds.has(client.id); + }); } /** @@ -205,73 +202,71 @@ async function resolveMainClient(event) { * @returns {Promise} */ async function getResponse(event, client, requestId) { - // Clone the request because it might've been already used - // (i.e. its body has been read and sent to the client). - const requestClone = event.request.clone() - - function passthrough() { - // Cast the request headers to a new Headers instance - // so the headers can be manipulated with. - const headers = new Headers(requestClone.headers) - - // Remove the "accept" header value that marked this request as passthrough. - // This prevents request alteration and also keeps it compliant with the - // user-defined CORS policies. - const acceptHeader = headers.get('accept') - if (acceptHeader) { - const values = acceptHeader.split(',').map((value) => value.trim()) - const filteredValues = values.filter( - (value) => value !== 'msw/passthrough', - ) - - if (filteredValues.length > 0) { - headers.set('accept', filteredValues.join(', ')) - } else { - headers.delete('accept') - } + // Clone the request because it might've been already used + // (i.e. its body has been read and sent to the client). + const requestClone = event.request.clone(); + + function passthrough() { + // Cast the request headers to a new Headers instance + // so the headers can be manipulated with. + const headers = new Headers(requestClone.headers); + + // Remove the "accept" header value that marked this request as passthrough. + // This prevents request alteration and also keeps it compliant with the + // user-defined CORS policies. + const acceptHeader = headers.get('accept'); + if (acceptHeader) { + const values = acceptHeader.split(',').map((value) => value.trim()); + const filteredValues = values.filter((value) => value !== 'msw/passthrough'); + + if (filteredValues.length > 0) { + headers.set('accept', filteredValues.join(', ')); + } else { + headers.delete('accept'); + } + } + + return fetch(requestClone, { headers }); } - return fetch(requestClone, { headers }) - } - - // Bypass mocking when the client is not active. - if (!client) { - return passthrough() - } - - // Bypass initial page load requests (i.e. static assets). - // The absence of the immediate/parent client in the map of the active clients - // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet - // and is not ready to handle requests. - if (!activeClientIds.has(client.id)) { - return passthrough() - } - - // Notify the client that a request has been intercepted. - const serializedRequest = await serializeRequest(event.request) - const clientMessage = await sendToClient( - client, - { - type: 'REQUEST', - payload: { - id: requestId, - ...serializedRequest, - }, - }, - [serializedRequest.body], - ) - - switch (clientMessage.type) { - case 'MOCK_RESPONSE': { - return respondWithMock(clientMessage.data) + // Bypass mocking when the client is not active. + if (!client) { + return passthrough(); } - case 'PASSTHROUGH': { - return passthrough() + // Bypass initial page load requests (i.e. static assets). + // The absence of the immediate/parent client in the map of the active clients + // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet + // and is not ready to handle requests. + if (!activeClientIds.has(client.id)) { + return passthrough(); + } + + // Notify the client that a request has been intercepted. + const serializedRequest = await serializeRequest(event.request); + const clientMessage = await sendToClient( + client, + { + type: 'REQUEST', + payload: { + id: requestId, + ...serializedRequest, + }, + }, + [serializedRequest.body], + ); + + switch (clientMessage.type) { + case 'MOCK_RESPONSE': { + return respondWithMock(clientMessage.data); + } + + case 'PASSTHROUGH': { + return passthrough(); + } } - } - return passthrough() + return passthrough(); } /** @@ -281,22 +276,19 @@ async function getResponse(event, client, requestId) { * @returns {Promise} */ function sendToClient(client, message, transferrables = []) { - return new Promise((resolve, reject) => { - const channel = new MessageChannel() + return new Promise((resolve, reject) => { + const channel = new MessageChannel(); - channel.port1.onmessage = (event) => { - if (event.data && event.data.error) { - return reject(event.data.error) - } + channel.port1.onmessage = (event) => { + if (event.data && event.data.error) { + return reject(event.data.error); + } - resolve(event.data) - } + resolve(event.data); + }; - client.postMessage(message, [ - channel.port2, - ...transferrables.filter(Boolean), - ]) - }) + client.postMessage(message, [channel.port2, ...transferrables.filter(Boolean)]); + }); } /** @@ -304,41 +296,41 @@ function sendToClient(client, message, transferrables = []) { * @returns {Response} */ function respondWithMock(response) { - // Setting response status code to 0 is a no-op. - // However, when responding with a "Response.error()", the produced Response - // instance will have status code set to 0. Since it's not possible to create - // a Response instance with status code 0, handle that use-case separately. - if (response.status === 0) { - return Response.error() - } - - const mockedResponse = new Response(response.body, response) - - Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, { - value: true, - enumerable: true, - }) - - return mockedResponse + // Setting response status code to 0 is a no-op. + // However, when responding with a "Response.error()", the produced Response + // instance will have status code set to 0. Since it's not possible to create + // a Response instance with status code 0, handle that use-case separately. + if (response.status === 0) { + return Response.error(); + } + + const mockedResponse = new Response(response.body, response); + + Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, { + value: true, + enumerable: true, + }); + + return mockedResponse; } /** * @param {Request} request */ async function serializeRequest(request) { - return { - url: request.url, - mode: request.mode, - method: request.method, - headers: Object.fromEntries(request.headers.entries()), - cache: request.cache, - credentials: request.credentials, - destination: request.destination, - integrity: request.integrity, - redirect: request.redirect, - referrer: request.referrer, - referrerPolicy: request.referrerPolicy, - body: await request.arrayBuffer(), - keepalive: request.keepalive, - } + return { + url: request.url, + mode: request.mode, + method: request.method, + headers: Object.fromEntries(request.headers.entries()), + cache: request.cache, + credentials: request.credentials, + destination: request.destination, + integrity: request.integrity, + redirect: request.redirect, + referrer: request.referrer, + referrerPolicy: request.referrerPolicy, + body: await request.arrayBuffer(), + keepalive: request.keepalive, + }; } diff --git a/apps/ungdomsytelse-veileder/.storybook/vitest.setup.ts b/apps/ungdomsytelse-veileder/.storybook/vitest.setup.ts index 995d892d91..1b5bc393f3 100644 --- a/apps/ungdomsytelse-veileder/.storybook/vitest.setup.ts +++ b/apps/ungdomsytelse-veileder/.storybook/vitest.setup.ts @@ -6,4 +6,4 @@ import * as projectAnnotations from './preview'; // More info at: https://storybook.js.org/docs/api/portable-stories/portable-stories-vitest#setprojectannotations const project = setProjectAnnotations([projectAnnotations]); -beforeAll(project.beforeAll); \ No newline at end of file +beforeAll(project.beforeAll); diff --git a/apps/ungdomsytelse-veileder/vitest.shims.d.ts b/apps/ungdomsytelse-veileder/vitest.shims.d.ts index f923d47d48..a1d31e5a7b 100644 --- a/apps/ungdomsytelse-veileder/vitest.shims.d.ts +++ b/apps/ungdomsytelse-veileder/vitest.shims.d.ts @@ -1 +1 @@ -/// \ No newline at end of file +/// diff --git a/packages/sif-common-utils/src/dateRangeUtils.ts b/packages/sif-common-utils/src/dateRangeUtils.ts index 3f70a3d2bb..3f361c1a5c 100644 --- a/packages/sif-common-utils/src/dateRangeUtils.ts +++ b/packages/sif-common-utils/src/dateRangeUtils.ts @@ -744,6 +744,13 @@ export const getFirstDateInDateRanges = (dateRanges: DateRange[]): Date | undefi return dates[0]; }; +export const ensureDateRange = (maybeDateRange: MaybeDateRange, fallbackDateRange: DateRange): DateRange => { + return { + from: maybeDateRange.from || fallbackDateRange.from, + to: maybeDateRange.to || fallbackDateRange.to, + }; +}; + // const dateRangeDifference = (range1: DateRange[], range2: DateRange[]): DateRange[] { // const difference: DateRange[] = []; // range1.forEach((r1) => { @@ -774,6 +781,7 @@ export const dateRangeUtils = { dateRangeIsAdjacentToDateRange, dateRangesCollide, dateRangeToISODateRange, + ensureDateRange, datesCollideWithDateRanges, getDateRangeFromDates, getDateRangeFromDateRanges,