From b53d715704503cc729f640cc499244b331567cde Mon Sep 17 00:00:00 2001 From: DanielRosa74 <58576743+DanielRosa74@users.noreply.github.com> Date: Fri, 19 Dec 2025 17:42:51 -0300 Subject: [PATCH] fix(client): fix speaking-modal showing span tags (#64759) Co-authored-by: Huyen Nguyen <25715018+huyenltnguyen@users.noreply.github.com> --- .../components/multiple-choice-questions.tsx | 7 +--- .../components/speaking-modal-helpers.test.ts | 40 ++++++++++++++++++- .../components/speaking-modal-helpers.ts | 4 ++ 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/client/src/templates/Challenges/components/multiple-choice-questions.tsx b/client/src/templates/Challenges/components/multiple-choice-questions.tsx index ccef1df62e0..1083913117d 100644 --- a/client/src/templates/Challenges/components/multiple-choice-questions.tsx +++ b/client/src/templates/Challenges/components/multiple-choice-questions.tsx @@ -11,6 +11,7 @@ import { SuperBlocks } from '../../../../../shared/config/curriculum'; import SpeakingModal from './speaking-modal'; import ChallengeHeading from './challenge-heading'; import PrismFormatted from './prism-formatted'; +import { stripHtmlTags } from './speaking-modal-helpers'; type MultipleChoiceQuestionsProps = { questions: Question[]; @@ -41,16 +42,12 @@ function MultipleChoiceQuestions({ const [modalAnswerIndex, setModalAnswerIndex] = useState(0); const [modalQuestionIndex, setModalQuestionIndex] = useState(0); - function stripCodeTags(text: string): string { - return text.replace(/(.*?)<\/code>/g, '$1'); - } - const handleSpeakingButtonClick = ( answer: string, answerIndex: number, questionIndex: number ) => { - setModalText(stripCodeTags(removeParagraphTags(answer))); + setModalText(stripHtmlTags(answer)); setModalAnswerIndex(answerIndex); setModalQuestionIndex(questionIndex); openSpeakingModal(); diff --git a/client/src/templates/Challenges/components/speaking-modal-helpers.test.ts b/client/src/templates/Challenges/components/speaking-modal-helpers.test.ts index 92457ca6b7d..1ba202ab6d4 100644 --- a/client/src/templates/Challenges/components/speaking-modal-helpers.test.ts +++ b/client/src/templates/Challenges/components/speaking-modal-helpers.test.ts @@ -1,5 +1,9 @@ import { describe, it, expect } from 'vitest'; -import { normalizeText, compareTexts } from './speaking-modal-helpers'; +import { + normalizeText, + compareTexts, + stripHtmlTags +} from './speaking-modal-helpers'; describe('speaking-modal-helpers', () => { describe('normalizeText', () => { @@ -231,4 +235,38 @@ describe('speaking-modal-helpers', () => { }); }); }); + + describe('stripHtmlTags', () => { + it('should remove HTML tags and attributes', () => { + expect(stripHtmlTags('hello')).toBe('hello'); + expect(stripHtmlTags('world')).toBe('world'); + expect(stripHtmlTags('

Text content

')).toBe('Text content'); + expect( + stripHtmlTags('Nǐ hǎo') + ).toBe('Nǐ hǎo'); + }); + + it('should handle nested tags', () => { + expect(stripHtmlTags('

Hello world

')).toBe( + 'Hello world' + ); + expect(stripHtmlTags('

text

')).toBe( + 'text' + ); + }); + + it('should handle text without tags', () => { + expect(stripHtmlTags('plain text')).toBe('plain text'); + }); + + it('should handle empty string', () => { + expect(stripHtmlTags('')).toBe(''); + }); + + it('should remove tags but preserve spacing', () => { + expect(stripHtmlTags('Hello world today')).toBe( + 'Hello world today' + ); + }); + }); }); diff --git a/client/src/templates/Challenges/components/speaking-modal-helpers.ts b/client/src/templates/Challenges/components/speaking-modal-helpers.ts index 6909330c88a..8e314bb2354 100644 --- a/client/src/templates/Challenges/components/speaking-modal-helpers.ts +++ b/client/src/templates/Challenges/components/speaking-modal-helpers.ts @@ -181,3 +181,7 @@ function alignWords( })); } } + +export const stripHtmlTags = (text: string): string => { + return text.replace(/<[^>]*>/g, ''); +};