Skip to content

Commit f18ab9c

Browse files
committed
CCM-11438 Fix interpolate unit test
1 parent bc236b6 commit f18ab9c

File tree

2 files changed

+16
-2
lines changed

2 files changed

+16
-2
lines changed

frontend/src/__tests__/utils/interpolate.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,13 @@ describe('interpolate', () => {
2727
'items'
2828
);
2929
});
30+
31+
it('replaces multiple variables and plurals in same string', () => {
32+
expect(
33+
interpolate(
34+
'{{characters}} {{characters|character|characters}} as {{count}} {{count|text message|text messages}}',
35+
{ characters: 2, count: 1 }
36+
)
37+
).toBe('2 characters as 1 text message');
38+
});
3039
});

frontend/src/utils/interpolate.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,17 @@
2323
* @param variables - An object of variables
2424
* @returns The interpolated string
2525
*/
26+
// the following regex is bounded, avoids nested repetition, and is safe for controlled templates
27+
// eslint-disable-next-line security/detect-unsafe-regex, sonarjs/slow-regex
28+
const interpolationPattern = /{{\s*(\w+)(?:\|([^|]+)\|([^|]+))?\s*}}/g;
29+
2630
export function interpolate(
2731
template: string,
2832
variables: Record<string, string | number> = {}
2933
): string {
30-
return template.replaceAll(/{{\s*([\w|]+?)\s*}}/g, (_, token) => {
31-
const parts = token.trim().split('|');
34+
// eslint-disable-next-line unicorn/prefer-string-replace-all
35+
return template.replace(interpolationPattern, (_, token) => {
36+
const parts = token.split('|').map((part: string) => part.trim());
3237

3338
if (parts.length === 3) {
3439
const [variable, singular, plural] = parts;

0 commit comments

Comments
 (0)