Moved to PircBotX and assertk.

This commit is contained in:
Erik C. Thauvin 2021-11-08 13:54:48 -08:00
parent 2a46761dc5
commit 9fb870648e
83 changed files with 2347 additions and 2577 deletions

View file

@ -1,5 +1,5 @@
/*
* Sanitize.kt
* ExceptionSanitizer.kt
*
* Copyright (c) 2004-2021, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
@ -36,27 +36,26 @@ import net.thauvin.erik.mobibot.Utils.obfuscate
import net.thauvin.erik.mobibot.Utils.replaceEach
import net.thauvin.erik.mobibot.modules.ModuleException
object Sanitize {
object ExceptionSanitizer {
/**
* Returns a sanitized exception to avoid displaying api keys, etc. in CI logs.
*/
fun sanitizeException(e: ModuleException, vararg sanitize: String): ModuleException {
var sanitizedException = e
fun ModuleException.sanitize(vararg sanitize: String): ModuleException {
val search = sanitize.filter { it.isNotBlank() }.toTypedArray()
if (search.isNotEmpty()) {
val obfuscate = search.map { it.obfuscate() }.toTypedArray()
with(e) {
if (cause?.message != null) {
sanitizedException = ModuleException(
with(this) {
if (!cause?.message.isNullOrBlank()) {
return ModuleException(
debugMessage,
cause!!.javaClass.name + ": " + cause!!.message!!.replaceEach(search, obfuscate),
this
)
} else if (message != null) {
sanitizedException = ModuleException(debugMessage, message!!.replaceEach(search, obfuscate), this)
} else if (!message.isNullOrBlank()) {
return ModuleException(debugMessage, message!!.replaceEach(search, obfuscate), this)
}
}
}
return sanitizedException
return this
}
}

View file

@ -31,12 +31,14 @@
*/
package net.thauvin.erik.mobibot
import assertk.assertThat
import assertk.assertions.contains
import assertk.assertions.isEqualTo
import assertk.assertions.isFailure
import assertk.assertions.isInstanceOf
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
@ -48,26 +50,24 @@ 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")
assertThat(messages.size, "size = 10").isEqualTo(10)
assertThat(messages[1].msg, "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")
assertThat(messages[0].msg, "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/")
assertThat(messages.size, "messages = 84").isEqualTo(84)
assertThat(messages.last().msg, "example entry url").contains("http://example.com/test/")
assertThatThrownBy { readFeed("blah") }.describedAs("invalid URL")
.isInstanceOf(MalformedURLException::class.java)
assertThat { readFeed("blah") }.isFailure().isInstanceOf(MalformedURLException::class.java)
assertThatThrownBy { readFeed("https://www.example.com") }.describedAs("not a feed")
.isInstanceOf(FeedException::class.java)
assertThat { readFeed("https://www.example.com") }.isFailure().isInstanceOf(FeedException::class.java)
assertThatThrownBy { readFeed("https://www.examples.com/foo") }.describedAs("404 not found")
assertThat { readFeed("https://www.examples.com/foo") }.isFailure()
.isInstanceOf(FileNotFoundException::class.java)
assertThatThrownBy { readFeed("https://www.doesnotexists.com") }.describedAs("unknown host")
assertThat { readFeed("https://www.doesnotexists.com") }.isFailure()
.isInstanceOf(UnknownHostException::class.java)
}
}

View file

@ -1,5 +1,5 @@
/*
* PinboardUtilsTest.kt
* PinboardTest.kt
*
* Copyright (c) 2004-2021, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
@ -32,45 +32,39 @@
package net.thauvin.erik.mobibot
import net.thauvin.erik.mobibot.PinboardUtils.toTimestamp
import net.thauvin.erik.mobibot.entries.EntryLink
import net.thauvin.erik.pinboard.PinboardPoster
import org.testng.Assert.assertFalse
import org.testng.Assert.assertTrue
import org.testng.annotations.Test
import java.net.URL
import java.util.Date
class PinboardUtilsTest : LocalProperties() {
class PinboardTest : LocalProperties() {
private val pinboard = Pinboard()
@Test
fun pinboardTest() {
fun testPinboard() {
val apiToken = getProperty("pinboard-api-token")
val pinboard = PinboardPoster(apiToken)
val url = "https://www.example.com/"
val ircServer = "irc.test.com"
val entry = EntryLink(url, "Test Example", "ErikT", "", "#mobitopia", listOf("test"))
PinboardUtils.addPin(pinboard, ircServer, entry)
pinboard.setApiToken(apiToken)
pinboard.addPin(ircServer, entry)
assertTrue(validatePin(apiToken, url = entry.link, entry.title, entry.nick, entry.channel), "validate add")
entry.link = "https://www.foo.com/"
PinboardUtils.updatePin(pinboard, ircServer, url, entry)
pinboard.updatePin(ircServer, url, entry)
assertTrue(validatePin(apiToken, url = entry.link, ircServer), "validate update")
entry.title = "Foo Title"
PinboardUtils.updatePin(pinboard, ircServer, entry.link, entry)
pinboard.updatePin(ircServer, entry.link, entry)
assertTrue(validatePin(apiToken, url = entry.link, entry.title), "validate title")
PinboardUtils.deletePin(pinboard, entry)
pinboard.deletePin(entry)
assertFalse(validatePin(apiToken, url = entry.link), "validate delete")
}
@Test
fun toTimestampTest() {
val d = Date()
assertTrue(d.toTimestamp().matches("[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z".toRegex()))
}
private fun validatePin(apiToken: String, url: String, vararg matches: String): Boolean {
val response = Utils.urlReader(
URL(

View file

@ -31,6 +31,8 @@
*/
package net.thauvin.erik.mobibot
import assertk.assertThat
import assertk.assertions.isEqualTo
import net.thauvin.erik.mobibot.Utils.appendIfMissing
import net.thauvin.erik.mobibot.Utils.bold
import net.thauvin.erik.mobibot.Utils.buildCmdSyntax
@ -55,8 +57,7 @@ import net.thauvin.erik.mobibot.Utils.unescapeXml
import net.thauvin.erik.mobibot.Utils.uptime
import net.thauvin.erik.mobibot.Utils.urlReader
import net.thauvin.erik.mobibot.msg.Message.Companion.DEFAULT_COLOR
import org.assertj.core.api.Assertions.assertThat
import org.jibble.pircbot.Colors
import org.pircbotx.Colors
import org.testng.annotations.BeforeClass
import org.testng.annotations.Test
import java.io.File
@ -86,59 +87,59 @@ class UtilsTest {
val dir = "dir"
val sep = '/'
val url = "https://erik.thauvin.net"
assertThat(dir.appendIfMissing(File.separatorChar)).describedAs("appendIfMissing(dir)")
assertThat(dir.appendIfMissing(File.separatorChar), "appendIfMissing(dir)")
.isEqualTo(dir + File.separatorChar)
assertThat(url.appendIfMissing(sep)).describedAs("appendIfMissing(url)").isEqualTo("$url$sep")
assertThat("$url$sep".appendIfMissing(sep)).describedAs("appendIfMissing($url$sep)").isEqualTo("$url$sep")
assertThat(url.appendIfMissing(sep), "appendIfMissing(url)").isEqualTo("$url$sep")
assertThat("$url$sep".appendIfMissing(sep), "appendIfMissing($url$sep)").isEqualTo("$url$sep")
}
@Test
fun testBold() {
assertThat(bold(1)).describedAs("bold(1)").isEqualTo(Colors.BOLD + "1" + Colors.BOLD)
assertThat(bold(2L)).describedAs("bold(1)").isEqualTo(Colors.BOLD + "2" + Colors.BOLD)
assertThat(bold(ascii)).describedAs("bold(ascii)").isEqualTo(Colors.BOLD + ascii + Colors.BOLD)
assertThat(bold("test")).describedAs("bold(test)").isEqualTo(Colors.BOLD + "test" + Colors.BOLD)
assertThat(bold(1), "bold(1)").isEqualTo(Colors.BOLD + "1" + Colors.BOLD)
assertThat(bold(2L), "bold(1)").isEqualTo(Colors.BOLD + "2" + Colors.BOLD)
assertThat(bold(ascii), "bold(ascii)").isEqualTo(Colors.BOLD + ascii + Colors.BOLD)
assertThat(bold("test"), "bold(test)").isEqualTo(Colors.BOLD + "test" + Colors.BOLD)
}
@Test
fun testBuildCmdSyntax() {
val bot = "mobibot"
assertThat(buildCmdSyntax("%c $test %n $test", bot, false)).describedAs("public")
assertThat(buildCmdSyntax("%c $test %n $test", bot, false), "public")
.isEqualTo("$bot: $test $bot $test")
assertThat(buildCmdSyntax("%c %n $test %c $test %n", bot, true)).describedAs("public")
assertThat(buildCmdSyntax("%c %n $test %c $test %n", bot, true), "public")
.isEqualTo("/msg $bot $bot $test /msg $bot $test $bot")
}
@Test
fun testCapitalise() {
assertThat("test".capitalise()).describedAs("capitalize(test)").isEqualTo("Test")
assertThat("Test".capitalise()).describedAs("capitalize(Test)").isEqualTo("Test")
assertThat(test.capitalise()).describedAs("capitalize($test)").isEqualTo(test)
assertThat("".capitalise()).describedAs("capitalize()").isEqualTo("")
assertThat("test".capitalise(), "capitalize(test)").isEqualTo("Test")
assertThat("Test".capitalise(), "capitalize(Test)").isEqualTo("Test")
assertThat(test.capitalise(), "capitalize($test)").isEqualTo(test)
assertThat("".capitalise(), "capitalize()").isEqualTo("")
}
@Test
fun textCapitaliseWords() {
assertThat(test.capitalizeWords()).describedAs("captiatlizeWords(test)").isEqualTo("This Is A Test.")
assertThat("Already Capitalized".capitalizeWords()).describedAs("already capitalized")
assertThat(test.capitalizeWords(), "captiatlizeWords(test)").isEqualTo("This Is A Test.")
assertThat("Already Capitalized".capitalizeWords(), "already capitalized")
.isEqualTo("Already Capitalized")
assertThat(" a test ".capitalizeWords()).describedAs("with spaces").isEqualTo(" A Test ")
assertThat(" a test ".capitalizeWords(), "with spaces").isEqualTo(" A Test ")
}
@Test
fun testColorize() {
assertThat(colorize(ascii, Colors.REVERSE)).describedAs("colorize(reverse)").isEqualTo(
assertThat(colorize(ascii, Colors.REVERSE), "colorize(reverse)").isEqualTo(
Colors.REVERSE + ascii + Colors.REVERSE
)
assertThat(colorize(ascii, Colors.RED)).describedAs("colorize(red)")
assertThat(colorize(ascii, Colors.RED), "colorize(red)")
.isEqualTo(Colors.RED + ascii + Colors.NORMAL)
assertThat(colorize(ascii, Colors.BOLD)).describedAs("colorized(bold)")
assertThat(colorize(ascii, Colors.BOLD), "colorized(bold)")
.isEqualTo(Colors.BOLD + ascii + Colors.BOLD)
assertThat(colorize(null, Colors.RED)).describedAs("colorize(null)").isEqualTo("")
assertThat(colorize("", Colors.RED)).describedAs("colorize()").isEqualTo("")
assertThat(colorize(ascii, DEFAULT_COLOR)).describedAs("colorize(none)").isEqualTo(ascii)
assertThat(colorize(" ", Colors.NORMAL)).describedAs("colorize(blank)")
assertThat(colorize(null, Colors.RED), "colorize(null)").isEqualTo("")
assertThat(colorize("", Colors.RED), "colorize()").isEqualTo("")
assertThat(colorize(ascii, DEFAULT_COLOR), "colorize(none)").isEqualTo(ascii)
assertThat(colorize(" ", Colors.NORMAL), "colorize(blank)")
.isEqualTo(Colors.NORMAL + " " + Colors.NORMAL)
}
@ -157,9 +158,9 @@ class UtilsTest {
val p = Properties()
p["one"] = "1"
p["two"] = "two"
assertThat(p.getIntProperty("one", 9)).describedAs("getIntProperty(one)").isEqualTo(1)
assertThat(p.getIntProperty("two", 2)).describedAs("getIntProperty(two)").isEqualTo(2)
assertThat(p.getIntProperty("foo", 3)).describedAs("getIntProperty(foo)").isEqualTo(3)
assertThat(p.getIntProperty("one", 9), "getIntProperty(one)").isEqualTo(1)
assertThat(p.getIntProperty("two", 2), "getIntProperty(two)").isEqualTo(2)
assertThat(p.getIntProperty("foo", 3), "getIntProperty(foo)").isEqualTo(3)
}
@Test
@ -169,26 +170,26 @@ class UtilsTest {
@Test
fun testHelpFormat() {
assertThat(helpFormat(test, isBold = true, isIndent = false)).describedAs("bold")
assertThat(helpFormat(test, isBold = true, isIndent = false), "bold")
.isEqualTo("${Colors.BOLD}$test${Colors.BOLD}")
assertThat(helpFormat(test, isBold = false, isIndent = true)).describedAs("indent")
assertThat(helpFormat(test, isBold = false, isIndent = true), "indent")
.isEqualTo(test.prependIndent())
assertThat(helpFormat(test, isBold = true, isIndent = true)).describedAs("bold-indent")
assertThat(helpFormat(test, isBold = true, isIndent = true), "bold-indent")
.isEqualTo(colorize(test, Colors.BOLD).prependIndent())
}
@Test
fun testIsoLocalDate() {
assertThat(cal.time.toIsoLocalDate()).describedAs("isoLocalDate(date)").isEqualTo("1952-02-17")
assertThat(localDateTime.toIsoLocalDate()).describedAs("isoLocalDate(localDate)").isEqualTo("1952-02-17")
assertThat(cal.time.toIsoLocalDate(), "isoLocalDate(date)").isEqualTo("1952-02-17")
assertThat(localDateTime.toIsoLocalDate(), "isoLocalDate(localDate)").isEqualTo("1952-02-17")
}
@Test
fun testObfuscate() {
assertThat(ascii.obfuscate().length).describedAs("obfuscate is right length").isEqualTo(ascii.length)
assertThat(ascii.obfuscate()).describedAs("obfuscate()").isEqualTo("x".repeat(ascii.length))
assertThat(" ".obfuscate()).describedAs("obfuscate(blank)").isEqualTo(" ")
assertThat(ascii.obfuscate().length, "obfuscate is right length").isEqualTo(ascii.length)
assertThat(ascii.obfuscate(), "obfuscate()").isEqualTo("x".repeat(ascii.length))
assertThat(" ".obfuscate(), "obfuscate(blank)").isEqualTo(" ")
}
@Test
@ -197,7 +198,7 @@ class UtilsTest {
val weeks = "weeks"
for (i in -1..3) {
assertThat(week.plural(i.toLong())).describedAs("plural($i)").isEqualTo(if (i > 1) weeks else week)
assertThat(week.plural(i.toLong()), "plural($i)").isEqualTo(if (i > 1) weeks else week)
}
}
@ -205,15 +206,15 @@ class UtilsTest {
fun testReplaceEach() {
val search = arrayOf("one", "two", "three")
val replace = arrayOf("1", "2", "3")
assertThat(search.joinToString(",").replaceEach(search, replace)).describedAs("replaceEach(1,2,3")
assertThat(search.joinToString(",").replaceEach(search, replace), "replaceEach(1,2,3")
.isEqualTo(replace.joinToString(","))
assertThat(test.replaceEach(search, replace)).describedAs("replaceEach(nothing)").isEqualTo(test)
assertThat(test.replaceEach(search, replace), "replaceEach(nothing)").isEqualTo(test)
assertThat(test.replaceEach(arrayOf("t", "e"), arrayOf("", "E"))).describedAs("replaceEach($test)")
assertThat(test.replaceEach(arrayOf("t", "e"), arrayOf("", "E")), "replaceEach($test)")
.isEqualTo(test.replace("t", "").replace("e", "E"))
assertThat(test.replaceEach(search, emptyArray())).describedAs("replaceEach(search, empty)")
assertThat(test.replaceEach(search, emptyArray()), "replaceEach(search, empty)")
.isEqualTo(test)
}
@ -234,8 +235,8 @@ class UtilsTest {
@Test
fun testToIntOrDefault() {
assertThat("10".toIntOrDefault(1)).describedAs("toIntOrDefault(10, 1)").isEqualTo(10)
assertThat("a".toIntOrDefault(2)).describedAs("toIntOrDefault(a, 2)").isEqualTo(2)
assertThat("10".toIntOrDefault(1), "toIntOrDefault(10, 1)").isEqualTo(10)
assertThat("a".toIntOrDefault(2), "toIntOrDefault(a, 2)").isEqualTo(2)
}
@Test
@ -247,26 +248,26 @@ class UtilsTest {
@Test
fun testUptime() {
assertThat(uptime(547800300076L)).describedAs("full")
assertThat(uptime(547800300076L), "full")
.isEqualTo("17 years 2 months 2 weeks 1 day 6 hours 45 minutes")
assertThat(uptime(2700000L)).describedAs("minutes").isEqualTo("45 minutes")
assertThat(uptime(24300000L)).describedAs("hours minutes").isEqualTo("6 hours 45 minutes")
assertThat(uptime(110700000L)).describedAs("days hours minutes").isEqualTo("1 day 6 hours 45 minutes")
assertThat(uptime(1320300000L)).describedAs("weeks days hours minutes")
assertThat(uptime(2700000L), "minutes").isEqualTo("45 minutes")
assertThat(uptime(24300000L), "hours minutes").isEqualTo("6 hours 45 minutes")
assertThat(uptime(110700000L), "days hours minutes").isEqualTo("1 day 6 hours 45 minutes")
assertThat(uptime(1320300000L), "weeks days hours minutes")
.isEqualTo("2 weeks 1 day 6 hours 45 minutes")
assertThat(uptime(0L)).describedAs("0 minutes").isEqualTo("0 minute")
assertThat(uptime(0L), "0 minutes").isEqualTo("0 minute")
}
@Test
@Throws(IOException::class)
fun testUrlReader() {
assertThat(urlReader(URL("https://postman-echo.com/status/200"))).describedAs("urlReader()")
assertThat(urlReader(URL("https://postman-echo.com/status/200")), "urlReader()")
.isEqualTo("{\"status\":200}")
}
@Test
fun testUtcDateTime() {
assertThat(cal.time.toUtcDateTime()).describedAs("utcDateTime(date)").isEqualTo("1952-02-17 12:30")
assertThat(localDateTime.toUtcDateTime()).describedAs("utcDateTime(localDate)").isEqualTo("1952-02-17 12:30")
assertThat(cal.time.toUtcDateTime(), "utcDateTime(date)").isEqualTo("1952-02-17 12:30")
assertThat(localDateTime.toUtcDateTime(), "utcDateTime(localDate)").isEqualTo("1952-02-17 12:30")
}
}

View file

@ -31,7 +31,12 @@
*/
package net.thauvin.erik.mobibot.commands.tell
import org.assertj.core.api.Assertions.assertThat
import assertk.all
import assertk.assertThat
import assertk.assertions.isEqualTo
import assertk.assertions.isFalse
import assertk.assertions.isTrue
import assertk.assertions.prop
import org.testng.annotations.Test
import java.time.Duration
import java.time.LocalDateTime
@ -51,18 +56,21 @@ class TellMessageTest {
val recipient = "recipient"
val sender = "sender"
val tellMessage = TellMessage(sender, recipient, message)
assertThat(tellMessage).extracting("sender", "recipient", "message")
.containsExactly(sender, recipient, message)
assertThat(isValidDate(tellMessage.queued)).describedAs("queued is valid date/time").isTrue
assertThat(tellMessage.isMatch(sender)).describedAs("match sender").isTrue
assertThat(tellMessage.isMatch(recipient)).describedAs("match recipient").isTrue
assertThat(tellMessage.isMatch("foo")).describedAs("foo is no match").isFalse
assertThat(tellMessage).all {
prop(TellMessage::sender).isEqualTo(sender)
prop(TellMessage::recipient).isEqualTo(recipient)
prop(TellMessage::message).isEqualTo(message)
}
assertThat(isValidDate(tellMessage.queued), "queued is valid date/time").isTrue()
assertThat(tellMessage.isMatch(sender), "match sender").isTrue()
assertThat(tellMessage.isMatch(recipient), "match recipient").isTrue()
assertThat(tellMessage.isMatch("foo"), "foo is no match").isFalse()
tellMessage.isReceived = false
assertThat(tellMessage.receptionDate).describedAs("reception date not set").isEqualTo(LocalDateTime.MIN)
assertThat(tellMessage.receptionDate, "reception date not set").isEqualTo(LocalDateTime.MIN)
tellMessage.isReceived = true
assertThat(tellMessage.isReceived).describedAs("is received").isTrue
assertThat(isValidDate(tellMessage.receptionDate)).describedAs("received is valid date/time").isTrue
assertThat(tellMessage.isReceived, "is received").isTrue()
assertThat(isValidDate(tellMessage.receptionDate), "received is valid date/time").isTrue()
tellMessage.isNotified = true
assertThat(tellMessage.isNotified).describedAs("is notified").isTrue
assertThat(tellMessage.isNotified, "is notified").isTrue()
}
}

View file

@ -31,9 +31,16 @@
*/
package net.thauvin.erik.mobibot.entries
import assertk.all
import assertk.assertThat
import assertk.assertions.isEmpty
import assertk.assertions.isEqualTo
import assertk.assertions.isFalse
import assertk.assertions.isTrue
import assertk.assertions.prop
import assertk.assertions.size
import com.rometools.rome.feed.synd.SyndCategory
import com.rometools.rome.feed.synd.SyndCategoryImpl
import org.assertj.core.api.Assertions.assertThat
import org.testng.annotations.Test
import java.security.SecureRandom
import java.util.Date
@ -58,21 +65,30 @@ class EntryLinkTest {
entryLink.addComment("c$i", "u$i")
i++
}
assertThat(entryLink.comments.size).describedAs("getComments().size() == 5").isEqualTo(i)
assertThat(entryLink.comments.size, "getComments().size() == 5").isEqualTo(i)
i = 0
for (comment in entryLink.comments) {
assertThat(comment).extracting("comment", "nick").containsExactly("c$i", "u$i")
assertThat(comment).all {
prop(EntryComment::comment).isEqualTo("c$i")
prop(EntryComment::nick).isEqualTo("u$i")
}
i++
}
val r = SecureRandom()
while (entryLink.comments.size > 0) {
entryLink.deleteComment(r.nextInt(entryLink.comments.size))
}
assertThat(entryLink.comments).describedAs("hasComments()").isEmpty()
assertThat(entryLink.comments, "hasComments()").isEmpty()
entryLink.addComment("nothing", "nobody")
entryLink.setComment(0, "something", "somebody")
assertThat(entryLink.getComment(0)).describedAs("get first comment").extracting("nick", "comment")
.containsExactly("somebody", "something")
val comment = entryLink.getComment(0)
assertThat(comment, "get first comment").all {
prop(EntryComment::nick).isEqualTo("somebody")
prop(EntryComment::comment).isEqualTo("something")
}
assertThat(entryLink.deleteComment(comment), "delete comment").isTrue()
assertThat(entryLink.deleteComment(comment), "comment is already deleted").isFalse()
}
@Test
@ -80,19 +96,19 @@ class EntryLinkTest {
val tag = "test"
val tags = listOf(SyndCategoryImpl().apply { name = tag })
val link = EntryLink("link", "title", "nick", "channel", Date(), tags)
assertThat(link.tags.size).describedAs("check tag size").isEqualTo(tags.size)
assertThat(link.tags[0].name).describedAs("check tag name").isEqualTo(tag)
assertThat(link.pinboardTags).describedAs("check pinboard tags").isEqualTo("nick,$tag")
assertThat(link.tags.size, "check tag size").isEqualTo(tags.size)
assertThat(link.tags[0].name, "check tag name").isEqualTo(tag)
assertThat(link.pinboardTags, "check pinboard tags").isEqualTo("nick,$tag")
}
@Test
fun testMatches() {
assertThat(entryLink.matches("mobitopia")).describedAs("match mobitopia").isTrue
assertThat(entryLink.matches("skynx")).describedAs("match nick").isTrue
assertThat(entryLink.matches("www.mobitopia.org")).describedAs("match url").isTrue
assertThat(entryLink.matches("foo")).describedAs("match foo").isFalse
assertThat(entryLink.matches("")).describedAs("match empty").isFalse
assertThat(entryLink.matches(null)).describedAs("match null").isFalse
assertThat(entryLink.matches("mobitopia"), "match mobitopia").isTrue()
assertThat(entryLink.matches("skynx"), "match nick").isTrue()
assertThat(entryLink.matches("www.mobitopia.org"), "match url").isTrue()
assertThat(entryLink.matches("foo"), "match foo").isFalse()
assertThat(entryLink.matches("<empty>"), "match empty").isFalse()
assertThat(entryLink.matches(null), "match null").isFalse()
}
@ -100,20 +116,19 @@ class EntryLinkTest {
fun testTags() {
val tags: List<SyndCategory> = entryLink.tags
for ((i, tag) in tags.withIndex()) {
assertThat(tag.name).describedAs("tag.getName($i)").isEqualTo("tag" + (i + 1))
assertThat(tag.name, "tag.getName($i)").isEqualTo("tag" + (i + 1))
}
assertThat(entryLink.tags.size).describedAs("getTags().size() is 5").isEqualTo(5)
assertThat(entryLink.tags).describedAs("hasTags() is true").isNotEmpty
assertThat(entryLink.tags, "size is 5").size().isEqualTo(5)
entryLink.setTags("-tag5")
entryLink.setTags("+mobitopia")
entryLink.setTags("tag4")
entryLink.setTags("-mobitopia")
assertThat(entryLink.pinboardTags).describedAs("getPinboardTags()")
assertThat(entryLink.pinboardTags, "getPinboardTags()")
.isEqualTo(entryLink.nick + ",tag1,tag2,tag3,tag4,mobitopia")
val size = entryLink.tags.size
entryLink.setTags("")
assertThat(entryLink.tags.size).describedAs("empty tag").isEqualTo(size)
assertThat(entryLink.tags.size, "empty tag").isEqualTo(size)
entryLink.setTags(" ")
assertThat(entryLink.tags.size).describedAs("blank tag").isEqualTo(size)
assertThat(entryLink.tags.size, "blank tag").isEqualTo(size)
}
}

View file

@ -0,0 +1,121 @@
/*
* FeedMgrTest.kt
*
* Copyright (c) 2004-2021, 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.entries
import assertk.all
import assertk.assertThat
import assertk.assertions.endsWith
import assertk.assertions.isEqualTo
import assertk.assertions.isTrue
import assertk.assertions.prop
import net.thauvin.erik.mobibot.Utils.today
import org.testng.annotations.BeforeSuite
import org.testng.annotations.Test
import java.nio.file.Paths
import java.util.Date
import kotlin.io.path.absolutePathString
import kotlin.io.path.deleteIfExists
import kotlin.io.path.exists
import kotlin.io.path.fileSize
import kotlin.io.path.name
class FeedMgrTest {
private val entries = Entries()
private val channel = "mobibot"
@BeforeSuite(alwaysRun = true)
fun beforeSuite() {
entries.logsDir = "src/test/resources/"
entries.ircServer = "irc.example.com"
entries.channel = channel
entries.backlogs = "https://www.mobitopia.org/mobibot/logs"
}
@Test
fun testFeedMgr() {
// Load the feed
assertThat(FeedsMgr.loadFeed(entries), "pubDate").isEqualTo("2021-10-31")
assertThat(entries.links.size, "2 links").isEqualTo(2)
entries.links.forEachIndexed { i, entryLink ->
assertThat(entryLink, "Example $(i + 1)").all {
prop(EntryLink::title).isEqualTo("Example ${i + 1}")
prop(EntryLink::link).isEqualTo("https://www.example.com/${i + 1}")
prop(EntryLink::channel).isEqualTo(channel)
}
entryLink.tags.forEachIndexed { y, tag ->
assertThat(tag.name, "tag${i + 1}-${y + 1}").isEqualTo("tag${i + 1}-${y + 1}")
}
}
with(entries.links.first()) {
assertThat(nick, "first nick").isEqualTo("ErikT")
assertThat(date, "first date").isEqualTo(Date(1635638400000L))
comments.forEachIndexed { i, entryComment ->
assertThat(entryComment.comment, "comment ${i + 1}").endsWith("comment ${i + 1}.")
if (i == 0) {
assertThat(entryComment.nick, "comment ${i + 1} nick").isEqualTo("ErikT")
} else {
assertThat(entryComment.nick, "comment ${i + 1} nick").isEqualTo("Skynx")
}
}
}
assertThat(entries.links[1], "second link").all {
prop(EntryLink::nick).isEqualTo("Skynx")
prop(EntryLink::date).isEqualTo(Date(1635638460000L))
}
val currentFile = Paths.get("${entries.logsDir}test.xml")
val backlogFile = Paths.get("${entries.logsDir}${today()}.xml")
// Save the feed
FeedsMgr.saveFeed(entries, currentFile.name)
assertThat(currentFile.exists(), "${currentFile.absolutePathString()} exists").isTrue()
assertThat(backlogFile.exists(), "${backlogFile.absolutePathString()} exits").isTrue()
assertThat(currentFile.fileSize(), "files are identical").isEqualTo(backlogFile.fileSize())
// Load the test feed
entries.links.clear()
FeedsMgr.loadFeed(entries, currentFile.name)
entries.links.forEachIndexed { i, entryLink ->
assertThat(entryLink.title, "${currentFile.name} title ${i + 1}").isEqualTo("Example ${i + 1}")
}
assertThat(currentFile.deleteIfExists(), "delete ${currentFile.absolutePathString()}").isTrue()
assertThat(backlogFile.deleteIfExists(), "delete ${backlogFile.absolutePathString()}").isTrue()
}
}

View file

@ -31,11 +31,13 @@
*/
package net.thauvin.erik.mobibot.modules
import assertk.assertThat
import assertk.assertions.isEqualTo
import assertk.assertions.isFailure
import assertk.assertions.isInstanceOf
import net.objecthunter.exp4j.tokenizer.UnknownFunctionOrVariableException
import net.thauvin.erik.mobibot.Utils.bold
import net.thauvin.erik.mobibot.modules.Calc.Companion.calculate
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.testng.annotations.Test
/**
@ -44,11 +46,11 @@ import org.testng.annotations.Test
class CalcTest {
@Test
fun testCalculate() {
assertThat(calculate("1 + 1")).describedAs("calculate(1+1)").isEqualTo("1+1 = %s", bold(2))
assertThat(calculate("1 -3")).describedAs("calculate(1 -3)").isEqualTo("1-3 = %s", bold(-2))
assertThat(calculate("pi+π+e+φ")).describedAs("calculate(pi+π+e+φ)")
.isEqualTo("pi+π+e+φ = %s", bold("10.62"))
assertThatThrownBy { calculate("one + one") }.describedAs("calculate(one+one)")
.isInstanceOf(UnknownFunctionOrVariableException::class.java)
assertThat(calculate("1 + 1"), "calculate(1+1)").isEqualTo("1+1 = ${bold(2)}")
assertThat(calculate("1 -3"), "calculate(1 -3)").isEqualTo("1-3 = ${bold(-2)}")
assertThat(calculate("pi+π+e+φ"), "calculate(pi+π+e+φ)")
.isEqualTo("pi+π+e+φ = ${bold("10.62")}")
assertThat { calculate("one + one") }
.isFailure().isInstanceOf(UnknownFunctionOrVariableException::class.java)
}
}

View file

@ -31,8 +31,13 @@
*/
package net.thauvin.erik.mobibot.modules
import assertk.all
import assertk.assertThat
import assertk.assertions.isEqualTo
import assertk.assertions.isGreaterThan
import assertk.assertions.prop
import net.thauvin.erik.crypto.CryptoPrice
import net.thauvin.erik.mobibot.modules.CryptoPrices.Companion.currentPrice
import org.assertj.core.api.Assertions.assertThat
import org.testng.annotations.Test
/**
@ -43,11 +48,17 @@ class CryptoPricesTest {
@Throws(ModuleException::class)
fun testMarketPrice() {
var price = currentPrice(listOf("BTC"))
assertThat(price).extracting("base", "currency").containsExactly("BTC", "USD")
assertThat(price.amount.signum()).describedAs("BTC > 0").isGreaterThan(0)
assertThat(price, "BTC in USD").all {
prop(CryptoPrice::base).isEqualTo("BTC")
prop(CryptoPrice::currency).isEqualTo("USD")
prop(CryptoPrice::amount).transform { it.signum() }.isGreaterThan(0)
}
price = currentPrice(listOf("ETH", "EUR"))
assertThat(price).extracting("base", "currency").containsExactly("ETH", "EUR")
assertThat(price.amount.signum()).describedAs("ETH > 0").isGreaterThan(0)
assertThat(price, "ETH in EUR").all {
prop(CryptoPrice::base).isEqualTo("ETH")
prop(CryptoPrice::currency).isEqualTo("EUR")
prop(CryptoPrice::amount).transform { it.signum() }.isGreaterThan(0)
}
}
}

View file

@ -31,10 +31,21 @@
*/
package net.thauvin.erik.mobibot.modules
import assertk.all
import assertk.assertThat
import assertk.assertions.any
import assertk.assertions.contains
import assertk.assertions.isEqualTo
import assertk.assertions.isInstanceOf
import assertk.assertions.matches
import assertk.assertions.prop
import assertk.assertions.size
import net.thauvin.erik.mobibot.modules.CurrencyConverter.Companion.convertCurrency
import net.thauvin.erik.mobibot.modules.CurrencyConverter.Companion.currencyRates
import net.thauvin.erik.mobibot.modules.CurrencyConverter.Companion.loadRates
import org.assertj.core.api.Assertions.assertThat
import net.thauvin.erik.mobibot.msg.ErrorMessage
import net.thauvin.erik.mobibot.msg.Message
import net.thauvin.erik.mobibot.msg.PublicMessage
import org.testng.annotations.BeforeClass
import org.testng.annotations.Test
@ -50,14 +61,28 @@ class CurrencyConverterTest {
@Test
fun testConvertCurrency() {
assertThat(convertCurrency("100 USD to EUR").msg)
.describedAs("100 USD to EUR").matches("\\$100\\.00 = €\\d{2,3}\\.\\d{2}")
assertThat(convertCurrency("100 USD to USD").msg).describedAs("100 USD to USD")
.contains("You're kidding, right?")
assertThat(convertCurrency("100 USD").msg).describedAs("100 USD").contains("Invalid query.")
assertThat(
convertCurrency("100 USD to EUR").msg,
"100 USD to EUR"
).matches("\\$100\\.00 = €\\d{2,3}\\.\\d{2}".toRegex())
assertThat(convertCurrency("100 USD to USD"), "100 USD to USD").all {
prop(Message::msg).contains("You're kidding, right?")
isInstanceOf(PublicMessage::class.java)
}
assertThat(convertCurrency("100 USD"), "100 USD").all {
prop(Message::msg).contains("Invalid query.")
isInstanceOf(ErrorMessage::class.java)
}
}
@Test
fun testCurrencyRates() {
val rates = currencyRates()
assertThat(rates.size).describedAs("currencyRates.size == 33").isEqualTo(33)
assertThat(rates).describedAs("currencyRates(EUR< USD)").contains("EUR: 1")
.anyMatch { it.matches("USD: .*".toRegex()) }
assertThat(rates).all {
size().isEqualTo(33)
any { it.matches("[A-Z]{3}: +[\\d.]+".toRegex()) }
contains("EUR: 1")
}
}
}

View file

@ -33,14 +33,15 @@
package net.thauvin.erik.mobibot.modules
import org.assertj.core.api.Assertions.assertThat
import assertk.assertThat
import assertk.assertions.isEqualTo
import org.testng.annotations.Test
class DiceTest {
@Test
fun testWinLoseOrTie() {
assertThat(Dice.winLoseOrTie(6, 6)).describedAs("6 vs. 6").isEqualTo(Dice.Result.TIE)
assertThat(Dice.winLoseOrTie(6, 5)).describedAs("6 vs. 5").isEqualTo(Dice.Result.WIN)
assertThat(Dice.winLoseOrTie(5, 6)).describedAs("5 vs. 6").isEqualTo(Dice.Result.LOSE)
assertThat(Dice.winLoseOrTie(6, 6), "6 vs. 6").isEqualTo(Dice.Result.TIE)
assertThat(Dice.winLoseOrTie(6, 5), "6 vs. 5").isEqualTo(Dice.Result.WIN)
assertThat(Dice.winLoseOrTie(5, 6), "5 vs. 6").isEqualTo(Dice.Result.LOSE)
}
}

View file

@ -31,11 +31,20 @@
*/
package net.thauvin.erik.mobibot.modules
import assertk.all
import assertk.assertThat
import assertk.assertions.contains
import assertk.assertions.hasNoCause
import assertk.assertions.isEqualTo
import assertk.assertions.isFailure
import assertk.assertions.isInstanceOf
import assertk.assertions.isNotEmpty
import assertk.assertions.prop
import net.thauvin.erik.mobibot.ExceptionSanitizer.sanitize
import net.thauvin.erik.mobibot.LocalProperties
import net.thauvin.erik.mobibot.Sanitize.sanitizeException
import net.thauvin.erik.mobibot.modules.GoogleSearch.Companion.searchGoogle
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
import net.thauvin.erik.mobibot.msg.ErrorMessage
import net.thauvin.erik.mobibot.msg.Message
import org.testng.annotations.Test
/**
@ -49,23 +58,33 @@ class GoogleSearchTest : LocalProperties() {
val cseKey = getProperty(GoogleSearch.GOOGLE_CSE_KEY_PROP)
try {
var messages = searchGoogle("mobitopia", apiKey, cseKey)
assertThat(messages).describedAs("mobitopia results not empty").isNotEmpty
assertThat(messages[0].msg).describedAs("found mobibtopia").containsIgnoringCase("mobitopia")
assertThat(messages, "mobitopia results not empty").isNotEmpty()
assertThat(messages[0].msg, "found mobibtopia").contains("mobitopia", true)
messages = searchGoogle("aapl", apiKey, cseKey)
assertThat(messages).describedAs("aapl results not empty").isNotEmpty
assertThat(messages[0].msg).describedAs("found apple").containsIgnoringCase("apple")
assertThatThrownBy { searchGoogle("test", "", "apiKey") }
.describedAs("no API key")
assertThat(messages, "aapl results not empty").isNotEmpty()
assertThat(messages[0].msg, "found apple").contains("apple", true)
messages = searchGoogle("adadflkjl", apiKey, cseKey)
assertThat(messages[0], "not found").all {
isInstanceOf(ErrorMessage::class.java)
prop(Message::msg).isEqualTo("No results found.")
}
assertThat(
searchGoogle("", "apikey", "cssKey").first(),
"empty query"
).isInstanceOf(ErrorMessage::class.java)
assertThat { searchGoogle("test", "", "apiKey") }.isFailure()
.isInstanceOf(ModuleException::class.java).hasNoCause()
assertThatThrownBy { searchGoogle("test", "apiKey", "") }
.describedAs("no CSE API key")
assertThat { searchGoogle("test", "apiKey", "") }.isFailure()
.isInstanceOf(ModuleException::class.java).hasNoCause()
assertThatThrownBy { searchGoogle("", "apikey", "apiKey") }
.describedAs("no query").isInstanceOf(ModuleException::class.java).hasNoCause()
} catch (e: ModuleException) {
// Avoid displaying api keys in CI logs
if ("true" == System.getenv("CI")) {
throw sanitizeException(e, apiKey, cseKey)
throw e.sanitize(apiKey, cseKey)
} else {
throw e
}

View file

@ -31,8 +31,11 @@
*/
package net.thauvin.erik.mobibot.modules
import assertk.all
import assertk.assertThat
import assertk.assertions.contains
import assertk.assertions.isNotEmpty
import net.thauvin.erik.mobibot.modules.Joke.Companion.randomJoke
import org.assertj.core.api.Assertions.assertThat
import org.testng.annotations.Test
/**
@ -42,7 +45,9 @@ class JokeTest {
@Test
@Throws(ModuleException::class)
fun testRandomJoke() {
assertThat(randomJoke().msg).describedAs("randomJoke() > 0").isNotEmpty
assertThat(randomJoke().msg).describedAs("randomJoke()").containsIgnoringCase("chuck")
assertThat(randomJoke().msg, "randomJoke() > 0").all {
isNotEmpty()
contains("chuck", true)
}
}
}

View file

@ -31,9 +31,11 @@
*/
package net.thauvin.erik.mobibot.modules
import assertk.assertThat
import assertk.assertions.any
import assertk.assertions.contains
import net.thauvin.erik.mobibot.modules.Lookup.Companion.nslookup
import net.thauvin.erik.mobibot.modules.Lookup.Companion.whois
import org.assertj.core.api.Assertions.assertThat
import org.testng.annotations.Test
/**
@ -44,14 +46,13 @@ class LookupTest {
@Throws(Exception::class)
fun testLookup() {
val result = nslookup("apple.com")
assertThat(result).describedAs("lookup(apple.com)").contains("17.253.144.10")
assertThat(result, "lookup(apple.com)").contains("17.253.144.10")
}
@Test
@Throws(Exception::class)
fun testWhois() {
val result = whois("17.178.96.59", Lookup.WHOIS_HOST)
assertThat(result).describedAs("whois(17.178.96.59/Apple Inc.")
.anyMatch { it.contains("Apple Inc.") }
assertThat(result, "whois(17.178.96.59/Apple Inc.").any { it.contains("Apple Inc.") }
}
}

View file

@ -31,8 +31,16 @@
*/
package net.thauvin.erik.mobibot.modules
import net.thauvin.erik.mobibot.Sanitize.sanitizeException
import org.assertj.core.api.Assertions.assertThat
import assertk.all
import assertk.assertThat
import assertk.assertions.contains
import assertk.assertions.doesNotContain
import assertk.assertions.endsWith
import assertk.assertions.hasMessage
import assertk.assertions.isEqualTo
import assertk.assertions.isNotNull
import assertk.assertions.isNull
import net.thauvin.erik.mobibot.ExceptionSanitizer.sanitize
import org.testng.annotations.DataProvider
import org.testng.annotations.Test
import java.io.IOException
@ -58,37 +66,41 @@ class ModuleExceptionTest {
@Test(dataProvider = "dp")
fun testGetDebugMessage(e: ModuleException) {
assertThat(e.debugMessage).describedAs("get debug message").isEqualTo(debugMessage)
assertThat(e.debugMessage, "get debug message").isEqualTo(debugMessage)
}
@Test(dataProvider = "dp")
fun testGetMessage(e: ModuleException) {
assertThat(e).describedAs("get message").hasMessage(message)
assertThat(e, "get message").hasMessage(message)
}
@Test
fun testSanitizeMessage() {
val apiKey = "1234567890"
var e = ModuleException(debugMessage, message, IOException("URL http://foo.com?apiKey=$apiKey&userID=me"))
assertThat(sanitizeException(e, apiKey, "", "me")).describedAs("sanitized url")
.hasMessageContainingAll("xxxxxxxxxx", "userID=xx", "java.io.IOException")
.hasMessageNotContainingAny(apiKey, "me")
assertThat(e.sanitize(apiKey, "", "me").message, "sanitized url").isNotNull().all {
contains("xxxxxxxxxx", "userID=xx", "java.io.IOException")
doesNotContain(apiKey, "me")
}
e = ModuleException(debugMessage, message, null)
assertThat(sanitizeException(e, apiKey)).describedAs("no cause").hasMessage(message)
assertThat(e.sanitize(apiKey), "no cause").hasMessage(message)
e = ModuleException(debugMessage, message, IOException())
assertThat(sanitizeException(e, apiKey)).describedAs("no cause message").hasMessage(message)
assertThat(e.sanitize(apiKey), "no cause message").hasMessage(message)
e = ModuleException(apiKey)
assertThat(sanitizeException(e, apiKey)).describedAs("api key in message").hasMessageNotContaining(apiKey)
assertThat(e.sanitize(apiKey).message, "api key in message").isNotNull().doesNotContain(apiKey)
val msg: String? = null
e = ModuleException(debugMessage, msg, IOException(msg))
assertThat(sanitizeException(e, apiKey).message).describedAs("null message").isNull()
assertThat(e.sanitize(apiKey).message, "null message").isNull()
e = ModuleException(msg, msg, IOException("foo is $apiKey"))
assertThat(sanitizeException(e, " ", apiKey, "foo").message).describedAs("key in cause")
.doesNotContain(apiKey).endsWith("xxx is xxxxxxxxxx")
assertThat(e.sanitize(" ", apiKey, "foo").message, "key in cause").isNotNull().all {
doesNotContain(apiKey)
endsWith("xxx is xxxxxxxxxx")
}
assertThat(e.sanitize(), "empty").isEqualTo(e)
}
}

View file

@ -31,8 +31,10 @@
*/
package net.thauvin.erik.mobibot.modules
import assertk.assertThat
import assertk.assertions.contains
import assertk.assertions.isNotEmpty
import net.thauvin.erik.mobibot.modules.Ping.Companion.randomPing
import org.assertj.core.api.Assertions.assertThat
import org.testng.annotations.Test
/**
@ -41,13 +43,13 @@ import org.testng.annotations.Test
class PingTest {
@Test
fun testPingsArray() {
assertThat(Ping.PINGS).describedAs("Pings array is not empty.").isNotEmpty
assertThat(Ping.PINGS, "Pings array is not empty.").isNotEmpty()
}
@Test
fun testRandomPing() {
for (i in 0..9) {
assertThat(randomPing()).describedAs("Random ping $i").isIn(Ping.PINGS)
assertThat(Ping.PINGS, "Random ping $i").contains(randomPing())
}
}
}

View file

@ -32,23 +32,19 @@
package net.thauvin.erik.mobibot.modules
import org.assertj.core.api.Assertions.assertThat
import assertk.assertThat
import assertk.assertions.isEqualTo
import org.testng.annotations.Test
class RockPaperScissorsTest {
@Test
fun testWinLoseOrDraw() {
assertThat(RockPaperScissors.winLoseOrDraw("scissors", "paper")).describedAs("scissors vs. paper")
.isEqualTo("win")
assertThat(RockPaperScissors.winLoseOrDraw("paper", "rock")).describedAs("paper vs. rock").isEqualTo("win")
assertThat(RockPaperScissors.winLoseOrDraw("rock", "scissors")).describedAs("rock vs. scissors")
.isEqualTo("win")
assertThat(RockPaperScissors.winLoseOrDraw("paper", "scissors")).describedAs("paper vs. scissors")
.isEqualTo("lose")
assertThat(RockPaperScissors.winLoseOrDraw("rock", "paper")).describedAs("rock vs. paper").isEqualTo("lose")
assertThat(RockPaperScissors.winLoseOrDraw("scissors", "rock")).describedAs("scissors vs. rock")
.isEqualTo("lose")
assertThat(RockPaperScissors.winLoseOrDraw("scissors", "scissors"))
.describedAs("scissors vs. scissors").isEqualTo("draw")
assertThat(RockPaperScissors.winLoseOrDraw("scissors", "paper"), "scissors vs. paper").isEqualTo("win")
assertThat(RockPaperScissors.winLoseOrDraw("paper", "rock"), "paper vs. rock").isEqualTo("win")
assertThat(RockPaperScissors.winLoseOrDraw("rock", "scissors"), "rock vs. scissors").isEqualTo("win")
assertThat(RockPaperScissors.winLoseOrDraw("paper", "scissors"), "paper vs. scissors").isEqualTo("lose")
assertThat(RockPaperScissors.winLoseOrDraw("rock", "paper"), "rock vs. paper").isEqualTo("lose")
assertThat(RockPaperScissors.winLoseOrDraw("scissors", "rock"), "scissors vs. rock").isEqualTo("lose")
assertThat(RockPaperScissors.winLoseOrDraw("scissors", "scissors"), "scissors vs. scissors").isEqualTo("draw")
}
}

View file

@ -31,11 +31,20 @@
*/
package net.thauvin.erik.mobibot.modules
import assertk.all
import assertk.assertThat
import assertk.assertions.hasNoCause
import assertk.assertions.isEqualTo
import assertk.assertions.isFailure
import assertk.assertions.isInstanceOf
import assertk.assertions.isNotEmpty
import assertk.assertions.matches
import assertk.assertions.prop
import net.thauvin.erik.mobibot.ExceptionSanitizer.sanitize
import net.thauvin.erik.mobibot.LocalProperties
import net.thauvin.erik.mobibot.Sanitize.sanitizeException
import net.thauvin.erik.mobibot.modules.StockQuote.Companion.getQuote
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
import net.thauvin.erik.mobibot.msg.ErrorMessage
import net.thauvin.erik.mobibot.msg.Message
import org.testng.annotations.Test
/**
@ -52,24 +61,25 @@ class StockQuoteTest : LocalProperties() {
val apiKey = getProperty(StockQuote.ALPHAVANTAGE_API_KEY_PROP)
try {
val messages = getQuote("apple inc", apiKey)
assertThat(messages).describedAs("response not empty").isNotEmpty
assertThat(messages[0].msg).describedAs("same stock symbol").matches("Symbol: AAPL .*")
assertThat(messages[1].msg).describedAs("price label").matches(buildMatch("Price"))
assertThat(messages[2].msg).describedAs("previous label").matches(buildMatch("Previous"))
assertThat(messages[3].msg).describedAs("open label").matches(buildMatch("Open"))
try {
getQuote("blahfoo", apiKey)
} catch (e: ModuleException) {
assertThat(e.message).describedAs("invalid symbol").containsIgnoringCase(StockQuote.INVALID_SYMBOL)
assertThat(messages, "response not empty").isNotEmpty()
assertThat(messages[0].msg, "same stock symbol").matches("Symbol: AAPL .*".toRegex())
assertThat(messages[1].msg, "price label").matches(buildMatch("Price").toRegex())
assertThat(messages[2].msg, "previous label").matches(buildMatch("Previous").toRegex())
assertThat(messages[3].msg, "open label").matches(buildMatch("Open").toRegex())
assertThat(getQuote("blahfoo", apiKey).first(), "invalid symbol").all {
isInstanceOf(ErrorMessage::class.java)
prop(Message::msg).isEqualTo(StockQuote.INVALID_SYMBOL)
}
assertThatThrownBy { getQuote("test", "") }.describedAs("no API key")
.isInstanceOf(ModuleException::class.java).hasNoCause()
assertThatThrownBy { getQuote("", "apikey") }.describedAs("no symbol")
.isInstanceOf(ModuleException::class.java).hasNoCause()
assertThat(getQuote("", "apikey").first(), "empty symbol").all {
isInstanceOf(ErrorMessage::class.java)
prop(Message::msg).isEqualTo(StockQuote.INVALID_SYMBOL)
}
assertThat { getQuote("test", "") }.isFailure().isInstanceOf(ModuleException::class.java).hasNoCause()
} catch (e: ModuleException) {
// Avoid displaying api keys in CI logs
if ("true" == System.getenv("CI")) {
throw sanitizeException(e, apiKey)
throw e.sanitize(apiKey)
} else {
throw e
}

View file

@ -31,9 +31,11 @@
*/
package net.thauvin.erik.mobibot.modules
import assertk.assertThat
import assertk.assertions.isEqualTo
import assertk.assertions.isSuccess
import net.thauvin.erik.mobibot.LocalProperties
import net.thauvin.erik.mobibot.modules.Twitter.Companion.twitterPost
import org.assertj.core.api.Assertions.assertThat
import org.testng.annotations.Test
import java.net.InetAddress
import java.net.UnknownHostException
@ -56,7 +58,7 @@ class TwitterTest : LocalProperties() {
@Throws(ModuleException::class)
fun testPostTwitter() {
val msg = "Testing Twitter API from $ci"
assertThat(
assertThat {
twitterPost(
getProperty(Twitter.CONSUMER_KEY_PROP),
getProperty(Twitter.CONSUMER_SECRET_PROP),
@ -65,7 +67,7 @@ class TwitterTest : LocalProperties() {
getProperty(Twitter.HANDLE_PROP),
msg,
true
).msg
).describedAs("twitterPost($msg)").isEqualTo(msg)
)
}.isSuccess().isEqualTo(msg)
}
}

View file

@ -31,6 +31,16 @@
*/
package net.thauvin.erik.mobibot.modules
import assertk.all
import assertk.assertThat
import assertk.assertions.contains
import assertk.assertions.endsWith
import assertk.assertions.hasNoCause
import assertk.assertions.isEqualTo
import assertk.assertions.isFailure
import assertk.assertions.isInstanceOf
import assertk.assertions.isNotNull
import assertk.assertions.isTrue
import net.aksingh.owmjapis.api.APIException
import net.aksingh.owmjapis.core.OWM
import net.thauvin.erik.mobibot.LocalProperties
@ -39,8 +49,6 @@ import net.thauvin.erik.mobibot.modules.Weather2.Companion.ftoC
import net.thauvin.erik.mobibot.modules.Weather2.Companion.getCountry
import net.thauvin.erik.mobibot.modules.Weather2.Companion.getWeather
import net.thauvin.erik.mobibot.modules.Weather2.Companion.mphToKmh
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.testng.annotations.Test
import kotlin.random.Random
@ -51,50 +59,63 @@ class Weather2Test : LocalProperties() {
@Test
fun testFtoC() {
val t = ftoC(32.0)
assertThat(t.second).describedAs("32 °F is 0 °C").isEqualTo(0)
assertThat(t.second, "32 °F is 0 °C").isEqualTo(0)
}
@Test
fun testGetCountry() {
assertThat(getCountry("foo")).describedAs("not a country").isEqualTo(OWM.Country.UNITED_STATES)
assertThat(getCountry("fr")).describedAs("fr is france").isEqualTo(OWM.Country.FRANCE)
assertThat(getCountry("foo"), "not a country").isEqualTo(OWM.Country.UNITED_STATES)
assertThat(getCountry("fr"), "fr is france").isEqualTo(OWM.Country.FRANCE)
val country = OWM.Country.values()
repeat(3) {
val rand = country[Random.nextInt(0, country.size - 1)]
assertThat(getCountry(rand.value)).describedAs(rand.name).isEqualTo(rand)
assertThat(getCountry(rand.value), rand.name).isEqualTo(rand)
}
}
@Test
fun testMphToKmh() {
val w = mphToKmh(0.62)
assertThat(w.second).describedAs("0.62 mph is 1 km/h").isEqualTo(1)
assertThat(w.second, "0.62 mph is 1 km/h").isEqualTo(1)
}
@Test
@Throws(ModuleException::class)
fun testWeather() {
var messages = getWeather("98204", getProperty(OWM_API_KEY_PROP))
assertThat(messages[0].msg).describedAs("is Everett").contains("Everett, United States").contains("US")
assertThat(messages[messages.size - 1].msg).describedAs("is Everett zip code").endsWith("98204%2CUS")
assertThat(messages[0].msg, "is Everett").all {
contains("Everett, United States")
contains("US")
}
assertThat(messages[messages.size - 1].msg, "is Everett zip code").endsWith("98204%2CUS")
messages = getWeather("San Francisco", getProperty(OWM_API_KEY_PROP))
assertThat(messages[0].msg).describedAs("is San Francisco").contains("San Francisco").contains("US")
assertThat(messages[messages.size - 1].msg).describedAs("is San Fran city code").endsWith("5391959")
assertThat(messages[0].msg, "is San Francisco").all {
contains("San Francisco")
contains("US")
}
assertThat(messages[messages.size - 1].msg, "is San Fran city code").endsWith("5391959")
messages = getWeather("London, GB", getProperty(OWM_API_KEY_PROP))
assertThat(messages[0].msg).describedAs("is UK").contains("London, United Kingdom").contains("GB")
assertThat(messages[messages.size - 1].msg).describedAs("is London city code").endsWith("2643743")
assertThat(messages[0].msg, "is UK").all {
contains("London, United Kingdom")
contains("GB")
}
assertThat(messages[messages.size - 1].msg, "is London city code").endsWith("2643743")
assertThatThrownBy { getWeather("Foo, US", getProperty(OWM_API_KEY_PROP)) }
.describedAs("foo not found").hasCauseInstanceOf(APIException::class.java)
assertThatThrownBy { getWeather("test", "") }
.describedAs("no API key").isInstanceOf(ModuleException::class.java).hasNoCause()
assertThatThrownBy { getWeather("test", null) }
.describedAs("null API key").isInstanceOf(ModuleException::class.java).hasNoCause()
try {
getWeather("Foo, US", getProperty(OWM_API_KEY_PROP))
} catch (e: ModuleException) {
assertThat(e.cause, "cause is API exception").isNotNull().isInstanceOf(APIException::class.java)
}
assertThat { getWeather("test", "") }.isFailure()
.isInstanceOf(ModuleException::class.java).hasNoCause()
assertThat { getWeather("test", null) }.isFailure()
.isInstanceOf(ModuleException::class.java).hasNoCause()
messages = getWeather("", "apikey")
assertThat(messages[0].isError).describedAs("no query").isTrue
assertThat(messages[0].isError, "no query").isTrue()
}
}

View file

@ -31,14 +31,18 @@
*/
package net.thauvin.erik.mobibot.modules
import assertk.assertThat
import assertk.assertions.endsWith
import assertk.assertions.isSuccess
import assertk.assertions.matches
import assertk.assertions.startsWith
import net.thauvin.erik.mobibot.Utils.bold
import net.thauvin.erik.mobibot.modules.WorldTime.Companion.BEATS_KEYWORD
import net.thauvin.erik.mobibot.modules.WorldTime.Companion.COUNTRIES_MAP
import net.thauvin.erik.mobibot.modules.WorldTime.Companion.time
import org.assertj.core.api.Assertions.assertThat
import org.pircbotx.Colors
import org.testng.annotations.Test
import java.time.ZoneId
import java.time.zone.ZoneRulesException
/**
* The `WordTimeTest` class.
@ -46,16 +50,23 @@ import java.time.zone.ZoneRulesException
class WordTimeTest {
@Test
fun testTime() {
assertThat(time("PST").msg).describedAs("PST").endsWith(bold("Los Angeles"))
assertThat(time("BLAH").isError).describedAs("BLAH").isTrue
assertThat(time("BEAT").msg).describedAs(BEATS_KEYWORD).matches("[\\w ]+: .?@\\d{3}+.? .beats")
assertThat(time(), "no zone").matches(
("The time is ${Colors.BOLD}\\d{1,2}:\\d{2}${Colors.BOLD} " +
"on ${Colors.BOLD}\\w+, \\d{1,2} \\w+ \\d{4}${Colors.BOLD} " +
"in ${Colors.BOLD}Los Angeles${Colors.BOLD}").toRegex()
)
assertThat(time(""), "empty zone").endsWith(bold("Los Angeles"))
assertThat(time("PST"), "PST").endsWith(bold("Los Angeles"))
assertThat(time("GB"), "GB").endsWith(bold("London"))
assertThat(time("FR"), "FR").endsWith(bold("Paris"))
assertThat(time("BLAH"), "BLAH").startsWith("Unsupported")
assertThat(time("BEAT"), BEATS_KEYWORD).matches("[\\w ]+ .?@\\d{3}+.? .beats".toRegex())
}
@Test
@Throws(ZoneRulesException::class)
fun testCountries() {
fun testZones() {
COUNTRIES_MAP.filter { it.value != BEATS_KEYWORD }.forEach {
ZoneId.of(it.value)
assertThat { ZoneId.of(it.value) }.isSuccess()
}
}
}

View file

@ -32,7 +32,8 @@
package net.thauvin.erik.mobibot.msg
import org.assertj.core.api.Assertions.assertThat
import assertk.assertThat
import assertk.assertions.isTrue
import org.testng.annotations.Test
class TestMessage {
@ -41,15 +42,15 @@ class TestMessage {
var msg = Message()
msg.isError = true
assertThat(msg.isNotice).describedAs("message is notice").isTrue
assertThat(msg.isNotice, "message is notice").isTrue()
msg = Message("foo", isError = true)
assertThat(msg.isNotice).describedAs("message is notice too").isTrue
assertThat(msg.isNotice, "message is notice too").isTrue()
}
@Test
fun testErrorMessage() {
val msg = ErrorMessage("foo")
assertThat(msg.isNotice).describedAs("error message is notice").isTrue
assertThat(msg.isNotice, "error message is notice").isTrue()
}
}

View file

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
<channel>
<title>#mobibot IRC Links</title>
<link>https://www.mobitopia.org/mobibot/logs</link>
<description>Links from irc.example.com on #mobibot</description>
<language>en</language>
<pubDate>Sun, 31 Oct 2021 21:45:11 GMT</pubDate>
<dc:date>2021-10-31T21:45:11Z</dc:date>
<dc:language>en</dc:language>
<item>
<title>Example 2</title>
<link>https://www.example.com/2</link>
<description>Posted by &lt;b&gt;Skynx&lt;/b&gt; on &lt;a href="irc://irc.libera.chat/#mobibot"&gt;&lt;b&gt;#mobibot&lt;/b&gt;&lt;/a&gt;</description>
<category>tag2-1</category>
<category>tag2-2</category>
<pubDate>Sun, 31 Oct 2021 21:45:11 GMT</pubDate>
<guid>https://www.foo.com</guid>
<dc:creator>mobibot@irc.libera.chat (Skynx)</dc:creator>
<dc:date>2021-10-31T00:01:00Z</dc:date>
</item>
<item>
<title>Example 1</title>
<link>https://www.example.com/1</link>
<description>Posted by &lt;b&gt;ErikT&lt;/b&gt; on &lt;a href="irc://irc.libera.chat/#mobibot"&gt;&lt;b&gt;#mobibot&lt;/b&gt;&lt;/a&gt;
&lt;br/&gt;&lt;br/&gt;ErikT: This is comment 1. &lt;br/&gt;Skynx: This is comment 2.
</description>
<category>tag1-1</category>
<category>tag1-2</category>
<pubDate>Sun, 31 Oct 2021 21:43:15 GMT</pubDate>
<guid>https://www.example.com/</guid>
<dc:creator>mobibot@irc.libera.chat (ErikT)</dc:creator>
<dc:date>2021-10-31T00:00:00Z</dc:date>
</item>
</channel>
</rss>