From 726d7455f5a6b0fc208457f16ac5121aebbfebfc Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Sat, 3 May 2025 15:43:35 -0700 Subject: [PATCH] Cleanup tests --- .../net/thauvin/erik/akismet/AkismetTest.kt | 629 ++++++++++-------- 1 file changed, 334 insertions(+), 295 deletions(-) diff --git a/src/test/kotlin/net/thauvin/erik/akismet/AkismetTest.kt b/src/test/kotlin/net/thauvin/erik/akismet/AkismetTest.kt index 8741a43..3d047b3 100644 --- a/src/test/kotlin/net/thauvin/erik/akismet/AkismetTest.kt +++ b/src/test/kotlin/net/thauvin/erik/akismet/AkismetTest.kt @@ -39,6 +39,8 @@ import okhttp3.FormBody import okhttp3.HttpUrl.Companion.toHttpUrl import org.junit.Assert.assertThrows import org.junit.BeforeClass +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test import org.mockito.Mockito import org.mockito.Mockito.`when` @@ -75,304 +77,15 @@ fun getKey(key: String): String { } /** - * AKISMET_API_KEY and AKISMET_BLOG should be in env vars or local.properties + * [Akismet] Tests + * + * `AKISMET_API_KEY` and `AKISMET_BLOG` should be set in env vars or `local.properties` */ class AkismetTest { private val emptyFormBody = FormBody.Builder().build() - @Test - fun constructorsTest() { - assertThrows( - IllegalArgumentException::class.java - ) { - Akismet("") - } - assertThrows( - IllegalArgumentException::class.java - ) { - Akismet("1234") - } - assertThrows( - IllegalArgumentException::class.java - ) { - Akismet("123456789 12") - } - assertThrows( - IllegalArgumentException::class.java - ) { - Akismet("123456789012", "") - } - assertThrows( - IllegalArgumentException::class.java - ) { - Akismet("1234", "foo") - } - } - - @Test - fun blogPropertyTest() { - assertThrows(IllegalArgumentException::class.java) { - akismet.blog = "" - } - - assertThat(akismet::blog).isEqualTo(blog) - } - - @Test - fun validateConfigTest() { - assertThat(AkismetComment(config) == comment).isTrue() - } - - @Test - fun verifyKeyTest() { - assertThat(akismet, "akismet").all { - prop(Akismet::isVerifiedKey).isFalse() - prop(Akismet::verifyKey).isTrue() - prop(Akismet::response).isEqualTo("valid") - prop(Akismet::isVerifiedKey).isTrue() - } - - akismet.reset() - assertThat(akismet, "akismet.reset()").all { - prop(Akismet::isVerifiedKey).isFalse() - prop(Akismet::response).isEmpty() - prop(Akismet::httpStatusCode).isEqualTo(0) - } - - assertThat(Akismet("123456789012"), "akismet(123456789012)").prop(Akismet::verifyKey).isFalse() - } - - @Test - fun mockCommentTest() { - assertThat(mockComment, "mockComment").all { - prop(AkismetComment::userIp).isEqualTo(comment.userIp) - prop(AkismetComment::userAgent).isEqualTo(comment.userAgent) - prop(AkismetComment::referrer).isEqualTo(comment.referrer) - prop(AkismetComment::serverEnv).all { - key("HTTP_ACCEPT_ENCODING").isEqualTo("gzip") - key("REMOTE_ADDR").isEqualTo(comment.userIp) - key("HTTP_NULL").isEmpty() - size().isEqualTo(6) - } - } - } - - @Test - fun emptyCommentTest() { - assertThrows( - java.lang.IllegalArgumentException::class.java - ) { akismet.checkComment(AkismetComment("", "")) } - - - val empty = AkismetComment("", "") - assertThat(empty, "AkismetComment(empty)").all { - prop(AkismetComment::isTest).isFalse() - prop(AkismetComment::referrer).isEqualTo("") - prop(AkismetComment::permalink).isEqualTo("") - prop(AkismetComment::type).isEqualTo(CommentType.NONE) - prop(AkismetComment::authorEmail).isEqualTo("") - prop(AkismetComment::author).isEqualTo("") - prop(AkismetComment::authorUrl).isEqualTo("") - prop(AkismetComment::content).isEqualTo("") - prop(AkismetComment::dateGmt).isEqualTo("") - prop(AkismetComment::postModifiedGmt).isEqualTo("") - prop(AkismetComment::blogLang).isEqualTo("") - prop(AkismetComment::blogCharset).isEqualTo("") - prop(AkismetComment::userRole).isEqualTo("") - prop(AkismetComment::recheckReason).isEqualTo("") - prop(AkismetComment::serverEnv).size().isEqualTo(0) - } - - with(receiver = empty) { - for (s in listOf("test", "", null)) { - referrer = s - permalink = s - if (s != null) type = CommentType(s) - authorEmail = s - author = s - authorUrl = s - content = s - dateGmt = s - postModifiedGmt = s - blogLang = s - blogCharset = s - userRole = s - recheckReason = s - - val expected = if (s.isNullOrEmpty()) "" else s - - assertThat(empty, "AkismetComment($s)").all { - prop(AkismetComment::referrer).isEqualTo(expected) - prop(AkismetComment::permalink).isEqualTo(expected) - prop(AkismetComment::type).isEqualTo(CommentType(expected)) - prop(AkismetComment::authorEmail).isEqualTo(expected) - prop(AkismetComment::author).isEqualTo(expected) - prop(AkismetComment::authorUrl).isEqualTo(expected) - prop(AkismetComment::content).isEqualTo(expected) - prop(AkismetComment::dateGmt).isEqualTo(expected) - prop(AkismetComment::postModifiedGmt).isEqualTo(expected) - prop(AkismetComment::blogLang).isEqualTo(expected) - prop(AkismetComment::blogCharset).isEqualTo(expected) - prop(AkismetComment::userRole).isEqualTo(expected) - prop(AkismetComment::recheckReason).isEqualTo(expected) - prop(AkismetComment::serverEnv).size().isEqualTo(0) - } - } - } - } - - @Test - fun emptyResponseTest() { - assertTrue( - akismet.executeMethod( - "https://postman-echo.com/status/200".toHttpUrl(), emptyFormBody, true - ) - ) - var expected = "{\n \"status\": 200\n}" - assertThat(akismet, "executeMethod(200)").all { - prop(Akismet::response).isEqualTo(expected) - prop(Akismet::errorMessage).contains(expected) - } - - akismet.reset() - assertThat(akismet, "akismet.reset()").all { - prop(Akismet::httpStatusCode).isEqualTo(0) - prop(Akismet::errorMessage).isEmpty() - } - - assertTrue( - akismet.executeMethod( - "https://erik.thauvin.net/blank.html".toHttpUrl(), emptyFormBody, true - ) - ) - expected = "" - assertThat(akismet, "executeMethod(blank)").all { - prop(Akismet::response).isEqualTo(expected) - prop(Akismet::errorMessage).contains("blank") - } - } - - @Test - fun proTipResponseTest() { - assertFalse( - akismet.executeMethod( - "https://postman-echo.com/response-headers?x-akismet-pro-tip=discard".toHttpUrl(), - emptyFormBody - ) - ) - - assertThat(akismet, "executeMethod(pro-tip)").all { - prop(Akismet::proTip).isEqualTo("discard") - prop(Akismet::isDiscard).isTrue() - } - - akismet.reset() - assertThat(akismet, "akismet.reset()").all { - prop(Akismet::isDiscard).isFalse() - prop(Akismet::response).isEmpty() - prop(Akismet::httpStatusCode).isEqualTo(0) - } - } - - @Test - fun checkCommentTest() { - with(akismet) { - assertFalse(checkComment(comment), "checkComment(admin)") - assertThat(akismet::response).isEqualTo("false") - - comment.userRole = "" - assertTrue(checkComment(comment), "checkComment()") - assertThat(akismet::response).isEqualTo("true") - - assertFalse(checkComment(mockComment), "checkComment(mock)") - assertThat(akismet::response).isEqualTo("false") - - mockComment.userRole = "" - assertTrue(checkComment(mockComment), "checkComment(mock)") - assertThat(akismet::response).isEqualTo("true") - - assertThat(akismet::httpStatusCode).isEqualTo(200) - } - } - - @Test - fun executeMethodTest() { - akismet.executeMethod( - "https://$apiKey.rest.akismet.com/1.1/comment-check".toHttpUrl(), - FormBody.Builder().apply { add("is_test", "1") }.build() - ) - assertThat(akismet::debugHelp).isNotEmpty() - - akismet.reset() - assertThat(akismet, "akismet.reset()").all { - prop(Akismet::httpStatusCode).isEqualTo(0) - prop(Akismet::debugHelp).isEmpty() - prop(Akismet::response).isEmpty() - } - } - - @Test - fun invalidApiTest() { - assertThrows( - java.lang.IllegalArgumentException::class.java - ) { akismet.executeMethod("https://.com".toHttpUrl(), emptyFormBody) } - - } - - @Test - fun ioErrorTest() { - akismet.executeMethod("https://www.foobarxyz.com".toHttpUrl(), emptyFormBody) - assertThat(akismet::errorMessage).contains("IO error") - } - - @Test - fun submitHamTest() { - assertTrue(akismet.submitHam(comment), "submitHam") - - assertTrue(akismet.submitHam(mockComment), "submitHam(mock)") - } - - @Test - fun submitSpamTest() { - assertTrue(akismet.submitSpam(comment), "submitHam") - assertTrue(akismet.submitSpam(mockComment), "submitHam(mock)") - } - - @Test - fun jsonCommentTest() { - val jsonComment = Akismet.jsonComment(mockComment.toJson()) - - assertEquals(jsonComment, mockComment, "jsonComment = mockComment") - assertEquals(jsonComment.hashCode(), mockComment.hashCode(), "jsonComment.hashCode = mockComment.hashcode") - - assertNotEquals(jsonComment, comment, "json") - assertNotEquals(jsonComment.hashCode(), comment.hashCode(), "jsonComment.hashCode != mockComment.hashcode") - - jsonComment.recheckReason = "" - assertNotEquals(jsonComment, mockComment, "jsonComment != jsonComment") - - assertThat(this, "this != comment").isNotEqualTo(comment) - } - - @Test - fun buildUserAgentTest() { - val libAgent = "${GeneratedVersion.PROJECT}/${GeneratedVersion.VERSION}" - assertEquals(akismet.buildUserAgent(), libAgent, "buildUserAgent()") - - akismet.appUserAgent = "My App/1.0" - assertEquals(akismet.buildUserAgent(), "${akismet.appUserAgent} | $libAgent", "buildUserAgent(my app)") - } - - @Test - fun dateToGmtTest() { - val localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()) - val utcDate = Akismet.dateToGmt(date) - assertEquals(Akismet.dateToGmt(localDateTime), utcDate, "dateGmt(localDateTime)") - assertThat(comment::dateGmt).isEqualTo(utcDate) - } - companion object { - private const val REFERER = "http://www.google.com" + private const val REFERER = "https://www.google.com" private val apiKey = getKey("AKISMET_API_KEY") private val blog = getKey("AKISMET_BLOG") private val akismet = Akismet(apiKey, blog) @@ -383,11 +96,11 @@ class AkismetTest { private val date = Date() private val config = CommentConfig.Builder(comment.userIp, comment.userAgent) .referrer(REFERER) - .permalink("http://yourblogdomainname.com/blog/post=1") + .permalink("https://yourblogdomainname.com/blog/post=1") .type(CommentType.COMMENT) .author("admin") .authorEmail("test@test.com") - .authorUrl("http://www.CheckOutMyCoolSite.com") + .authorUrl("https://www.CheckOutMyCoolSite.com") .content("It means a lot that you would take the time to review our software. Thanks again.") .dateGmt(Akismet.dateToGmt(date)) .postModifiedGmt(Akismet.dateToGmt(date)) @@ -462,4 +175,330 @@ class AkismetTest { return request } } + + @Nested + @DisplayName("Comment Tests") + inner class CommentTests { + @Test + fun checkComment() { + with(akismet) { + assertFalse(checkComment(comment), "checkComment(admin)") + assertThat(akismet::response).isEqualTo("false") + + comment.userRole = "" + assertTrue(checkComment(comment), "checkComment()") + assertThat(akismet::response).isEqualTo("true") + + assertFalse(checkComment(mockComment), "checkComment(mock)") + assertThat(akismet::response).isEqualTo("false") + + mockComment.userRole = "" + assertTrue(checkComment(mockComment), "checkComment(mock)") + assertThat(akismet::response).isEqualTo("true") + + assertThat(akismet::httpStatusCode).isEqualTo(200) + } + } + + @Test + fun emptyComment() { + assertThrows( + java.lang.IllegalArgumentException::class.java + ) { akismet.checkComment(AkismetComment("", "")) } + + + val empty = AkismetComment("", "") + assertThat(empty, "AkismetComment(empty)").all { + prop(AkismetComment::isTest).isFalse() + prop(AkismetComment::referrer).isEqualTo("") + prop(AkismetComment::permalink).isEqualTo("") + prop(AkismetComment::type).isEqualTo(CommentType.NONE) + prop(AkismetComment::authorEmail).isEqualTo("") + prop(AkismetComment::author).isEqualTo("") + prop(AkismetComment::authorUrl).isEqualTo("") + prop(AkismetComment::content).isEqualTo("") + prop(AkismetComment::dateGmt).isEqualTo("") + prop(AkismetComment::postModifiedGmt).isEqualTo("") + prop(AkismetComment::blogLang).isEqualTo("") + prop(AkismetComment::blogCharset).isEqualTo("") + prop(AkismetComment::userRole).isEqualTo("") + prop(AkismetComment::recheckReason).isEqualTo("") + prop(AkismetComment::serverEnv).size().isEqualTo(0) + } + + with(receiver = empty) { + for (s in listOf("test", "", null)) { + referrer = s + permalink = s + if (s != null) type = CommentType(s) + authorEmail = s + author = s + authorUrl = s + content = s + dateGmt = s + postModifiedGmt = s + blogLang = s + blogCharset = s + userRole = s + recheckReason = s + + val expected = if (s.isNullOrEmpty()) "" else s + + assertThat(empty, "AkismetComment($s)").all { + prop(AkismetComment::referrer).isEqualTo(expected) + prop(AkismetComment::permalink).isEqualTo(expected) + prop(AkismetComment::type).isEqualTo(CommentType(expected)) + prop(AkismetComment::authorEmail).isEqualTo(expected) + prop(AkismetComment::author).isEqualTo(expected) + prop(AkismetComment::authorUrl).isEqualTo(expected) + prop(AkismetComment::content).isEqualTo(expected) + prop(AkismetComment::dateGmt).isEqualTo(expected) + prop(AkismetComment::postModifiedGmt).isEqualTo(expected) + prop(AkismetComment::blogLang).isEqualTo(expected) + prop(AkismetComment::blogCharset).isEqualTo(expected) + prop(AkismetComment::userRole).isEqualTo(expected) + prop(AkismetComment::recheckReason).isEqualTo(expected) + prop(AkismetComment::serverEnv).size().isEqualTo(0) + } + } + } + } + + @Test + fun jsonComment() { + val jsonComment = Akismet.jsonComment(mockComment.toJson()) + + assertEquals(jsonComment, mockComment, "jsonComment = mockComment") + assertEquals(jsonComment.hashCode(), mockComment.hashCode(), "jsonComment.hashCode = mockComment.hashcode") + + assertNotEquals(jsonComment, comment, "json") + assertNotEquals(jsonComment.hashCode(), comment.hashCode(), "jsonComment.hashCode != mockComment.hashcode") + + jsonComment.recheckReason = "" + assertNotEquals(jsonComment, mockComment, "jsonComment != jsonComment") + + assertThat(this, "this != comment").isNotEqualTo(comment) + } + + @Test + fun mockComment() { + assertThat(mockComment, "mockComment").all { + prop(AkismetComment::userIp).isEqualTo(comment.userIp) + prop(AkismetComment::userAgent).isEqualTo(comment.userAgent) + prop(AkismetComment::referrer).isEqualTo(comment.referrer) + prop(AkismetComment::serverEnv).all { + key("HTTP_ACCEPT_ENCODING").isEqualTo("gzip") + key("REMOTE_ADDR").isEqualTo(comment.userIp) + key("HTTP_NULL").isEmpty() + size().isEqualTo(6) + } + } + } + } + + @Nested + @DisplayName("Constructor Tests") + inner class ConstructorTests { + @Test + fun apiKeyTooLong() { + assertThrows( + IllegalArgumentException::class.java + ) { + Akismet("123456789 12") + } + } + + @Test + fun apiKeyTooShort() { + assertThrows( + IllegalArgumentException::class.java + ) { + Akismet("1234") + } + } + + @Test + fun invalidKeyAndBlog() { + assertThrows( + IllegalArgumentException::class.java + ) { + Akismet("1234", "foo") + } + } + + @Test + fun noApiKey() { + assertThrows( + IllegalArgumentException::class.java + ) { + Akismet("") + } + } + + @Test + fun noBlog() { + assertThrows( + IllegalArgumentException::class.java + ) { + Akismet("123456789012", "") + } + } + } + + @Test + fun dateToGmtTest() { + val localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()) + val utcDate = Akismet.dateToGmt(date) + assertEquals(Akismet.dateToGmt(localDateTime), utcDate, "dateGmt(localDateTime)") + assertThat(comment::dateGmt).isEqualTo(utcDate) + } + + @Nested + @DisplayName("Response Tests") + inner class ResponseTests { + @Test + fun emptyResponse() { + assertTrue( + akismet.executeMethod( + "https://postman-echo.com/status/200".toHttpUrl(), emptyFormBody, true + ) + ) + var expected = "{\n \"status\": 200\n}" + assertThat(akismet, "executeMethod(200)").all { + prop(Akismet::response).isEqualTo(expected) + prop(Akismet::errorMessage).contains(expected) + } + + akismet.reset() + assertThat(akismet, "akismet.reset()").all { + prop(Akismet::httpStatusCode).isEqualTo(0) + prop(Akismet::errorMessage).isEmpty() + } + + assertTrue( + akismet.executeMethod( + "https://erik.thauvin.net/blank.html".toHttpUrl(), emptyFormBody, true + ) + ) + expected = "" + assertThat(akismet, "executeMethod(blank)").all { + prop(Akismet::response).isEqualTo(expected) + prop(Akismet::errorMessage).contains("blank") + } + } + + @Test + fun executeMethod() { + akismet.executeMethod( + "https://$apiKey.rest.akismet.com/1.1/comment-check".toHttpUrl(), + FormBody.Builder().apply { add("is_test", "1") }.build() + ) + assertThat(akismet::debugHelp).isNotEmpty() + + akismet.reset() + assertThat(akismet, "akismet.reset()").all { + prop(Akismet::httpStatusCode).isEqualTo(0) + prop(Akismet::debugHelp).isEmpty() + prop(Akismet::response).isEmpty() + } + } + + @Test + fun invalidApi() { + assertThrows( + java.lang.IllegalArgumentException::class.java + ) { akismet.executeMethod("https://.com".toHttpUrl(), emptyFormBody) } + } + + @Test + fun ioError() { + akismet.executeMethod("https://www.foobarxyz.com".toHttpUrl(), emptyFormBody) + assertThat(akismet::errorMessage).contains("IO error") + } + + @Test + fun proTipResponse() { + assertFalse( + akismet.executeMethod( + "https://postman-echo.com/response-headers?x-akismet-pro-tip=discard".toHttpUrl(), + emptyFormBody + ) + ) + + assertThat(akismet, "executeMethod(pro-tip)").all { + prop(Akismet::proTip).isEqualTo("discard") + prop(Akismet::isDiscard).isTrue() + } + + akismet.reset() + assertThat(akismet, "akismet.reset()").all { + prop(Akismet::isDiscard).isFalse() + prop(Akismet::response).isEmpty() + prop(Akismet::httpStatusCode).isEqualTo(0) + } + } + } + + @Nested + @DisplayName("Submit Test") + inner class SubmitTests { + @Test + fun submitHam() { + assertTrue(akismet.submitHam(comment), "submitHam") + assertTrue(akismet.submitHam(mockComment), "submitHam(mock)") + } + + @Test + fun submitSpam() { + assertTrue(akismet.submitSpam(comment), "submitHam") + assertTrue(akismet.submitSpam(mockComment), "submitHam(mock)") + } + } + + @Nested + @DisplayName("Validation Tests") + inner class ValidationTests { + + @Test + fun blogProperty() { + assertThrows(IllegalArgumentException::class.java) { + akismet.blog = "" + } + + assertThat(akismet::blog).isEqualTo(blog) + } + + @Test + fun validateConfig() { + assertThat(AkismetComment(config) == comment).isTrue() + } + + @Test + fun verifyKey() { + assertThat(akismet, "akismet").all { + prop(Akismet::isVerifiedKey).isFalse() + prop(Akismet::verifyKey).isTrue() + prop(Akismet::response).isEqualTo("valid") + prop(Akismet::isVerifiedKey).isTrue() + } + + akismet.reset() + assertThat(akismet, "akismet.reset()").all { + prop(Akismet::isVerifiedKey).isFalse() + prop(Akismet::response).isEmpty() + prop(Akismet::httpStatusCode).isEqualTo(0) + } + + assertThat(Akismet("123456789012"), "akismet(123456789012)").prop(Akismet::verifyKey).isFalse() + } + + @Test + fun userAgent() { + val libAgent = "${GeneratedVersion.PROJECT}/${GeneratedVersion.VERSION}" + assertEquals(akismet.buildUserAgent(), libAgent, "buildUserAgent($libAgent)") + + akismet.appUserAgent = "My App/1.0" + assertEquals(akismet.buildUserAgent(), "${akismet.appUserAgent} | $libAgent", "buildUserAgent(My App/1.0)") + } + } }