diff --git a/mocks/routes/cms.js b/mocks/routes/cms.js
index 5cd8f38bb..5eab6c3d6 100644
--- a/mocks/routes/cms.js
+++ b/mocks/routes/cms.js
@@ -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'
@@ -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 = `
Mock content voor BEDRIJVEN
`;
+ return res.send(productenOndernemer);
+ }
+ return res.send(PRODUCTEN_OP_MA);
+ },
},
},
],
diff --git a/src/mijnamsterdam.d.ts b/src/mijnamsterdam.d.ts
index db2eb41cd..16f1d978f 100644
--- a/src/mijnamsterdam.d.ts
+++ b/src/mijnamsterdam.d.ts
@@ -22,10 +22,6 @@ type ReturnTypeAsync any> = T extends (
? R
: any;
-type ProfileType = 'private' | 'private-attributes' | 'commercial';
-
-type AuthMethod = 'digid' | 'eherkenning';
-
type Optional = Pick, K> & Omit;
type Prettify = {
diff --git a/src/server/auth/auth-helpers.ts b/src/server/auth/auth-helpers.ts
index 226a40d80..82b45b673 100644
--- a/src/server/auth/auth-helpers.ts
+++ b/src/server/auth/auth-helpers.ts
@@ -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';
@@ -172,3 +173,7 @@ export function createLogoutHandler(
return res.redirect(postLogoutRedirectUrl);
};
}
+
+export function isValidProfileType(profileType: unknown) {
+ return PROFILE_TYPES.includes(profileType as ProfileType);
+}
diff --git a/src/server/config/source-api.ts b/src/server/config/source-api.ts
index d4404aff7..e188d1d94 100644
--- a/src/server/config/source-api.ts
+++ b/src/server/config/source-api.ts
@@ -12,7 +12,6 @@ export interface DataRequestConfig extends AxiosRequestConfig {
cacheTimeout?: number;
cancelTimeout?: number;
postponeFetch?: boolean;
- urls?: Record;
// Construct an url that will be assigned to the url key in the local requestConfig.
// Example: formatUrl: (requestConfig) => requestConfig.url + '/some/additional/path/segments/,
@@ -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`,
diff --git a/src/server/services/cms-content.ts b/src/server/services/cms-content.ts
index 530ef4c4e..912819cfc 100644
--- a/src/server/services/cms-content.ts
+++ b/src/server/services/cms-content.ts
@@ -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';
@@ -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(requestConfigFinal, requestID).then(
+ return requestData(requestConfig, requestID).then(
(apiData) => {
if (
apiData.status === 'OK' &&
@@ -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
);
@@ -310,10 +313,10 @@ async function fetchCmsBase(
};
}
-export interface QueryParamsCMSFooter extends Record {
- forceRenew: 'true';
- profileType: ProfileType;
-}
+export type QueryParamsCMSFooter = {
+ forceRenew?: 'true';
+ profileType?: ProfileType;
+};
export async function fetchCmsFooter(
requestID: RequestID,
diff --git a/src/server/services/controller.test.ts b/src/server/services/controller.test.ts
index 2da3e1362..6a8661f14 100644
--- a/src/server/services/controller.test.ts
+++ b/src/server/services/controller.test.ts
@@ -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 {
@@ -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(),
@@ -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',
+ });
+ });
+ });
+});
diff --git a/src/server/services/controller.ts b/src/server/services/controller.ts
index 8bc047d20..4931c5c4d 100644
--- a/src/server/services/controller.ts
+++ b/src/server/services/controller.ts
@@ -117,7 +117,13 @@ export function addServiceResultHandler(
* The service methods
*/
// Public services
-const CMS_CONTENT = callPublicService(fetchCMSCONTENT);
+const CMS_CONTENT = (requestID: RequestID, req: Request) => {
+ const auth = getAuth(req);
+ return fetchCMSCONTENT(requestID, {
+ profileType: auth?.profile.profileType,
+ ...queryParams(req),
+ });
+};
const CMS_MAINTENANCE_NOTIFICATIONS = callPublicService(
fetchMaintenanceNotificationsActual
);
@@ -485,3 +491,7 @@ export async function getTipNotifications(
return [];
}
+
+export const forTesting = {
+ CMS_CONTENT,
+};
diff --git a/src/universal/types/App.types.ts b/src/universal/types/App.types.ts
index 31a6b7015..910c3f518 100644
--- a/src/universal/types/App.types.ts
+++ b/src/universal/types/App.types.ts
@@ -122,3 +122,16 @@ export interface Match {
path: string;
url: string;
}
+
+export const PROFILE_TYPES = [
+ 'private',
+ 'commercial',
+ 'private-attributes',
+] as const;
+
+export const AUTH_METHODS = ['eherkenning', 'digid'] as const;
+
+declare global {
+ type ProfileType = (typeof PROFILE_TYPES)[number];
+ type AuthMethod = (typeof AUTH_METHODS)[number];
+}