Skip to content

Commit

Permalink
Merge branch 'main' into MIJN-9836-disclaimer-tekst-bij-hulpmiddelen-…
Browse files Browse the repository at this point in the history
…van-1-11-acc-prod-meldingen
  • Loading branch information
OscarBakker authored Dec 19, 2024
2 parents a371380 + 5a5bccc commit fa62dd8
Show file tree
Hide file tree
Showing 13 changed files with 175 additions and 48 deletions.
15 changes: 11 additions & 4 deletions mocks/routes/cms.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const settings = require('../settings');
const loadFixtureAndReplaceBaseUrl = require('../loadFixtureAndReplaceBaseUrl');
const settings = require('../settings');

const ALLE_RESPONSE = loadFixtureAndReplaceBaseUrl(
'cms-maintenance-notifications-alle.json'
Expand Down Expand Up @@ -65,10 +65,17 @@ module.exports = [
variants: [
{
id: 'standard',
type: 'json',
type: 'middleware',
options: {
status: 200,
body: PRODUCTEN_OP_MA,
middleware: (req, res, next, core) => {
const { articleslug } = req.params;
if (articleslug === 'overzicht-producten-ondernemers') {
const productenOndernemer = structuredClone(PRODUCTEN_OP_MA);
productenOndernemer.applicatie.inhoud.inleiding = `<p><strong>Mock content voor BEDRIJVEN</strong></p>`;
return res.send(productenOndernemer);
}
return res.send(PRODUCTEN_OP_MA);
},
},
},
],
Expand Down
16 changes: 12 additions & 4 deletions src/client/pages/Parkeren/Parkeren.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@ describe('Parkeren', () => {
);
}

function initializeState(snapshot: MutableSnapshot) {
snapshot.set(appStateAtom, testState);
}
beforeAll(() => {
window.scrollTo = vi.fn();
});
Expand Down Expand Up @@ -80,7 +77,14 @@ describe('determinePageContentTop', () => {

test('Renders button with parkeer vergunningen', () => {
const PageContentTop = determinePageContentTop(true, EXTERNAL_PARKEREN_URL);
const screen = render(<PageContentTop />);
const screen = render(
<MockApp
routeEntry="/"
routePath="/"
component={PageContentTop}
initializeState={initializeState}
/>
);
expect(screen.queryByText(linkButtonTxt)).toBeInTheDocument();
});

Expand All @@ -94,6 +98,10 @@ describe('determinePageContentTop', () => {
});
});

function initializeState(snapshot: MutableSnapshot) {
snapshot.set(appStateAtom, testState);
}

const testState = {
PARKEREN: {
content: {
Expand Down
15 changes: 12 additions & 3 deletions src/client/pages/Parkeren/Parkeren.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { VergunningFrontendV2 } from '../../../server/services/vergunningen-v2/c
import { AppRoutes } from '../../../universal/config/routes';
import { MaButtonLink } from '../../components/MaLink/MaLink';
import { ThemaTitles } from '../../config/thema';
import { useProfileTypeValue } from '../../hooks/useProfileType';
import ThemaPagina from '../ThemaPagina/ThemaPagina';
import ThemaPaginaTable from '../ThemaPagina/ThemaPaginaTable';

Expand Down Expand Up @@ -63,12 +64,20 @@ function determinePageContentTop(
parkerenUrlSSO: string
) {
if (hasMijnParkerenVergunningen) {
const profileType = useProfileTypeValue();

const profileTypeLabel =
profileType === 'commercial' ? 'bedrijven' : 'bewoners';

return (
<>
<Alert severity="info" heading="Parkeervergunning voor bewoners">
<Alert
severity="info"
heading={`Parkeervergunning voor ${profileTypeLabel}`}
>
<Paragraph>
Het inzien, aanvragen of wijzigen van een parkeervergunning voor
bewoners kan via Mijn Parkeren.
Het inzien, aanvragen of wijzigen van een parkeervergunning voor{' '}
{profileTypeLabel} kan via Mijn Parkeren.
</Paragraph>
<Paragraph>
<MaButtonLink href={parkerenUrlSSO}>
Expand Down
25 changes: 23 additions & 2 deletions src/client/pages/ZaakStatus/ZaakStatus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { useAppStateGetter, useAppStateReady } from '../../hooks/useAppState';
const ITEM_NOT_FOUND = 'not-found';
const STATE_ERROR = 'state-error';

type ThemaQueryParam = 'vergunningen';
type ThemaQueryParam = 'vergunningen' | 'toeristischeVerhuur';

type PageRouteResolver = {
baseRoute: AppRoute;
Expand All @@ -41,13 +41,34 @@ const pageRouteResolvers: PageRouteResolvers = {
}
if (!isLoading(appState.VERGUNNINGEN)) {
return (
appState.VERGUNNINGEN.content?.find(
(appState.VERGUNNINGEN.content || []).find(
(vergunning) => vergunning.identifier === detailPageItemId
)?.link.to ?? ITEM_NOT_FOUND
);
}
},
},
toeristischeVerhuur: {
baseRoute: AppRoutes.TOERISTISCHE_VERHUUR,
getRoute: (detailPageItemId, appState) => {
if (isError(appState.TOERISTISCHE_VERHUUR)) {
return STATE_ERROR;
}

if (!isLoading(appState.TOERISTISCHE_VERHUUR)) {
return (
(
appState.TOERISTISCHE_VERHUUR.content
?.vakantieverhuurVergunningen || []
).find((toeristischeVerhuur) => {
if (toeristischeVerhuur.zaaknummer === detailPageItemId) {
return toeristischeVerhuur;
}
})?.link.to ?? ITEM_NOT_FOUND
);
}
},
},
};

function useNavigateToPage(queryParams: URLSearchParams) {
Expand Down
4 changes: 0 additions & 4 deletions src/mijnamsterdam.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@ type ReturnTypeAsync<T extends (...args: any) => any> = T extends (
? R
: any;

type ProfileType = 'private' | 'private-attributes' | 'commercial';

type AuthMethod = 'digid' | 'eherkenning';

type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;

type Prettify<T> = {
Expand Down
5 changes: 5 additions & 0 deletions src/server/auth/auth-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
} from './auth-types';
import { FeatureToggle } from '../../universal/config/feature-toggles';
import { AppRoutes } from '../../universal/config/routes';
import { PROFILE_TYPES } from '../../universal/types/App.types';
import { ExternalConsumerEndpoints } from '../routing/bff-routes';
import { generateFullApiUrlBFF } from '../routing/route-helpers';
import { captureException } from '../services/monitoring';
Expand Down Expand Up @@ -172,3 +173,7 @@ export function createLogoutHandler(
return res.redirect(postLogoutRedirectUrl);
};
}

export function isValidProfileType(profileType: unknown) {
return PROFILE_TYPES.includes(profileType as ProfileType);
}
7 changes: 1 addition & 6 deletions src/server/config/source-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ export interface DataRequestConfig extends AxiosRequestConfig {
cacheTimeout?: number;
cancelTimeout?: number;
postponeFetch?: boolean;
urls?: Record<string, string>;

// Construct an url that will be assigned to the url key in the local requestConfig.
// Example: formatUrl: (requestConfig) => requestConfig.url + '/some/additional/path/segments/,
Expand Down Expand Up @@ -205,11 +204,7 @@ export const ApiConfig: ApiDataRequestConfig = {
CMS_CONTENT_GENERAL_INFO: {
// eslint-disable-next-line no-magic-numbers
cacheTimeout: 4 * ONE_HOUR_MS,
urls: {
private: `${getFromEnv('BFF_CMS_BASE_URL')}/mijn-content/artikelen/ziet-amsterdam/?AppIdt=app-data`,
'private-attributes': `${getFromEnv('BFF_CMS_BASE_URL')}/mijn-content/artikelen/ziet-amsterdam/?AppIdt=app-data`,
commercial: `${getFromEnv('BFF_CMS_BASE_URL')}/mijn-content/artikelen/overzicht-producten-ondernemers/?AppIdt=app-data`,
},
url: `${getFromEnv('BFF_CMS_BASE_URL')}/mijn-content/artikelen`,
},
CMS_CONTENT_FOOTER: {
url: `${getFromEnv('BFF_CMS_BASE_URL')}/algemene_onderdelen/overige/footer/?AppIdt=app-data`,
Expand Down
10 changes: 2 additions & 8 deletions src/server/services/afis/afis-facturen.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ const ROUTES = {
},
deelbetalingen: (uri: string) =>
decodeURI(uri).includes(
`IsCleared eq false and InvoiceReference ne '' and (AccountingDocumentType eq 'AB')`
`IsCleared eq false and InvoiceReference ne '' and`
),
};

Expand Down Expand Up @@ -699,13 +699,7 @@ describe('afis-facturen', async () => {
},
};

remoteApi
.get((uri) =>
decodeURI(uri).includes(
`IsCleared eq false and InvoiceReference ne '' and (AccountingDocumentType eq 'AB')`
)
)
.reply(200, deelbetalingenResponse);
remoteApi.get(ROUTES.deelbetalingen).reply(200, deelbetalingenResponse);

const params: AfisFacturenParams = {
state: 'deelbetalingen',
Expand Down
2 changes: 1 addition & 1 deletion src/server/services/afis/afis-facturen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const accountingDocumentTypesByState: Record<
open: ['DR', 'DG', 'DM', 'DE', 'DF', 'DV', 'DW'],
afgehandeld: ['DR', 'DE', 'DM', 'DV', 'DG', 'DF', 'DM', 'DW'],
overgedragen: ['DR', 'DE', 'DM', 'DV', 'DG', 'DF', 'DM', 'DW'],
deelbetalingen: ['AB'],
deelbetalingen: ['AB', 'BA'],
};

const select = `$select=IsCleared,ReverseDocument,Paylink,PostingDate,ProfitCenterName,DocumentReferenceID,AccountingDocument,AmountInBalanceTransacCrcy,NetDueDate,DunningLevel,DunningBlockingReason,SEPAMandate,ClearingDate,PaymentMethod`;
Expand Down
31 changes: 17 additions & 14 deletions src/server/services/cms-content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
} from '../../universal/helpers/api';
import { hash } from '../../universal/helpers/utils';
import { LinkProps } from '../../universal/types/App.types';
import { DataRequestConfig } from '../config/source-api';
import { isValidProfileType } from '../auth/auth-helpers';
import FileCache from '../helpers/file-cache';
import { getApiConfig } from '../helpers/source-api-helpers';
import { requestData } from '../helpers/source-api-request';
Expand Down Expand Up @@ -211,14 +211,14 @@ async function getGeneralPage(
sanitizeCmsContent(responseData.applicatie.inhoud.tekst),
};
},
formatUrl({ url }) {
return profileType === 'commercial'
? `${url}/overzicht-producten-ondernemers/?AppIdt=app-data`
: `${url}/ziet-amsterdam/?AppIdt=app-data`;
},
});

const requestConfigFinal: DataRequestConfig = {
...requestConfig,
url: requestConfig.urls![profileType],
};

return requestData<CMSPageContent>(requestConfigFinal, requestID).then(
return requestData<CMSPageContent>(requestConfig, requestID).then(
(apiData) => {
if (
apiData.status === 'OK' &&
Expand Down Expand Up @@ -285,11 +285,14 @@ async function fetchCmsBase(
requestID: RequestID,
query?: QueryParamsCMSFooter
) {
const forceRenew = !!(query?.forceRenew === 'true');

const forceRenew = query?.forceRenew === 'true';
const profileType =
query?.profileType && isValidProfileType(query?.profileType)
? query.profileType
: undefined;
const generalInfoPageRequest = getGeneralPage(
requestID,
query?.profileType as ProfileType,
profileType,
forceRenew
);

Expand All @@ -310,10 +313,10 @@ async function fetchCmsBase(
};
}

export interface QueryParamsCMSFooter extends Record<string, string> {
forceRenew: 'true';
profileType: ProfileType;
}
export type QueryParamsCMSFooter = {
forceRenew?: 'true';
profileType?: ProfileType;
};

export async function fetchCmsFooter(
requestID: RequestID,
Expand Down
68 changes: 67 additions & 1 deletion src/server/services/controller.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,19 @@ import {
vi,
} from 'vitest';

import { fetchCMSCONTENT } from './cms-content';
import {
addServiceResultHandler,
forTesting,
getServiceResultsForTips,
getTipNotifications,
servicesTipsByProfileType,
} from './controller';
import { getReqMockWithOidc, ResponseMock } from '../../testing/utils';
import {
getReqMockWithOidc,
RequestMock,
ResponseMock,
} from '../../testing/utils';

const mocks = vi.hoisted(() => {
return {
Expand All @@ -35,6 +41,12 @@ const mocks = vi.hoisted(() => {
};
});

vi.mock('./cms-content', () => {
return {
fetchCMSCONTENT: vi.fn(),
};
});

vi.mock('./tips-and-notifications', async () => {
return {
getTipsAndNotificationsFromApiResults: vi.fn(),
Expand Down Expand Up @@ -192,3 +204,57 @@ describe('controller', () => {
expect(result).toEqual(data);
});
});

describe('request handlers', () => {
describe('CMS_CONTENT', async () => {
const reqID = 'xx-req-id-yy';

test('profileType: private', async () => {
const reqMock = await getReqMockWithOidc({
sid: 'x123y',
authMethod: 'digid',
profileType: 'private',
id: '9988',
});

await forTesting.CMS_CONTENT(reqID, reqMock);

expect(fetchCMSCONTENT).toHaveBeenCalledWith(reqID, {
profileType: 'private',
});
});

test('profileType: commercial', async () => {
const reqMock = await getReqMockWithOidc({
sid: 'x123y',
authMethod: 'eherkenning',
profileType: 'commercial',
id: '9988',
});

await forTesting.CMS_CONTENT(reqID, reqMock);

expect(fetchCMSCONTENT).toHaveBeenCalledWith(reqID, {
profileType: 'commercial',
});
});

test('arbitrary query params are passed', async () => {
const reqMock = await getReqMockWithOidc({
sid: 'x123y',
authMethod: 'eherkenning',
profileType: 'commercial',
id: '9988',
});

(reqMock as unknown as RequestMock).setQuery({ forceRenew: 'true' });

await forTesting.CMS_CONTENT(reqID, reqMock);

expect(fetchCMSCONTENT).toHaveBeenCalledWith(reqID, {
profileType: 'commercial',
forceRenew: 'true',
});
});
});
});
Loading

0 comments on commit fa62dd8

Please sign in to comment.