Add new helper class to get RSS feed type, with tests

This commit is contained in:
Shinokuni 2020-08-24 21:38:46 +02:00
parent 594a0a67fa
commit 355b5a4375
2 changed files with 128 additions and 0 deletions

View File

@ -0,0 +1,68 @@
package com.readrops.api.localfeed
import com.readrops.api.utils.ParseException
import java.io.InputStream
import java.util.regex.Pattern
object LocalRSSHelper {
private const val RSS_DEFAULT_CONTENT_TYPE = "application/rss+xml"
private const val RSS_TEXT_CONTENT_TYPE = "text/xml"
private const val RSS_APPLICATION_CONTENT_TYPE = "application/xml"
private const val ATOM_CONTENT_TYPE = "application/atom+xml"
private const val JSON_CONTENT_TYPE = "application/json"
private const val HTML_CONTENT_TYPE = "text/html"
private const val RSS_2_REGEX = "rss.*version=\"2.0\""
private const val ATOM_REGEX = "<feed.* xmlns=\"http://www.w3.org/2005/Atom\""
/**
* Guess RSS type based on content-type header
*/
fun getRSSType(contentType: String): RSSType {
return when (contentType) {
RSS_DEFAULT_CONTENT_TYPE -> RSSType.RSS_2
ATOM_CONTENT_TYPE -> RSSType.ATOM
JSON_CONTENT_TYPE -> RSSType.JSONFEED
RSS_TEXT_CONTENT_TYPE, RSS_APPLICATION_CONTENT_TYPE, HTML_CONTENT_TYPE -> RSSType.UNKNOWN
else -> throw ParseException("Unknown content type")
}
}
/**
* Guess RSS type based on xml content
*/
fun getRSSContentType(content: InputStream): RSSType {
val stringBuffer = StringBuffer()
val reader = content.bufferedReader()
var currentLine = reader.readLine()
while (currentLine != null) {
stringBuffer.append(currentLine)
if (Pattern.compile(RSS_2_REGEX).matcher(stringBuffer.toString()).find()) {
reader.close()
content.close()
return RSSType.RSS_2
} else if (Pattern.compile(ATOM_REGEX).matcher(stringBuffer.toString()).find()) {
reader.close()
content.close()
return RSSType.ATOM
}
currentLine = reader.readLine()
}
return RSSType.UNKNOWN
}
enum class RSSType {
RSS_2,
ATOM,
JSONFEED,
UNKNOWN
}
}

View File

@ -0,0 +1,60 @@
package com.readrops.api
import com.readrops.api.localfeed.LocalRSSHelper
import com.readrops.api.utils.ParseException
import junit.framework.TestCase.assertEquals
import org.junit.Test
import java.io.ByteArrayInputStream
class LocalRSSHelperTest {
@Test
fun standardContentTypesTest() {
assertEquals(LocalRSSHelper.getRSSType("application/rss+xml"),
LocalRSSHelper.RSSType.RSS_2)
assertEquals(LocalRSSHelper.getRSSType("application/atom+xml"),
LocalRSSHelper.RSSType.ATOM)
assertEquals(LocalRSSHelper.getRSSType("application/json"),
LocalRSSHelper.RSSType.JSONFEED)
}
@Test
fun nonStandardContentTypesTest() {
assertEquals(LocalRSSHelper.getRSSType("application/xml"),
LocalRSSHelper.RSSType.UNKNOWN)
assertEquals(LocalRSSHelper.getRSSType("text/xml"),
LocalRSSHelper.RSSType.UNKNOWN)
assertEquals(LocalRSSHelper.getRSSType("text/html"),
LocalRSSHelper.RSSType.UNKNOWN)
}
@Test(expected = ParseException::class)
fun nonSupportedContentTypeTest() {
LocalRSSHelper.getRSSType("image/jpeg")
}
@Test
fun rssContentTest() {
assertEquals(LocalRSSHelper.getRSSContentType(ByteArrayInputStream(
"""<rss
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
version="2.0"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
</rss>""".toByteArray()
)), LocalRSSHelper.RSSType.RSS_2)
}
@Test
fun atomContentTest() {
assertEquals(LocalRSSHelper.getRSSContentType(ByteArrayInputStream(
"""<feed xmlns="http://www.w3.org/2005/Atom">
</feed>""".toByteArray()
)), LocalRSSHelper.RSSType.ATOM)
}
}