Added FeedReader tests.

This commit is contained in:
Erik C. Thauvin 2021-05-18 22:12:07 -07:00
parent 082b430ee2
commit 484f11664e
2 changed files with 106 additions and 24 deletions

View file

@ -31,11 +31,14 @@
*/
package net.thauvin.erik.mobibot
import com.rometools.rome.io.FeedException
import com.rometools.rome.io.SyndFeedInput
import com.rometools.rome.io.XmlReader
import net.thauvin.erik.mobibot.msg.Message
import net.thauvin.erik.mobibot.msg.PublicMessage
import net.thauvin.erik.mobibot.Utils.green
import net.thauvin.erik.mobibot.Utils.helpFormat
import java.net.MalformedURLException
import java.io.IOException
import java.net.URL
/**
@ -49,38 +52,44 @@ class FeedReader(
// URL to fetch
private val url: String
) : Runnable {
// Maximum number of feed items to display
@Suppress("MagicNumber")
private val maxItems = 5
/**
* Fetches the Feed's items.
*/
override fun run() {
with(bot) {
try {
val input = SyndFeedInput()
XmlReader(URL(url)).use { reader ->
val feed = input.build(reader)
val items = feed.entries
if (items.isEmpty()) {
send(sender, "There is currently nothing to view.", false)
} else {
var i = 0
while (i < items.size && i < maxItems) {
send(sender, items[i].title, false)
send(sender, helpFormat(green(items[i].link), false), false)
i++
}
}
readFeed(url).forEach {
send(sender, it)
}
} catch (e: MalformedURLException) {
if (logger.isDebugEnabled) logger.debug("Invalid feed URL.", e)
send(sender, "The feed URL is invalid.", false)
} catch (e: Exception) {
if (logger.isDebugEnabled) logger.debug("Unable to fetch the feed.", e)
} catch (e: FeedException) {
if (logger.isDebugEnabled) logger.debug("Unabled to parse the feed at ${url}", e)
send(sender, "An error has occured while parsing the feed: ${e.message}", false)
} catch (e: IOException) {
if (logger.isDebugEnabled) logger.debug("Unable to fetch the feed at ${url}", e)
send(sender, "An error has occurred while fetching the feed: ${e.message}", false)
}
}
}
companion object {
@JvmStatic
@Throws(FeedException::class, IOException::class)
fun readFeed(url: String, maxItems: Int = 5) : List<Message> {
val messages = mutableListOf<Message>()
val input = SyndFeedInput()
XmlReader(URL(url)).use { reader ->
val feed = input.build(reader)
val items = feed.entries
if (items.isEmpty()) {
messages.add(PublicMessage("There is currently nothing to view."))
} else {
items.take(maxItems).forEach {
messages.add(PublicMessage(it.title))
messages.add(PublicMessage(helpFormat(green(it.link), false)))
}
}
}
return messages
}
}
}

View file

@ -0,0 +1,73 @@
/*
* FeedReaderTest.java
*
* Copyright (c) 2004-2019, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of this project nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.thauvin.erik.mobibot
import com.rometools.rome.io.FeedException
import net.thauvin.erik.mobibot.FeedReader.Companion.readFeed
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.testng.annotations.Test
import java.io.FileNotFoundException
import java.net.MalformedURLException
import java.net.UnknownHostException
/**
* The `FeedReader Test` class.
*/
class FeedReaderTest {
@Test
fun readFeedTest() {
var messages = readFeed("https://feeds.thauvin.net/ethauvin")
assertThat(messages.size).describedAs("messages = 10").isEqualTo(10)
assertThat(messages[1].msg).describedAs("feed entry url").contains("ethauvin")
messages = readFeed("https://lorem-rss.herokuapp.com/feed?length=0")
assertThat(messages[0].msg).describedAs("nothing to view").contains("nothing")
messages = readFeed("https://lorem-rss.herokuapp.com/feed?length=42", 42)
assertThat(messages.size).describedAs("messages = 84").isEqualTo(84)
assertThat(messages.last().msg).describedAs("example entry url").contains("http://example.com/test/")
assertThatThrownBy { readFeed("blah") }.describedAs("invalid URL")
.isInstanceOf(MalformedURLException::class.java)
assertThatThrownBy { readFeed("https://www.example.com") }.describedAs("not a feed")
.isInstanceOf(FeedException::class.java)
assertThatThrownBy { readFeed("https://www.examples.com/foo") }.describedAs("404 not found")
.isInstanceOf(FileNotFoundException::class.java)
assertThatThrownBy { readFeed("https://www.doesnotexists.com") }.describedAs("unknown host")
.isInstanceOf(UnknownHostException::class.java)
}
}