From 50ef7cb59a5d678f105b6786eccaf661b50d87bf Mon Sep 17 00:00:00 2001 From: Merge Sim Date: Mon, 7 Sep 2026 10:35:12 -0700 Subject: [PATCH] test(mobile): scope i18n coverage to what this PR lands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Supersedes the UNVERIFIED note on the first commit: the suites have now run. Three embedded-webview-copy cases asserted that the rich-editor and terminal WebView documents emit localized, escaped copy. Those documents are not localized here, so the cases belonged to string extraction, not to this PR. Replaced with direct coverage of escapeEmbeddedHtmlCopy, including the ampersand-first ordering that keeps entities from double-decoding. Also relabels the catalog-registration test. It cannot distinguish lazy from eager registration while only en.json exists — registering every supported locale yields an identical result — so it now says what it actually pins: a supported locale without a catalog is never registered. --- mobile/src/i18n/embedded-webview-copy.test.ts | 83 +++++-------------- mobile/src/i18n/mobile-i18n.test.ts | 9 +- 2 files changed, 25 insertions(+), 67 deletions(-) diff --git a/mobile/src/i18n/embedded-webview-copy.test.ts b/mobile/src/i18n/embedded-webview-copy.test.ts index 5348120a620..64c50842eab 100644 --- a/mobile/src/i18n/embedded-webview-copy.test.ts +++ b/mobile/src/i18n/embedded-webview-copy.test.ts @@ -1,79 +1,34 @@ -import { afterEach, describe, expect, it } from 'vitest' +import { describe, expect, it } from 'vitest' -import { - buildMobileRichMarkdownEditorHtml, - escapeInjectedJavaScriptString -} from '../components/mobile-rich-markdown-editor-html' -import { buildTerminalWebViewHtml } from '../terminal/terminal-webview-html' import { escapeEmbeddedHtmlCopy } from './embedded-webview-copy' -import { mobileI18n } from './mobile-i18n' -const INITIAL_LOCALE = mobileI18n.language - -afterEach(async () => { - await mobileI18n.changeLanguage(INITIAL_LOCALE) -}) - -describe('embedded WebView copy', () => { - it('escapes translated HTML text and attributes', () => { +// The WebView-injection call sites are not localized yet, so this covers the +// primitive on its own. Extraction adds the cases that assert translated copy +// reaches the rich-editor and terminal documents already escaped. +describe('escapeEmbeddedHtmlCopy', () => { + it('escapes text and attribute delimiters', () => { expect(escapeEmbeddedHtmlCopy('')).toBe( '<Copy "all" & more>' ) }) - it('injects localized rich-editor and terminal controls', async () => { - await mobileI18n.changeLanguage('es') - - const editorHtml = buildMobileRichMarkdownEditorHtml() - expect(editorHtml).toContain('') - expect(editorHtml).toContain('data-placeholder="Empieza a escribir..."') - expect(editorHtml).toContain('window.prompt("URL del enlace")') - expect(editorHtml).toContain('window.prompt("URL de la imagen")') - expect(editorHtml).toContain(`+ "Tarea" +`) - - const terminalHtml = buildTerminalWebViewHtml() - expect(terminalHtml).toContain('') - expect(terminalHtml).toContain('id="sel-menu-copy">Copiar') - expect(terminalHtml).toContain('id="sel-menu-all">Seleccionar todo') + it('neutralizes markup that would otherwise parse as an element', () => { + expect(escapeEmbeddedHtmlCopy('')).toBe( + '<img src=x onerror=alert(1)>' + ) + expect(escapeEmbeddedHtmlCopy('Task & more')).toBe('<b>Task & more</b>') }) - it('escapes script-state delimiters in translated JavaScript strings', () => { - expect(escapeInjectedJavaScriptString('