Skip to content

Commit b48f4c5

Browse files
committed
refactor: read runtime config from environment variables
- remove Next.js runtimeConfig usage in app config and test setup - update runtime config helpers to read values from process.env - update tests to stub required env vars with vi.stubEnv - map mock config keys to environment variable names Refs: LINK-2574
1 parent 2b770c7 commit b48f4c5

7 files changed

Lines changed: 107 additions & 58 deletions

next.config.js

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,8 @@ const moduleExports = {
2424
sassOptions: {
2525
includePaths: ['src/styles'],
2626
},
27-
publicRuntimeConfig: {
28-
linkedEventsApiBaseUrl: process.env.NEXT_PUBLIC_LINKED_EVENTS_URL,
29-
webStoreApiBaseUrl: process.env.NEXT_PUBLIC_WEB_STORE_API_BASE_URL,
30-
attendanceListLoginMethods:
31-
process.env.NEXT_PUBLIC_ATTENDANCE_LIST_LOGIN_METHODS,
32-
signupsLoginMethods: process.env.NEXT_PUBLIC_SIGNUPS_LOGIN_METHODS,
33-
},
34-
serverRuntimeConfig: {
35-
env: process.env.NEXT_ENV,
36-
oidcApiTokensUrl: process.env.OIDC_API_TOKENS_URL,
37-
oidcClientId: process.env.OIDC_CLIENT_ID,
38-
oidcClientSecret: process.env.OIDC_CLIENT_SECRET,
39-
oidcIssuer: process.env.OIDC_ISSUER,
40-
oidcLinkedEventsApiScope: process.env.OIDC_LINKED_EVENTS_API_SCOPE,
41-
},
4227
env: {
43-
APP_VERSION: packageJson.version
28+
APP_VERSION: packageJson.version,
4429
},
4530
output: 'standalone',
4631
eslint: {
@@ -64,7 +49,7 @@ module.exports = withSentryConfig(moduleExports, {
6449
},
6550
treeshake: {
6651
// Automatically tree-shake Sentry logger statements to reduce bundle size
67-
removeDebugLogging: true
52+
removeDebugLogging: true,
6853
},
6954
reactComponentAnnotation: {
7055
enabled: true,

src/setupTests.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,11 @@ if (typeof Blob !== 'undefined' && !Blob.prototype.stream) {
2121
} as () => ReadableStream;
2222
}
2323

24-
import { setConfig } from 'next/config';
2524
import { expect, beforeAll, afterAll, afterEach, vi } from 'vitest';
2625
import * as matchers from 'vitest-axe/matchers';
2726

28-
import config from '../next.config';
29-
3027
import { server } from './tests/msw/server';
3128

32-
setConfig(config);
33-
3429
expect.extend(matchers);
3530

3631
// Mock scrollTo function

src/utils/__tests__/getPublicRuntimeConfig.test.ts

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import { beforeEach, vi } from 'vitest';
12
import getPublicRuntimeConfig from '../getPublicRuntimeConfig';
2-
import { mockConfig } from '../mockNextJsConfig';
33

44
const publicRuntimeConfig = {
55
linkedEventsApiBaseUrl: 'https://linkedevents-backend:8000/v1',
@@ -15,9 +15,28 @@ const expectedPublicRuntimeConfig = {
1515
signupsLoginMethods: ['helsinki_tunnus', 'helsinkiad'],
1616
};
1717

18+
afterEach(() => {
19+
vi.unstubAllEnvs();
20+
});
21+
1822
describe('getPublicRuntimeConfig function', () => {
19-
it('should return public runtime config', () => {
20-
mockConfig(publicRuntimeConfig, {});
23+
it('should return public runtime config', () => {
24+
vi.stubEnv(
25+
'NEXT_PUBLIC_LINKED_EVENTS_URL',
26+
publicRuntimeConfig.linkedEventsApiBaseUrl
27+
);
28+
vi.stubEnv(
29+
'NEXT_PUBLIC_WEB_STORE_API_BASE_URL',
30+
publicRuntimeConfig.webStoreApiBaseUrl
31+
);
32+
vi.stubEnv(
33+
'NEXT_PUBLIC_ATTENDANCE_LIST_LOGIN_METHODS',
34+
publicRuntimeConfig.attendanceListLoginMethods
35+
);
36+
vi.stubEnv(
37+
'NEXT_PUBLIC_SIGNUPS_LOGIN_METHODS',
38+
publicRuntimeConfig.signupsLoginMethods
39+
);
2140
expect(getPublicRuntimeConfig()).toEqual(expectedPublicRuntimeConfig);
2241
});
2342

@@ -29,7 +48,22 @@ describe('getPublicRuntimeConfig function', () => {
2948
it.each(cases)(
3049
'should throw error if and public runtime variable is missing',
3150
(publicRuntimeConfig) => {
32-
mockConfig(publicRuntimeConfig, {});
51+
vi.stubEnv(
52+
'NEXT_PUBLIC_LINKED_EVENTS_URL',
53+
publicRuntimeConfig.linkedEventsApiBaseUrl
54+
);
55+
vi.stubEnv(
56+
'NEXT_PUBLIC_WEB_STORE_API_BASE_URL',
57+
publicRuntimeConfig.webStoreApiBaseUrl
58+
);
59+
vi.stubEnv(
60+
'NEXT_PUBLIC_ATTENDANCE_LIST_LOGIN_METHODS',
61+
publicRuntimeConfig.attendanceListLoginMethods
62+
);
63+
vi.stubEnv(
64+
'NEXT_PUBLIC_SIGNUPS_LOGIN_METHODS',
65+
publicRuntimeConfig.signupsLoginMethods
66+
);
3367
expect(getPublicRuntimeConfig).toThrow(
3468
'Invalid configuration. Some required public runtime variable are missing'
3569
);

src/utils/__tests__/getServerRuntimeConfig.test.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import { beforeEach, vi } from 'vitest';
12
import getServerRuntimeConfig from '../getServerRuntimeConfig';
2-
import { mockConfig } from '../mockNextJsConfig';
33

44
const serverRuntimeConfig = {
55
env: 'development',
@@ -11,9 +11,21 @@ const serverRuntimeConfig = {
1111
oidcLinkedEventsApiScope: 'linkedevents',
1212
};
1313

14+
afterEach(() => {
15+
vi.unstubAllEnvs();
16+
});
17+
1418
describe('getServerRuntimeConfig function', () => {
15-
it('should return server runtime config', () => {
16-
mockConfig({}, serverRuntimeConfig);
19+
it('should return server runtime config', () => {
20+
vi.stubEnv('NEXT_ENV', serverRuntimeConfig.env);
21+
vi.stubEnv('OIDC_API_TOKENS_URL', serverRuntimeConfig.oidcApiTokensUrl);
22+
vi.stubEnv('OIDC_CLIENT_ID', serverRuntimeConfig.oidcClientId);
23+
vi.stubEnv('OIDC_CLIENT_SECRET', serverRuntimeConfig.oidcClientSecret);
24+
vi.stubEnv('OIDC_ISSUER', serverRuntimeConfig.oidcIssuer);
25+
vi.stubEnv(
26+
'OIDC_LINKED_EVENTS_API_SCOPE',
27+
serverRuntimeConfig.oidcLinkedEventsApiScope
28+
);
1729
expect(getServerRuntimeConfig()).toEqual(serverRuntimeConfig);
1830
});
1931

@@ -29,7 +41,15 @@ describe('getServerRuntimeConfig function', () => {
2941
it.each(cases)(
3042
'should throw error if an server runtime variable is missing',
3143
(serverRuntimeConfig) => {
32-
mockConfig({}, serverRuntimeConfig);
44+
vi.stubEnv('NEXT_ENV', serverRuntimeConfig.env);
45+
vi.stubEnv('OIDC_API_TOKENS_URL', serverRuntimeConfig.oidcApiTokensUrl);
46+
vi.stubEnv('OIDC_CLIENT_ID', serverRuntimeConfig.oidcClientId);
47+
vi.stubEnv('OIDC_CLIENT_SECRET', serverRuntimeConfig.oidcClientSecret);
48+
vi.stubEnv('OIDC_ISSUER', serverRuntimeConfig.oidcIssuer);
49+
vi.stubEnv(
50+
'OIDC_LINKED_EVENTS_API_SCOPE',
51+
serverRuntimeConfig.oidcLinkedEventsApiScope
52+
);
3353
expect(getServerRuntimeConfig).toThrow(
3454
'Invalid configuration. Some required server runtime variable are missing'
3555
);

src/utils/getPublicRuntimeConfig.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
import getConfig from 'next/config';
2-
3-
import { parseLoginMethods } from "../constants";
1+
import { parseLoginMethods } from '../constants';
42

53
const getPublicRuntimeConfig = () => {
6-
const {
7-
publicRuntimeConfig: {
8-
linkedEventsApiBaseUrl,
9-
webStoreApiBaseUrl,
10-
attendanceListLoginMethods,
11-
signupsLoginMethods
12-
},
13-
} = getConfig();
4+
const linkedEventsApiBaseUrl = process.env.NEXT_PUBLIC_LINKED_EVENTS_URL;
5+
const webStoreApiBaseUrl = process.env.NEXT_PUBLIC_WEB_STORE_API_BASE_URL;
6+
const attendanceListLoginMethods =
7+
process.env.NEXT_PUBLIC_ATTENDANCE_LIST_LOGIN_METHODS;
8+
const signupsLoginMethods = process.env.NEXT_PUBLIC_SIGNUPS_LOGIN_METHODS;
149

15-
if (!linkedEventsApiBaseUrl || !webStoreApiBaseUrl || !attendanceListLoginMethods || !signupsLoginMethods) {
10+
if (
11+
!linkedEventsApiBaseUrl ||
12+
!webStoreApiBaseUrl ||
13+
!attendanceListLoginMethods ||
14+
!signupsLoginMethods
15+
) {
1616
throw new Error(
1717
'Invalid configuration. Some required public runtime variable are missing'
1818
);

src/utils/getServerRuntimeConfig.ts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,10 @@
1-
import getConfig from 'next/config';
2-
31
const getServerRuntimeConfig = () => {
4-
const {
5-
serverRuntimeConfig: {
6-
env,
7-
oidcApiTokensUrl,
8-
oidcClientId,
9-
oidcClientSecret,
10-
oidcIssuer,
11-
oidcLinkedEventsApiScope,
12-
},
13-
} = getConfig();
2+
const env = process.env.NEXT_ENV;
3+
const oidcApiTokensUrl = process.env.OIDC_API_TOKENS_URL;
4+
const oidcClientId = process.env.OIDC_CLIENT_ID;
5+
const oidcClientSecret = process.env.OIDC_CLIENT_SECRET;
6+
const oidcIssuer = process.env.OIDC_ISSUER;
7+
const oidcLinkedEventsApiScope = process.env.OIDC_LINKED_EVENTS_API_SCOPE;
148

159
if (
1610
!env ||

src/utils/mockNextJsConfig.ts

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,33 @@
1-
import * as nextConfig from 'next/config';
1+
import { vi } from 'vitest';
22

33
export const mockConfig = (
44
publicRuntimeConfig: Record<string, string>,
55
serverRuntimeConfig: Record<string, string>
66
) => {
7-
nextConfig.setConfig({
8-
publicRuntimeConfig,
9-
serverRuntimeConfig,
7+
const publicEnvMap: Record<string, string> = {
8+
linkedEventsApiBaseUrl: 'NEXT_PUBLIC_LINKED_EVENTS_URL',
9+
webStoreApiBaseUrl: 'NEXT_PUBLIC_WEB_STORE_API_BASE_URL',
10+
attendanceListLoginMethods: 'NEXT_PUBLIC_ATTENDANCE_LIST_LOGIN_METHODS',
11+
signupsLoginMethods: 'NEXT_PUBLIC_SIGNUPS_LOGIN_METHODS',
12+
};
13+
14+
Object.entries(publicRuntimeConfig).forEach(([key, value]) => {
15+
const envKey = publicEnvMap[key] || `NEXT_PUBLIC_${key.toUpperCase()}`;
16+
vi.stubEnv(envKey, value);
17+
});
18+
19+
const serverEnvMap: Record<string, string> = {
20+
env: 'NEXT_ENV',
21+
oidcApiTokensUrl: 'OIDC_API_TOKENS_URL',
22+
oidcClientId: 'OIDC_CLIENT_ID',
23+
oidcClientSecret: 'OIDC_CLIENT_SECRET',
24+
oidcIssuer: 'OIDC_ISSUER',
25+
oidcLinkedEventsApiScope: 'OIDC_LINKED_EVENTS_API_SCOPE',
26+
};
27+
28+
Object.entries(serverRuntimeConfig).forEach(([key, value]) => {
29+
const envKey = serverEnvMap[key] || key.toUpperCase();
30+
vi.stubEnv(envKey, value);
1031
});
1132
};
1233

0 commit comments

Comments
 (0)