Initial commit.
This commit is contained in:
commit
271568e674
20 changed files with 1426 additions and 0 deletions
521
src/main/kotlin/net/thauvin/erik/akismet/Akismet.kt
Normal file
521
src/main/kotlin/net/thauvin/erik/akismet/Akismet.kt
Normal file
|
@ -0,0 +1,521 @@
|
|||
/*
|
||||
* Akismet.kt
|
||||
*
|
||||
* Copyright (c) 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.akismet
|
||||
|
||||
import net.thauvin.erik.semver.Version
|
||||
import okhttp3.FormBody
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import java.io.IOException
|
||||
import java.util.logging.Level
|
||||
import java.util.logging.Logger
|
||||
import javax.servlet.http.HttpServletRequest
|
||||
|
||||
/**
|
||||
* Akismet Kotlin/Java Client Library
|
||||
*/
|
||||
@Version(properties = "version.properties", type = "kt")
|
||||
open class Akismet(apiKey: String, blog: String) {
|
||||
@Suppress("unused")
|
||||
companion object {
|
||||
/** A blog comment. */
|
||||
const val COMMENT_TYPE_COMMENT = "comment"
|
||||
/** A top-level forum post. */
|
||||
const val COMMENT_TYPE_FORUM_POST = "forum-post"
|
||||
/** A reply to a top-level forum post. */
|
||||
const val COMMENT_TYPE_REPLY = "reply"
|
||||
/** A blog post. */
|
||||
const val COMMENT_TYPE_BLOG_POST = "blog-post"
|
||||
/** A contact form or feedback form submission. */
|
||||
const val COMMENT_TYPE_CONTACT_FORM = "contact-form"
|
||||
/** A new user account. */
|
||||
const val COMMENT_TYPE_SIGNUP = "signup"
|
||||
/** A message sent between just a few users. */
|
||||
const val COMMENT_TYPE_MESSAGE = "message"
|
||||
/** Administrator role */
|
||||
const val ADMIN_ROLE = "administrator"
|
||||
}
|
||||
|
||||
private val apiEndPoint = "https://%s.akismet.com/1.1/%s"
|
||||
private val libUserAgent = "${GeneratedVersion.PROJECT}/${GeneratedVersion.VERSION}"
|
||||
private val verifyMethod = "verify-key"
|
||||
private var apiKey: String
|
||||
private var blog: String
|
||||
private var client: OkHttpClient
|
||||
|
||||
var isValidKey: Boolean = false
|
||||
private set
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
var proTip: String = ""
|
||||
private set
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
var error: String = ""
|
||||
private set
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
var degugHelp: String = ""
|
||||
private set
|
||||
|
||||
val logger: Logger by lazy { Logger.getLogger(Akismet::class.java.simpleName) }
|
||||
|
||||
init {
|
||||
require(!apiKey.isBlank() || apiKey.length != 12) { "An Akismet API key must be specified." }
|
||||
require(!blog.isBlank()) { "A Blog URL must be specified." }
|
||||
|
||||
this.apiKey = apiKey
|
||||
this.blog = blog
|
||||
|
||||
if (logger.isLoggable(Level.FINE)) {
|
||||
val logging = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger {
|
||||
override fun log(message: String) {
|
||||
logger.log(Level.FINE, message)
|
||||
}
|
||||
})
|
||||
logging.level = HttpLoggingInterceptor.Level.BODY
|
||||
client = OkHttpClient.Builder().addInterceptor(logging).build()
|
||||
} else {
|
||||
client = OkHttpClient()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Key Verification
|
||||
*
|
||||
* @see <a href="https://akismet.com/development/api/#verify-key">Akismet API</a>
|
||||
*/
|
||||
fun verifyKey(): Boolean {
|
||||
val params = HashMap<String, String>()
|
||||
params["key"] = apiKey
|
||||
params["blog"] = blog
|
||||
isValidKey = executeMethod(verifyMethod, FormBody.Builder().build())
|
||||
return isValidKey
|
||||
}
|
||||
|
||||
/**
|
||||
* Comment Check using [HttpServletRequest][request] content.
|
||||
*
|
||||
* @see <a href="https://akismet.com/development/api/#comment-check">Akismet API</a>
|
||||
*/
|
||||
@JvmOverloads
|
||||
fun checkComment(
|
||||
request: HttpServletRequest,
|
||||
permalink: String = "",
|
||||
type: String = "",
|
||||
author: String = "",
|
||||
authorEmail: String = "",
|
||||
authorUrl: String = "",
|
||||
content: String = "",
|
||||
dateGmt: String = "",
|
||||
postModifiedGmt: String = "",
|
||||
blogLang: String = "",
|
||||
blogCharset: String = "",
|
||||
userRole: String = "",
|
||||
isTest: Boolean = false,
|
||||
recheckReason: String = "",
|
||||
other: Map<String, String> = emptyMap()
|
||||
): Boolean {
|
||||
return checkComment(
|
||||
userIp = request.remoteAddr,
|
||||
userAgent = request.getHeader("User-Agent"),
|
||||
referrer = request.getHeader("Referer"),
|
||||
permalink = permalink,
|
||||
type = type,
|
||||
author = author,
|
||||
authorEmail = authorEmail,
|
||||
authorUrl = authorUrl,
|
||||
content = content,
|
||||
dateGmt = dateGmt,
|
||||
postModifiedGmt = postModifiedGmt,
|
||||
blogLang = blogLang,
|
||||
blogCharset = blogCharset,
|
||||
userRole = userRole,
|
||||
isTest = isTest,
|
||||
recheckReason = recheckReason,
|
||||
other = buildPhpVars(request, other))
|
||||
}
|
||||
|
||||
/**
|
||||
* Comment Check
|
||||
*
|
||||
* @see <a href="https://akismet.com/development/api/#comment-check">Akismet API</a>
|
||||
*/
|
||||
@JvmOverloads
|
||||
fun checkComment(
|
||||
userIp: String,
|
||||
userAgent: String,
|
||||
referrer: String = "",
|
||||
permalink: String = "",
|
||||
type: String = "",
|
||||
author: String = "",
|
||||
authorEmail: String = "",
|
||||
authorUrl: String = "",
|
||||
content: String = "",
|
||||
dateGmt: String = "",
|
||||
postModifiedGmt: String = "",
|
||||
blogLang: String = "",
|
||||
blogCharset: String = "",
|
||||
userRole: String = "",
|
||||
isTest: Boolean = false,
|
||||
recheckReason: String = "",
|
||||
other: Map<String, String> = emptyMap()
|
||||
): Boolean {
|
||||
|
||||
require(!(userIp.isBlank() && userAgent.isBlank())) { "userIp and/or userAgent are required." }
|
||||
|
||||
return executeMethod(
|
||||
"comment-check",
|
||||
buildFormBody(
|
||||
userIp = userIp,
|
||||
userAgent = userAgent,
|
||||
referrer = referrer,
|
||||
permalink = permalink,
|
||||
type = type,
|
||||
author = author,
|
||||
authorEmail = authorEmail,
|
||||
authorUrl = authorUrl,
|
||||
content = content,
|
||||
dateGmt = dateGmt,
|
||||
postModifiedGmt = postModifiedGmt,
|
||||
blogLang = blogLang,
|
||||
blogCharset = blogCharset,
|
||||
userRole = userRole,
|
||||
isTest = isTest,
|
||||
recheckReason = recheckReason,
|
||||
other = other))
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit Spam
|
||||
*
|
||||
* @see <a href="https://akismet.com/development/api/#submit-spam">Akismet API</a>
|
||||
*/
|
||||
@JvmOverloads
|
||||
fun submitSpam(
|
||||
request: HttpServletRequest,
|
||||
permalink: String = "",
|
||||
type: String = "",
|
||||
author: String = "",
|
||||
authorEmail: String = "",
|
||||
authorUrl: String = "",
|
||||
content: String = "",
|
||||
dateGmt: String = "",
|
||||
postModifiedGmt: String = "",
|
||||
blogLang: String = "",
|
||||
blogCharset: String = "",
|
||||
userRole: String = "",
|
||||
isTest: Boolean = false,
|
||||
recheckReason: String = "",
|
||||
other: Map<String, String> = emptyMap()
|
||||
): Boolean {
|
||||
return submitSpam(
|
||||
userIp = request.remoteAddr,
|
||||
userAgent = request.getHeader("User-Agent"),
|
||||
referrer = request.getHeader("Referer"),
|
||||
permalink = permalink,
|
||||
type = type,
|
||||
author = author,
|
||||
authorEmail = authorEmail,
|
||||
authorUrl = authorUrl,
|
||||
content = content,
|
||||
dateGmt = dateGmt,
|
||||
postModifiedGmt = postModifiedGmt,
|
||||
blogLang = blogLang,
|
||||
blogCharset = blogCharset,
|
||||
userRole = userRole,
|
||||
isTest = isTest,
|
||||
recheckReason = recheckReason,
|
||||
other = buildPhpVars(request, other))
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit Spam (missed spam)
|
||||
*
|
||||
* @see <a href="https://akismet.com/development/api/#submit-spam">Akismet API</a>
|
||||
*/
|
||||
@JvmOverloads
|
||||
fun submitSpam(
|
||||
userIp: String,
|
||||
userAgent: String,
|
||||
referrer: String = "",
|
||||
permalink: String = "",
|
||||
type: String = "",
|
||||
author: String = "",
|
||||
authorEmail: String = "",
|
||||
authorUrl: String = "",
|
||||
content: String = "",
|
||||
dateGmt: String = "",
|
||||
postModifiedGmt: String = "",
|
||||
blogLang: String = "",
|
||||
blogCharset: String = "",
|
||||
userRole: String = "",
|
||||
isTest: Boolean = false,
|
||||
recheckReason: String = "",
|
||||
other: Map<String, String> = emptyMap()
|
||||
): Boolean {
|
||||
return executeMethod(
|
||||
"submit-spam",
|
||||
buildFormBody(
|
||||
userIp = userIp,
|
||||
userAgent = userAgent,
|
||||
referrer = referrer,
|
||||
permalink = permalink,
|
||||
type = type,
|
||||
author = author,
|
||||
authorEmail = authorEmail,
|
||||
authorUrl = authorUrl,
|
||||
content = content,
|
||||
dateGmt = dateGmt,
|
||||
postModifiedGmt = postModifiedGmt,
|
||||
blogLang = blogLang,
|
||||
blogCharset = blogCharset,
|
||||
userRole = userRole,
|
||||
isTest = isTest,
|
||||
recheckReason = recheckReason,
|
||||
other = other))
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit Ham (false positives)
|
||||
*
|
||||
* @see <a href="https://akismet.com/development/api/#submit-ham">Akismet API</a>
|
||||
*/
|
||||
@JvmOverloads
|
||||
fun submitHam(
|
||||
request: HttpServletRequest,
|
||||
permalink: String = "",
|
||||
type: String = "",
|
||||
author: String = "",
|
||||
authorEmail: String = "",
|
||||
authorUrl: String = "",
|
||||
content: String = "",
|
||||
dateGmt: String = "",
|
||||
postModifiedGmt: String = "",
|
||||
blogLang: String = "",
|
||||
blogCharset: String = "",
|
||||
userRole: String = "",
|
||||
isTest: Boolean = false,
|
||||
recheckReason: String = "",
|
||||
other: Map<String, String> = emptyMap()
|
||||
): Boolean {
|
||||
return submitHam(
|
||||
userIp = request.remoteAddr,
|
||||
userAgent = request.getHeader("User-Agent"),
|
||||
referrer = request.getHeader("Referer"),
|
||||
permalink = permalink,
|
||||
type = type,
|
||||
author = author,
|
||||
authorEmail = authorEmail,
|
||||
authorUrl = authorUrl,
|
||||
content = content,
|
||||
dateGmt = dateGmt,
|
||||
postModifiedGmt = postModifiedGmt,
|
||||
blogLang = blogLang,
|
||||
blogCharset = blogCharset,
|
||||
userRole = userRole,
|
||||
isTest = isTest,
|
||||
recheckReason = recheckReason,
|
||||
other = buildPhpVars(request, other))
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit Ham
|
||||
*
|
||||
* @see <a href="https://akismet.com/development/api/#submit-ham">Akismet API</a>
|
||||
*/
|
||||
@JvmOverloads
|
||||
fun submitHam(
|
||||
userIp: String,
|
||||
userAgent: String,
|
||||
referrer: String = "",
|
||||
permalink: String = "",
|
||||
type: String = "",
|
||||
author: String = "",
|
||||
authorEmail: String = "",
|
||||
authorUrl: String = "",
|
||||
content: String = "",
|
||||
dateGmt: String = "",
|
||||
postModifiedGmt: String = "",
|
||||
blogLang: String = "",
|
||||
blogCharset: String = "",
|
||||
userRole: String = "",
|
||||
isTest: Boolean = false,
|
||||
recheckReason: String = "",
|
||||
other: Map<String, String> = emptyMap()
|
||||
): Boolean {
|
||||
return executeMethod(
|
||||
"submit-ham",
|
||||
buildFormBody(
|
||||
userIp = userIp,
|
||||
userAgent = userAgent,
|
||||
referrer = referrer,
|
||||
permalink = permalink,
|
||||
type = type,
|
||||
author = author,
|
||||
authorEmail = authorEmail,
|
||||
authorUrl = authorUrl,
|
||||
content = content,
|
||||
dateGmt = dateGmt,
|
||||
postModifiedGmt = postModifiedGmt,
|
||||
blogLang = blogLang,
|
||||
blogCharset = blogCharset,
|
||||
userRole = userRole,
|
||||
isTest = isTest,
|
||||
recheckReason = recheckReason,
|
||||
other = other))
|
||||
}
|
||||
|
||||
private fun executeMethod(method: String, formBody: FormBody): Boolean {
|
||||
val apiUrl = buildApiUrl(method).toHttpUrlOrNull()
|
||||
if (apiUrl != null) {
|
||||
val request = Request.Builder().url(apiUrl).post(formBody).header("User-Agent", libUserAgent).build()
|
||||
try {
|
||||
val result = client.newCall(request).execute()
|
||||
proTip = result.header("x-akismet-pro-tip", "").toString()
|
||||
error = result.header("x-akismet-error", "").toString()
|
||||
degugHelp = result.header("X-akismet-debug-help", "").toString()
|
||||
val body = result.body?.string()
|
||||
if (body != null) {
|
||||
val response = body.trim()
|
||||
if (response.equals("valid", true) ||
|
||||
response.equals("true", true) ||
|
||||
response.startsWith("Thanks", true)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
logger.log(Level.SEVERE, "An IO error occurred while communicating with the Akismet service.", e)
|
||||
}
|
||||
} else {
|
||||
logger.severe("Invalid API end point URL: $method. The API Key is likely invalid.")
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun buildApiUrl(method: String): String {
|
||||
if (method == verifyMethod) {
|
||||
return String.format(apiEndPoint, "rest", method)
|
||||
}
|
||||
return String.format(apiEndPoint, apiKey, method)
|
||||
}
|
||||
|
||||
private fun buildPhpVars(request: HttpServletRequest, other: Map<String, String>): HashMap<String, String> {
|
||||
val params = HashMap<String, String>()
|
||||
params["REMOTE_ADDR"] = request.remoteAddr
|
||||
params["REQUEST_URI"] = request.requestURI
|
||||
|
||||
val names = request.headerNames
|
||||
while (names.hasMoreElements()) {
|
||||
val name = names.nextElement()
|
||||
if (!name.equals("cookie", true)) {
|
||||
params["HTTP_${name.toUpperCase()}"] = request.getHeader(name)
|
||||
}
|
||||
}
|
||||
|
||||
if (other.isEmpty()) {
|
||||
params.putAll(other)
|
||||
}
|
||||
|
||||
return params
|
||||
}
|
||||
|
||||
private fun buildFormBody(
|
||||
userIp: String,
|
||||
userAgent: String,
|
||||
referrer: String,
|
||||
permalink: String,
|
||||
type: String,
|
||||
author: String,
|
||||
authorEmail: String,
|
||||
authorUrl: String,
|
||||
content: String,
|
||||
dateGmt: String,
|
||||
postModifiedGmt: String,
|
||||
blogLang: String,
|
||||
blogCharset: String,
|
||||
userRole: String,
|
||||
isTest: Boolean,
|
||||
recheckReason: String,
|
||||
other: Map<String, String>
|
||||
): FormBody {
|
||||
return FormBody.Builder().apply {
|
||||
add("blog", blog)
|
||||
add("user_ip", userIp)
|
||||
add("user_agent", userAgent)
|
||||
|
||||
if (referrer.isNotBlank()) {
|
||||
add("referrer", referrer)
|
||||
}
|
||||
if (permalink.isNotBlank()) {
|
||||
add("permalink", permalink)
|
||||
}
|
||||
if (type.isNotBlank()) {
|
||||
add("comment_type", type)
|
||||
}
|
||||
if (author.isNotBlank()) {
|
||||
add("comment_author", author)
|
||||
}
|
||||
if (authorEmail.isNotBlank()) {
|
||||
add("comment_author_email", authorEmail)
|
||||
}
|
||||
if (authorUrl.isNotBlank()) {
|
||||
add("comment_author_url", authorUrl)
|
||||
}
|
||||
if (content.isNotBlank()) {
|
||||
add("comment_content", content)
|
||||
}
|
||||
if (dateGmt.isNotBlank()) {
|
||||
add("comment_date_gmt", dateGmt)
|
||||
}
|
||||
if (postModifiedGmt.isNotBlank()) {
|
||||
add("comment_post_modified_gmt", postModifiedGmt)
|
||||
}
|
||||
if (blogLang.isNotBlank()) {
|
||||
add("blog_lang", blogLang)
|
||||
}
|
||||
if (blogCharset.isNotBlank()) {
|
||||
add("blog_charset", blogCharset)
|
||||
}
|
||||
if (userRole.isNotBlank()) {
|
||||
add("user_role", userRole)
|
||||
}
|
||||
if (isTest) {
|
||||
add("is_test", "true")
|
||||
}
|
||||
if (recheckReason.isNotBlank()) {
|
||||
add("recheck_reason", recheckReason)
|
||||
}
|
||||
|
||||
other.forEach { (k, v) -> add(k, v) }
|
||||
}.build()
|
||||
}
|
||||
}
|
156
src/test/kotlin/net/thauvin/erik/akismet/AkismetTest.kt
Normal file
156
src/test/kotlin/net/thauvin/erik/akismet/AkismetTest.kt
Normal file
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* AkismetTest.kt
|
||||
*
|
||||
* Copyright (c) 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.akismet
|
||||
|
||||
import org.mockito.Mockito
|
||||
import org.testng.Assert.assertFalse
|
||||
import org.testng.Assert.assertTrue
|
||||
import org.testng.Assert.expectThrows
|
||||
import org.testng.annotations.BeforeClass
|
||||
import org.testng.annotations.Test
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.util.Collections
|
||||
import java.util.Properties
|
||||
import java.util.logging.ConsoleHandler
|
||||
import java.util.logging.Level
|
||||
import javax.servlet.http.HttpServletRequest
|
||||
|
||||
/**
|
||||
* The <code>AkismetTest</code> class.
|
||||
*
|
||||
* @author <a href="https://erik.thauvin.net/" target="_blank">Erik C. Thauvin</a>
|
||||
* @created 2019-09-17
|
||||
* @since 1.0
|
||||
*/
|
||||
|
||||
fun getApiKey(): String {
|
||||
var apiKey = System.getenv("AKISMET_API_KEY") ?: ""
|
||||
if (apiKey.isBlank()) {
|
||||
val localProps = File("local.properties")
|
||||
if (localProps.exists())
|
||||
localProps.apply {
|
||||
if (exists()) {
|
||||
FileInputStream(this).use { fis ->
|
||||
Properties().apply {
|
||||
load(fis)
|
||||
apiKey = getProperty("AKISMET_API_KEY", "")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return apiKey
|
||||
}
|
||||
|
||||
class AkismetTest {
|
||||
private val userIp = "127.0.0.1"
|
||||
private val userAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
|
||||
private val referrer = "http://www.google.com"
|
||||
private val permalink = "http://yourblogdomainname.com/blog/post=1"
|
||||
private val type = "comment"
|
||||
private val author = "admin"
|
||||
private val authorEmail = "test@test.com"
|
||||
private val authorUrl = "http://www.CheckOutMyCoolSite.com"
|
||||
private val content = "It means a lot that you would take the time to review our software. Thanks again."
|
||||
private val akismet = Akismet(getApiKey(), "http://erik.thauvin.net/blog/")
|
||||
private val request = Mockito.mock(HttpServletRequest::class.java)
|
||||
|
||||
@BeforeClass
|
||||
fun beforeClass() {
|
||||
with(akismet.logger) {
|
||||
addHandler(ConsoleHandler().apply { level = Level.FINE })
|
||||
level = Level.FINE
|
||||
}
|
||||
|
||||
Mockito.`when`(request.remoteAddr).thenReturn(userIp)
|
||||
Mockito.`when`(request.requestURI).thenReturn("/blog/post=1")
|
||||
Mockito.`when`(request.getHeader("User-Agent")).thenReturn(userAgent)
|
||||
Mockito.`when`(request.getHeader("Referer")).thenReturn(referrer)
|
||||
Mockito.`when`(request.getHeader("Cookie")).thenReturn("name=value; name2=value2; name3=value3")
|
||||
Mockito.`when`(request.getHeader("Accept-Encoding")).thenReturn("gzip")
|
||||
Mockito.`when`(request.headerNames)
|
||||
.thenReturn(Collections.enumeration(listOf("User-Agent", "Referer", "Cookie", "Accept-Encoding")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun constructorTest() {
|
||||
expectThrows(IllegalArgumentException::class.java) {
|
||||
Akismet("123456789012", "http://www.foo.com/")
|
||||
Akismet("", "http://www.foo.com/")
|
||||
Akismet("123456789012", "")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun verifyKeyTest() {
|
||||
assertFalse(akismet.isValidKey, "isValidKey -> false")
|
||||
assertTrue(akismet.verifyKey(), "verify_key")
|
||||
assertTrue(akismet.isValidKey, "isValidKey -> true")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun checkCommentTest() {
|
||||
// assertFalse(akismet.checkComment(userIp = userIp,
|
||||
// userAgent = userAgent,
|
||||
// referrer = referrer,
|
||||
// permalink = permalink,
|
||||
// type = type,
|
||||
// author = author,
|
||||
// authorEmail = authorEmail,
|
||||
// authorUrl = authorUrl,
|
||||
// content = content,
|
||||
// userRole = Akismet.ADMIN_ROLE,
|
||||
// isTest = true), "check_comment -> false")
|
||||
//
|
||||
// assertTrue(akismet.checkComment(userIp = userIp,
|
||||
// userAgent = userAgent,
|
||||
// referrer = referrer,
|
||||
// permalink = permalink,
|
||||
// type = type,
|
||||
// author = author,
|
||||
// authorEmail = authorEmail,
|
||||
// authorUrl = authorUrl,
|
||||
// content = content,
|
||||
// isTest = true), "check_comment -> true")
|
||||
|
||||
assertTrue(akismet.checkComment(request,
|
||||
permalink = permalink,
|
||||
type = type,
|
||||
author = author,
|
||||
authorEmail = authorEmail,
|
||||
authorUrl = authorUrl,
|
||||
content = content,
|
||||
isTest = true), "check_comment(request) -> true")
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue