Skip to content

Commit fcc9a4a

Browse files
committed
getConfig: handle instances of useage where should throw error in prod but not in test
1 parent bbeac90 commit fcc9a4a

File tree

10 files changed

+54
-30
lines changed

10 files changed

+54
-30
lines changed

client/modules/IDE/actions/project.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ import {
1515
} from './ide';
1616
import { clearState, saveState } from '../../../persistState';
1717

18-
const ROOT_URL = getConfig('API_URL', { nullishString: true });
19-
const S3_BUCKET_URL_BASE = getConfig('S3_BUCKET_URL_BASE');
20-
const S3_BUCKET = getConfig('S3_BUCKET');
18+
const ROOT_URL = getConfig('API_URL', { failOnNotFound: true });
19+
const S3_BUCKET_URL_BASE = getConfig('S3_BUCKET_URL_BASE', {
20+
failOnNotFound: true
21+
});
22+
const S3_BUCKET = getConfig('S3_BUCKET', { failOnNotFound: true });
2123

2224
export function setProject(project) {
2325
return {

client/modules/IDE/actions/uploader.js

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
import { TEXT_FILE_REGEX } from '../../../../server/utils/fileUtils';
22
import { apiClient } from '../../../utils/apiClient';
3-
import { getConfig } from '../../../utils/getConfig';
3+
import { getConfig, isTestEnvironment } from '../../../utils/getConfig';
44
import { handleCreateFile } from './files';
55

6+
const s3BucketUrlBase = getConfig('S3_BUCKET_URL_BASE');
7+
const awsRegion = getConfig('AWS_REGION');
8+
const s3Bucket = getConfig('S3_BUCKET');
9+
10+
if (!isTestEnvironment && !s3BucketUrlBase && !(awsRegion && s3Bucket)) {
11+
throw new Error(`S3 bucket address not configured.
12+
Configure either S3_BUCKET_URL_BASE or both AWS_REGION & S3_BUCKET in env vars`);
13+
}
14+
615
export const s3BucketHttps =
7-
getConfig('S3_BUCKET_URL_BASE') ||
8-
`https://s3-${getConfig('AWS_REGION', {
9-
nullishString: true
10-
})}.amazonaws.com/${getConfig('S3_BUCKET', {
11-
nullishString: true
12-
})}/`;
16+
s3BucketUrlBase || `https://s3-${awsRegion}.amazonaws.com/${s3Bucket}/`;
17+
1318
const MAX_LOCAL_FILE_SIZE = 80000; // bytes, aka 80 KB
1419

1520
function isS3Upload(file) {

client/modules/IDE/components/PreviewFrame.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const Frame = styled.iframe`
1313

1414
function PreviewFrame({ fullView, isOverlayVisible }) {
1515
const iframe = useRef();
16-
const previewUrl = getConfig('PREVIEW_URL');
16+
const previewUrl = getConfig('PREVIEW_URL', { failOnNotFound: true });
1717
useEffect(() => {
1818
const unsubscribe = registerFrame(iframe.current.contentWindow, previewUrl);
1919
return () => {

client/modules/IDE/components/SketchListRowBase.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import MenuItem from '../../../components/Dropdown/MenuItem';
1111
import { formatDateToString } from '../../../utils/formatDate';
1212
import { getConfig } from '../../../utils/getConfig';
1313

14-
const ROOT_URL = getConfig('API_URL', { nullishString: true });
14+
const ROOT_URL = getConfig('API_URL', { failOnNotFound: true });
1515

1616
const formatDateCell = (date, mobile = false) =>
1717
formatDateToString(date, { showTime: !mobile });

client/modules/Preview/EmbedFrame.jsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -232,9 +232,9 @@ p5.prototype.registerMethod('afterSetup', p5.prototype.ensureAccessibleCanvas);`
232232
}
233233

234234
const previewScripts = sketchDoc.createElement('script');
235-
previewScripts.src = `${window.location.origin}${
236-
(getConfig('PREVIEW_SCRIPTS_URL'), { nullishString: true })
237-
}`;
235+
previewScripts.src = `${
236+
window.location.origin
237+
}${getConfig('PREVIEW_SCRIPTS_URL', { nullishString: true })}`;
238238
previewScripts.setAttribute('crossorigin', '');
239239
sketchDoc.head.appendChild(previewScripts);
240240

@@ -245,9 +245,9 @@ p5.prototype.registerMethod('afterSetup', p5.prototype.ensureAccessibleCanvas);`
245245
window.offs = ${JSON.stringify(scriptOffs)};
246246
window.objectUrls = ${JSON.stringify(objectUrls)};
247247
window.objectPaths = ${JSON.stringify(objectPaths)};
248-
window.editorOrigin = '${
249-
(getConfig('EDITOR_URL'), { nullishString: true })
250-
}';
248+
window.editorOrigin = '${getConfig('EDITOR_URL', {
249+
failOnNotFound: true
250+
})}';
251251
`;
252252
addLoopProtect(sketchDoc);
253253
sketchDoc.head.prepend(consoleErrorsScript);

client/modules/Preview/previewIndex.jsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
} from '../../utils/dispatcher';
1010
import { filesReducer, setFiles } from './filesReducer';
1111
import EmbedFrame from './EmbedFrame';
12-
import { getConfig } from '../../utils/getConfig';
12+
import { getConfig, isTestEnvironment } from '../../utils/getConfig';
1313
import { initialState } from '../IDE/reducers/files';
1414

1515
const GlobalStyle = createGlobalStyle`
@@ -24,7 +24,10 @@ const App = () => {
2424
const [basePath, setBasePath] = useState('');
2525
const [textOutput, setTextOutput] = useState(false);
2626
const [gridOutput, setGridOutput] = useState(false);
27-
registerFrame(window.parent, getConfig('EDITOR_URL'));
27+
registerFrame(
28+
window.parent,
29+
getConfig('EDITOR_URL', { failOnNotFound: true })
30+
);
2831

2932
function handleMessageEvent(message) {
3033
const { type, payload } = message;

client/modules/User/components/CookieConsent.jsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ const CookieConsentButtons = styled.div`
7777
}
7878
`;
7979

80+
const GOOGLE_ANALYTICS_ID = getConfig('GA_MEASUREMENT_ID');
81+
8082
function CookieConsent({ hide }) {
8183
const user = useSelector((state) => state.user);
8284
const [cookieConsent, setBrowserCookieConsent] = useState('none');
@@ -133,15 +135,15 @@ function CookieConsent({ hide }) {
133135
initializeCookieConsent();
134136
}
135137

136-
if (getConfig('GA_MEASUREMENT_ID')) {
138+
if (GOOGLE_ANALYTICS_ID) {
137139
if (p5CookieConsent === 'essential') {
138-
ReactGA.initialize(getConfig('GA_MEASUREMENT_ID'), {
140+
ReactGA.initialize(GOOGLE_ANALYTICS_ID, {
139141
gaOptions: {
140142
storage: 'none'
141143
}
142144
});
143145
} else {
144-
ReactGA.initialize(getConfig('GA_MEASUREMENT_ID'));
146+
ReactGA.initialize(GOOGLE_ANALYTICS_ID);
145147
}
146148
ReactGA.pageview(window.location.pathname + window.location.search);
147149
}

client/utils/apiClient.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import axios, { AxiosInstance } from 'axios';
22
import { getConfig } from './getConfig';
33

4-
const ROOT_URL = getConfig('API_URL', { nullishString: true });
4+
const ROOT_URL = getConfig('API_URL', { failOnNotFound: true });
55

66
/**
77
* Configures an Axios instance with the correct API URL

client/utils/getConfig.test.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,12 @@ describe('utils/getConfig()', () => {
3333
});
3434

3535
it('throws an error if failOnNotFound is true', () => {
36+
process.env.NODE_ENV = 'not_test';
3637
expect(() =>
37-
getConfig('CONFIG_TEST_KEY_NAME', { failOnNotFound: true })
38+
getConfig('CONFIG_TEST_KEY_NAME', {
39+
failOnNotFound: true,
40+
failInTestEnv: true
41+
})
3842
).toThrow();
3943
});
4044

@@ -62,7 +66,10 @@ describe('utils/getConfig()', () => {
6266

6367
it('throws an error if failOnNotFound is true', () => {
6468
expect(() =>
65-
getConfig('CONFIG_TEST_KEY_NAME', { failOnNotFound: true })
69+
getConfig('CONFIG_TEST_KEY_NAME', {
70+
failOnNotFound: true,
71+
failInTestEnv: true
72+
})
6673
).toThrow();
6774
});
6875

client/utils/getConfig.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,16 @@ interface GetConfigOptions {
1313
warn?: boolean;
1414
nullishString?: boolean;
1515
failOnNotFound?: boolean;
16+
failInTestEnv?: boolean; // this is only to test getConfig and should never be set to override defaults
1617
}
1718

18-
const isTestEnvironment = getEnvVar('NODE_ENV') === 'test';
19+
export const isTestEnvironment = getEnvVar('NODE_ENV') === 'test';
1920

2021
const defaultGetConfigOptions: GetConfigOptions = {
2122
warn: !isTestEnvironment,
2223
nullishString: false,
23-
failOnNotFound: false
24+
failOnNotFound: false,
25+
failInTestEnv: false
2426
};
2527

2628
/**
@@ -43,7 +45,7 @@ export function getConfig(
4345
}
4446

4547
// override default options with param options
46-
const { warn, nullishString, failOnNotFound } = {
48+
const { warn, nullishString, failOnNotFound, failInTestEnv } = {
4749
...defaultGetConfigOptions,
4850
...options
4951
};
@@ -56,7 +58,10 @@ export function getConfig(
5658
const notFoundMessage = `getConfig("${key}") returned null or undefined`;
5759

5860
// error, warn or continue if no value found:
59-
if (failOnNotFound) {
61+
if (
62+
(failOnNotFound && !isTestEnvironment) ||
63+
(failOnNotFound && isTestEnvironment && failInTestEnv) // this is just to enable us to test getConfig's error throwing
64+
) {
6065
throw new Error(notFoundMessage);
6166
}
6267
if (warn) {

0 commit comments

Comments
 (0)