diff --git a/core/test/utils/html_utils_test.dart b/core/test/utils/html_utils_test.dart index 58d3353d7..567c8e8ba 100644 --- a/core/test/utils/html_utils_test.dart +++ b/core/test/utils/html_utils_test.dart @@ -232,7 +232,6 @@ void main() { expect(HtmlUtils.extractPlainText(html), 'Before Hello After'); }); - test('handles emoji correctly', () { const html = '''
Hello 🌍🚀
@@ -318,8 +317,203 @@ void main() { }); test('keeps unknown tags as plain text', () { + // Unknown HTML tags should be keep as html text, + // not stripped or removed by the extractor. const html = 'Intro
+++Level1+++Level2
++ Level3 +++ Level4 ++
Outro
+ '''; + expect(HtmlUtils.extractPlainText(html), 'Intro Outro'); + }); + + test('removes adjacent blockquotes and preserves surrounding text', () { + const html = ''' ++Q1
+Q2
+Q3
Start
++ On Nov 10 ... ++Quoted text+
End
+ '''; + expect(HtmlUtils.extractPlainText(html), 'Start End'); + }); + + test('keeps content when removeQuotes=false', () { + const html = ''' +A
++B inside quote
C
+ '''; + expect( + HtmlUtils.extractPlainText(html, removeQuotes: false), + 'A B inside quote C', + ); + }); + + test('keeps content of encoded blockquotes since they are not real tags', () { + const html = ''' +Before
+ <blockquote>Inner from encoded quote</blockquote> +After
+ '''; + expect(HtmlUtils.extractPlainText(html), 'Before Inner from encoded quote After'); + }); + + test('handles multiple encoded tags that become real tags then stripped', () { + const html = ''' + <div>A</div><span>B</span> + '''; + // After decoding twice:Keep
+ + +Me
+ '''; + expect(HtmlUtils.extractPlainText(html), 'Keep Me'); + }); + + test('keeps style content when removeStyle=false', () { + const html = ''' +Top
+ +Bottom
+ '''; + // When removeStyle=false, style content remains after tag stripping. + expect( + HtmlUtils.extractPlainText(html, removeStyle: false), + 'Top Bottom', + ); + }); + + test('keeps script content when removeScript=false', () { + const html = ''' +Hello
+ +World
+ '''; + expect( + HtmlUtils.extractPlainText(html, removeScript: false), + 'Hello World', + ); + }); + + test('collapses multipleXin chào
++Bonjour (quoted)
こんにちは
+ '''; + expect(HtmlUtils.extractPlainText(html), 'Xin chào こんにちは'); + }); + + test('handles messy whitespace around quotes and tags', () { + const html = ''' +++ B + '''; + expect(HtmlUtils.extractPlainText(html), 'A B'); + }); + + test('ignores disclaimers when wrapped inside blockquotes', () { + const html = ''' +should be gone
+
Keep
++++ Ce message et les éventuels documents joints... ++
Text
+ '''; + expect(HtmlUtils.extractPlainText(html), 'Keep Text'); + }); + + test('keeps disclaimers that are not wrapped in blockquotes', () { + const html = ''' +Top
+Bottom
+ '''; + expect(HtmlUtils.extractPlainText(html), + 'Top Ce message et les éventuels documents joints... Bottom'); + }); + + test('removes malformed nested blockquotes completely', () { + const html = ''' +Intro
+++Q1 ++Q2 ++Q3
Outro
+ '''; + expect(HtmlUtils.extractPlainText(html), 'Intro Outro'); + }); + + test('leaves unknown entities untouched while decoding known ones', () { + const html = ''' +© 2025 &unknown; & <tag>
+ '''; + // © → ©, & → &, <tag> →