diff --git a/packages/@coorpacademy-player-store/src/utils/state-extract.js b/packages/@coorpacademy-player-store/src/utils/state-extract.js
index 2b0edc8471..bccdcb95ee 100644
--- a/packages/@coorpacademy-player-store/src/utils/state-extract.js
+++ b/packages/@coorpacademy-player-store/src/utils/state-extract.js
@@ -19,8 +19,6 @@ import {
toString as _toString,
isNil
} from 'lodash/fp';
-// eslint-disable-next-line lodash-fp/use-fp
-import {template} from 'lodash';
import type {
Answer,
Choice,
@@ -393,14 +391,15 @@ export const getCurrentExitNode = (state: State): ExitNode | void => {
const ref = progression.state.nextContent.ref;
const counters = getOr({}, 'state.variables', progression);
- const translateWithCounters = templateValue =>
- templateValue
- ? // eslint-disable-next-line lodash-fp/no-extraneous-args
- template(templateValue, {
- interpolate: /{{([\s\S]+?)}}/g,
- imports: {}
- })(counters)
- : null;
+ // Use simple string replacement instead of lodash template
+ // to avoid SyntaxError when content contains HTML (e.g.,
)
+ const translateWithCounters = (templateValue: ?string): ?string => {
+ if (!templateValue) return null;
+ return templateValue.replace(/{{([\s\S]+?)}}/g, (match: string, key: string): string => {
+ const trimmedKey = key.trim();
+ return counters[trimmedKey] !== undefined ? counters[trimmedKey] : match;
+ });
+ };
return pipe(
getExitNode(ref),
diff --git a/packages/@coorpacademy-player-store/src/utils/test/state-extract.js b/packages/@coorpacademy-player-store/src/utils/test/state-extract.js
index 6f773f761c..f66aa7c026 100644
--- a/packages/@coorpacademy-player-store/src/utils/test/state-extract.js
+++ b/packages/@coorpacademy-player-store/src/utils/test/state-extract.js
@@ -849,6 +849,48 @@ test('getCurrentExitNode should get current exit node from state with counters',
});
});
+test('getCurrentExitNode should keep unmatched template variables', t => {
+ const exitNode = {
+ ref: 'successExitNode',
+ title: 'Score: {{ score }}, Unknown: {{ unknownVar }}'
+ };
+ const progression = {
+ state: {nextContent: {ref: 'successExitNode'}, variables: {score: 5}}
+ };
+ const state = pipe(
+ set('ui.current.progressionId', '0'),
+ set('data.progressions.entities', {0: progression}),
+ set('data.exitNodes.entities', {successExitNode: exitNode})
+ )({});
+
+ t.deepEqual(getCurrentExitNode(state), {
+ ref: 'successExitNode',
+ title: 'Score: 5, Unknown: {{ unknownVar }}'
+ });
+});
+
+test('getCurrentExitNode should handle HTML content without crashing', t => {
+ const exitNode = {
+ ref: 'successExitNode',
+ title: 'Congratulations!',
+ description: 'Your transcript will be updated.
Thanks for your patience.'
+ };
+ const progression = {
+ state: {nextContent: {ref: 'successExitNode'}, variables: {}}
+ };
+ const state = pipe(
+ set('ui.current.progressionId', '0'),
+ set('data.progressions.entities', {0: progression}),
+ set('data.exitNodes.entities', {successExitNode: exitNode})
+ )({});
+
+ t.deepEqual(getCurrentExitNode(state), {
+ ref: 'successExitNode',
+ title: 'Congratulations!',
+ description: 'Your transcript will be updated.
Thanks for your patience.'
+ });
+});
+
test('getCurrentExitNode should return undefined if no progression is found', t => {
const state = set('ui.current.progressionId', '0')({});
t.is(getCurrentExitNode(state), undefined);