From 7e266fc7977d1e324dda6e9f24382df15e4b5b85 Mon Sep 17 00:00:00 2001 From: Josiah Campbell <9521010+jocmp@users.noreply.github.com> Date: Fri, 3 Jan 2025 21:49:42 -0600 Subject: [PATCH] Ensure XML parser uses response encoding (#672) --- .../jocmp/rssparser/internal/DefaultParser.kt | 2 +- .../com/jocmp/rssparser/BaseParserTest.kt | 10 +- .../kotlin/com/jocmp/rssparser/TestUtils.kt | 6 +- .../rssparser/rss/XmlParserAccentsTest.kt | 20 ++++ .../src/test/resources/feed-test-accents.xml | 105 ++++++++++++++++++ 5 files changed, 136 insertions(+), 7 deletions(-) create mode 100644 rssparser/src/test/kotlin/com/jocmp/rssparser/rss/XmlParserAccentsTest.kt create mode 100644 rssparser/src/test/resources/feed-test-accents.xml diff --git a/rssparser/src/main/kotlin/com/jocmp/rssparser/internal/DefaultParser.kt b/rssparser/src/main/kotlin/com/jocmp/rssparser/internal/DefaultParser.kt index c377b4bb..3eba649d 100644 --- a/rssparser/src/main/kotlin/com/jocmp/rssparser/internal/DefaultParser.kt +++ b/rssparser/src/main/kotlin/com/jocmp/rssparser/internal/DefaultParser.kt @@ -67,7 +67,7 @@ internal class DefaultParser( private fun tryXmlParse(input: ParserInput): Document? { return try { - Jsoup.parse(input.inputStream(), null, "", JsoupParser.xmlParser()) + Jsoup.parse(input.inputStream(), input.charset?.toString(), "", JsoupParser.xmlParser()) } catch (e: IOException) { null } diff --git a/rssparser/src/test/kotlin/com/jocmp/rssparser/BaseParserTest.kt b/rssparser/src/test/kotlin/com/jocmp/rssparser/BaseParserTest.kt index 3e241eef..4a86c2a1 100644 --- a/rssparser/src/test/kotlin/com/jocmp/rssparser/BaseParserTest.kt +++ b/rssparser/src/test/kotlin/com/jocmp/rssparser/BaseParserTest.kt @@ -1,11 +1,12 @@ package com.jocmp.rssparser -import com.jocmp.rssparser.model.RssItem +import com.jocmp.rssparser.model.ItunesChannelData +import com.jocmp.rssparser.model.ItunesItemData import com.jocmp.rssparser.model.RssChannel import com.jocmp.rssparser.model.RssImage -import com.jocmp.rssparser.model.ItunesItemData -import com.jocmp.rssparser.model.ItunesChannelData +import com.jocmp.rssparser.model.RssItem import kotlinx.coroutines.test.runTest +import java.nio.charset.Charset import kotlin.test.BeforeTest import kotlin.test.Test import kotlin.test.assertEquals @@ -38,6 +39,7 @@ abstract class BaseParserTest( val articleCategories: List = emptyList(), val articleCommentsUrl: String? = null, val articleItunesData: ItunesItemData? = null, + val charset: Charset? = null ) { private lateinit var channel: RssChannel @@ -45,7 +47,7 @@ abstract class BaseParserTest( @BeforeTest fun setUp() = runTest { - val input = readFileFromResources(feedPath) + val input = readFileFromResources(feedPath, charset = charset) channel = ParserFactory.build().parse(input) article = channel.items[0] } diff --git a/rssparser/src/test/kotlin/com/jocmp/rssparser/TestUtils.kt b/rssparser/src/test/kotlin/com/jocmp/rssparser/TestUtils.kt index 188ecfa8..afa90020 100644 --- a/rssparser/src/test/kotlin/com/jocmp/rssparser/TestUtils.kt +++ b/rssparser/src/test/kotlin/com/jocmp/rssparser/TestUtils.kt @@ -2,11 +2,13 @@ package com.jocmp.rssparser import com.jocmp.rssparser.internal.ParserInput import java.io.File +import java.nio.charset.Charset internal fun readFileFromResources( - resourceName: String + resourceName: String, + charset: Charset? = null, ): ParserInput { val file = File("src/test/resources/$resourceName") - return ParserInput(file.readBytes(), charset = null) + return ParserInput(file.readBytes(), charset = charset) } diff --git a/rssparser/src/test/kotlin/com/jocmp/rssparser/rss/XmlParserAccentsTest.kt b/rssparser/src/test/kotlin/com/jocmp/rssparser/rss/XmlParserAccentsTest.kt new file mode 100644 index 00000000..db17045f --- /dev/null +++ b/rssparser/src/test/kotlin/com/jocmp/rssparser/rss/XmlParserAccentsTest.kt @@ -0,0 +1,20 @@ +package com.jocmp.rssparser.rss + +import com.jocmp.rssparser.BaseParserTest +import com.jocmp.rssparser.model.RssImage +import java.nio.charset.Charset + +class XmlParserAccentsTest : BaseParserTest( + charset = Charset.forName("ISO-8859-1"), + feedPath = "feed-test-accents.xml", + channelTitle = "UOL Noticias", + channelLink = "http://noticias.uol.com.br/", + channelImage = RssImage( + url = "http://rss.i.uol.com.br/uol_rss.gif" + ), + channelDescription = "Últimas Notícias", + articleTitle = "Artur Jorge não é mais técnico do Botafogo", + articleLink = "https://noticias.uol.com.br/ultimas-noticias/afp/2025/01/03/artur-jorge-nao-e-mais-tecnico-do-botafogo.htm", + articlePubDate = "Sex, 03 Jan 2025 23:47:02 -0300", + articleDescription = "O português Artur Jorge não continuará como treinador do Botafogo, anunciou nesta sexta-feira (3) o atual campeão brasileiro e da Copa Libertadores.", +) diff --git a/rssparser/src/test/resources/feed-test-accents.xml b/rssparser/src/test/resources/feed-test-accents.xml new file mode 100644 index 00000000..63c93253 --- /dev/null +++ b/rssparser/src/test/resources/feed-test-accents.xml @@ -0,0 +1,105 @@ + + + UOL Noticias + http://noticias.uol.com.br/ + Últimas Notícias + + Notícias + + + UOL Noticias - Últimas Notícias + http://rss.i.uol.com.br/uol_rss.gif + http://noticias.uol.com.br/ultimas/ + + + <![CDATA[Artur Jorge não é mais técnico do Botafogo]]> + + + Sex, 03 Jan 2025 23:47:02 -0300 + + + <![CDATA[Aerolíneas Argentinas reduz custos visando privatização]]> + + + Sex, 03 Jan 2025 23:10:42 -0300 + + + <![CDATA[Livro mostra como Taiwan aposta em internet e participação social para driblar discurso de ódio]]> + + + Sex, 03 Jan 2025 23:00:00 -0300 + + + <![CDATA[Irmão de Cleitinho diz que senador pode ir para o Novo para disputar governo de MG]]> + + + Sex, 03 Jan 2025 23:00:00 -0300 + + + <![CDATA[Varanda metálica, acoplada como peça de Lego, vira alternativa para prédios antigos]]> + + + Sex, 03 Jan 2025 23:00:00 -0300 + + + <![CDATA[Brasil está entrando em ciclo perverso, diz empresário Rubens Menin]]> + + + Sex, 03 Jan 2025 23:00:00 -0300 + + + <![CDATA[Jornal O Estado de S. Paulo completa 150 anos]]> + + + Sex, 03 Jan 2025 23:00:00 -0300 + + + <![CDATA[O ano do carro elétrico chinês no Brasil]]> + + + Sex, 03 Jan 2025 23:00:00 -0300 + + + <![CDATA[Corte internacional deve analisar neste ano caso de adolescentes mortos por PMs há 30 anos no Pará]]> + + + Sex, 03 Jan 2025 23:00:00 -0300 + + + <![CDATA[Vice-campeão Mallorca é eliminado da Copa do Rei pelo modesto Pontevedra]]> + + + Sex, 03 Jan 2025 22:39:06 -0300 + + + <![CDATA[Governo chileno desiste de comprar casa de Salvador Allende após críticas da oposição]]> + + + Sex, 03 Jan 2025 22:22:32 -0300 + + + <![CDATA[8/1 de Lula terá cerimônia no Planalto e ato com esquerda na praça dos 3 Poderes]]> + + + Sex, 03 Jan 2025 22:14:00 -0300 + + + <![CDATA[A lógica oculta por trás do sobe e desce do Ibovespa]]> + + + Sex, 03 Jan 2025 21:58:00 -0300 + + + <![CDATA[Vinicius Junior é alvo de racismo após ser expulso em partida contra o Valencia]]> + + + Sex, 03 Jan 2025 21:48:00 -0300 + + + <![CDATA[Brasil registra recorde de calor em 2024]]> + + + Sex, 03 Jan 2025 21:45:00 -0300 + + +