API URL must not be null.
This commit is contained in:
parent
e17758f71b
commit
f9594e9dc3
3 changed files with 59 additions and 67 deletions
|
@ -35,7 +35,7 @@ import kotlinx.serialization.json.Json
|
||||||
import net.thauvin.erik.semver.Version
|
import net.thauvin.erik.semver.Version
|
||||||
import okhttp3.FormBody
|
import okhttp3.FormBody
|
||||||
import okhttp3.HttpUrl
|
import okhttp3.HttpUrl
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.logging.HttpLoggingInterceptor
|
import okhttp3.logging.HttpLoggingInterceptor
|
||||||
|
@ -45,7 +45,7 @@ import java.time.OffsetDateTime
|
||||||
import java.time.ZoneId
|
import java.time.ZoneId
|
||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
import java.time.temporal.ChronoUnit
|
import java.time.temporal.ChronoUnit
|
||||||
import java.util.*
|
import java.util.Date
|
||||||
import java.util.logging.Level
|
import java.util.logging.Level
|
||||||
import java.util.logging.Logger
|
import java.util.logging.Logger
|
||||||
|
|
||||||
|
@ -206,8 +206,8 @@ open class Akismet(apiKey: String) {
|
||||||
init {
|
init {
|
||||||
require(
|
require(
|
||||||
(apiKey.isNotBlank() &&
|
(apiKey.isNotBlank() &&
|
||||||
apiKey.length == 12 &&
|
apiKey.length == 12 &&
|
||||||
apiKey.matches(Regex("[A-Za-z0-9\\-]+")))
|
apiKey.matches(Regex("[A-Za-z0-9\\-]+")))
|
||||||
) {
|
) {
|
||||||
"An Akismet API key must be specified."
|
"An Akismet API key must be specified."
|
||||||
}
|
}
|
||||||
|
@ -325,41 +325,37 @@ open class Akismet(apiKey: String) {
|
||||||
* @param trueOnError Set to return `true` on error (IO, empty response, etc.)
|
* @param trueOnError Set to return `true` on error (IO, empty response, etc.)
|
||||||
*/
|
*/
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun executeMethod(apiUrl: HttpUrl?, formBody: FormBody, trueOnError: Boolean = false): Boolean {
|
fun executeMethod(apiUrl: HttpUrl, formBody: FormBody, trueOnError: Boolean = false): Boolean {
|
||||||
reset()
|
reset()
|
||||||
if (apiUrl != null) {
|
val request = if (formBody.size == 0) {
|
||||||
val request = if (formBody.size == 0) {
|
Request.Builder().url(apiUrl).header("User-Agent", buildUserAgent()).build()
|
||||||
Request.Builder().url(apiUrl).header("User-Agent", buildUserAgent()).build()
|
|
||||||
} else {
|
|
||||||
Request.Builder().url(apiUrl).post(formBody).header("User-Agent", buildUserAgent()).build()
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
val result = client.newCall(request).execute()
|
|
||||||
httpStatusCode = result.code
|
|
||||||
proTip = result.header("x-akismet-pro-tip", "").toString().trim()
|
|
||||||
isDiscard = (proTip == "discard")
|
|
||||||
debugHelp = result.header("x-akismet-debug-help", "").toString().trim()
|
|
||||||
val body = result.body?.string()
|
|
||||||
if (body != null) {
|
|
||||||
response = body.trim()
|
|
||||||
if (response == "valid" || response == "true" || response.startsWith("Thanks")) {
|
|
||||||
return true
|
|
||||||
} else if (response != "false" && response != "invalid") {
|
|
||||||
errorMessage = "Unexpected response: " + if (body.isBlank()) "<blank>" else body
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
val message = "No response body was received from Akismet."
|
|
||||||
errorMessage = if (debugHelp.isNotBlank()) {
|
|
||||||
"$message: $debugHelp"
|
|
||||||
} else {
|
|
||||||
message
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: IOException) {
|
|
||||||
errorMessage = "An IO error occurred while communicating with the Akismet service."
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
errorMessage = "Invalid API end point URL."
|
Request.Builder().url(apiUrl).post(formBody).header("User-Agent", buildUserAgent()).build()
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
val result = client.newCall(request).execute()
|
||||||
|
httpStatusCode = result.code
|
||||||
|
proTip = result.header("x-akismet-pro-tip", "").toString().trim()
|
||||||
|
isDiscard = (proTip == "discard")
|
||||||
|
debugHelp = result.header("x-akismet-debug-help", "").toString().trim()
|
||||||
|
val body = result.body?.string()
|
||||||
|
if (body != null) {
|
||||||
|
response = body.trim()
|
||||||
|
if (response == "valid" || response == "true" || response.startsWith("Thanks")) {
|
||||||
|
return true
|
||||||
|
} else if (response != "false" && response != "invalid") {
|
||||||
|
errorMessage = "Unexpected response: " + if (body.isBlank()) "<blank>" else body
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val message = "No response body was received from Akismet."
|
||||||
|
errorMessage = if (debugHelp.isNotBlank()) {
|
||||||
|
"$message: $debugHelp"
|
||||||
|
} else {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: IOException) {
|
||||||
|
errorMessage = "An IO error occurred while communicating with the Akismet service: ${e.message}"
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errorMessage.isNotEmpty()) {
|
if (errorMessage.isNotEmpty()) {
|
||||||
|
@ -384,11 +380,11 @@ open class Akismet(apiKey: String) {
|
||||||
response = ""
|
response = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun String.toApiUrl(): HttpUrl? {
|
private fun String.toApiUrl(): HttpUrl {
|
||||||
return if (this == verifyMethod) {
|
return if (this == verifyMethod) {
|
||||||
String.format(apiEndPoint, "", this).toHttpUrlOrNull()
|
String.format(apiEndPoint, "", this).toHttpUrl()
|
||||||
} else {
|
} else {
|
||||||
String.format(apiEndPoint, "$apiKey.", this).toHttpUrlOrNull()
|
String.format(apiEndPoint, "$apiKey.", this).toHttpUrl()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,9 +36,6 @@ import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.encodeToString
|
import kotlinx.serialization.encodeToString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import javax.servlet.http.HttpServletRequest
|
import javax.servlet.http.HttpServletRequest
|
||||||
import kotlin.collections.Map
|
|
||||||
import kotlin.collections.emptyMap
|
|
||||||
import kotlin.collections.iterator
|
|
||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
|
|
||||||
private fun String?.ifNull() = this ?: ""
|
private fun String?.ifNull() = this ?: ""
|
||||||
|
@ -241,8 +238,8 @@ open class AkismetComment(val userIp: String, val userAgent: String) {
|
||||||
* @see [serverEnv]
|
* @see [serverEnv]
|
||||||
*/
|
*/
|
||||||
constructor(request: HttpServletRequest) : this(
|
constructor(request: HttpServletRequest) : this(
|
||||||
request.remoteAddr,
|
request.remoteAddr,
|
||||||
request.getHeader("User-Agent").ifNull()
|
request.getHeader("User-Agent").ifNull()
|
||||||
) {
|
) {
|
||||||
referrer = request.getHeader("referer").ifNull()
|
referrer = request.getHeader("referer").ifNull()
|
||||||
serverEnv = buildServerEnv(request)
|
serverEnv = buildServerEnv(request)
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
package net.thauvin.erik.akismet
|
package net.thauvin.erik.akismet
|
||||||
|
|
||||||
import okhttp3.FormBody
|
import okhttp3.FormBody
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import org.mockito.Mockito
|
import org.mockito.Mockito
|
||||||
import org.mockito.Mockito.`when`
|
import org.mockito.Mockito.`when`
|
||||||
import org.testng.Assert.assertEquals
|
import org.testng.Assert.assertEquals
|
||||||
|
@ -82,8 +82,8 @@ class AkismetTest {
|
||||||
private val referer = "http://www.google.com"
|
private val referer = "http://www.google.com"
|
||||||
private val date = Date()
|
private val date = Date()
|
||||||
private val comment = AkismetComment(
|
private val comment = AkismetComment(
|
||||||
userIp = "127.0.0.1",
|
userIp = "127.0.0.1",
|
||||||
userAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
|
userAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
|
||||||
)
|
)
|
||||||
private val akismet = Akismet(apiKey, blog)
|
private val akismet = Akismet(apiKey, blog)
|
||||||
private val mockComment: AkismetComment = AkismetComment(request = getMockRequest())
|
private val mockComment: AkismetComment = AkismetComment(request = getMockRequest())
|
||||||
|
@ -255,9 +255,9 @@ class AkismetTest {
|
||||||
fun emptyResponseTest() {
|
fun emptyResponseTest() {
|
||||||
with(akismet) {
|
with(akismet) {
|
||||||
assertTrue(
|
assertTrue(
|
||||||
executeMethod(
|
executeMethod(
|
||||||
"https://postman-echo.com/status/200".toHttpUrlOrNull(), emptyFormBody, true
|
"https://postman-echo.com/status/200".toHttpUrl(), emptyFormBody, true
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
var expected = "{\"status\":200}"
|
var expected = "{\"status\":200}"
|
||||||
assertEquals(response, expected, "response: $expected")
|
assertEquals(response, expected, "response: $expected")
|
||||||
|
@ -267,9 +267,9 @@ class AkismetTest {
|
||||||
assertTrue(httpStatusCode == 0 && errorMessage.isEmpty(), "reset")
|
assertTrue(httpStatusCode == 0 && errorMessage.isEmpty(), "reset")
|
||||||
|
|
||||||
assertTrue(
|
assertTrue(
|
||||||
executeMethod(
|
executeMethod(
|
||||||
"https://erik.thauvin.net/blank.html".toHttpUrlOrNull(), emptyFormBody, true
|
"https://erik.thauvin.net/blank.html".toHttpUrl(), emptyFormBody, true
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
expected = ""
|
expected = ""
|
||||||
assertEquals(response, expected, "response: $expected")
|
assertEquals(response, expected, "response: $expected")
|
||||||
|
@ -281,10 +281,10 @@ class AkismetTest {
|
||||||
fun proTipResponseTest() {
|
fun proTipResponseTest() {
|
||||||
with(akismet) {
|
with(akismet) {
|
||||||
assertFalse(
|
assertFalse(
|
||||||
executeMethod(
|
executeMethod(
|
||||||
"https://postman-echo.com/response-headers?x-akismet-pro-tip=discard".toHttpUrlOrNull(),
|
"https://postman-echo.com/response-headers?x-akismet-pro-tip=discard".toHttpUrl(),
|
||||||
emptyFormBody
|
emptyFormBody
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
assertEquals(proTip, "discard")
|
assertEquals(proTip, "discard")
|
||||||
assertTrue(isDiscard, "isDiscard")
|
assertTrue(isDiscard, "isDiscard")
|
||||||
|
@ -317,8 +317,8 @@ class AkismetTest {
|
||||||
fun executeMethodTest() {
|
fun executeMethodTest() {
|
||||||
with(akismet) {
|
with(akismet) {
|
||||||
executeMethod(
|
executeMethod(
|
||||||
"https://$apiKey.rest.akismet.com/1.1/comment-check".toHttpUrlOrNull(),
|
"https://$apiKey.rest.akismet.com/1.1/comment-check".toHttpUrl(),
|
||||||
FormBody.Builder().apply { add("is_test", "1") }.build()
|
FormBody.Builder().apply { add("is_test", "1") }.build()
|
||||||
)
|
)
|
||||||
assertTrue(debugHelp.isNotEmpty(), "debugHelp not empty")
|
assertTrue(debugHelp.isNotEmpty(), "debugHelp not empty")
|
||||||
|
|
||||||
|
@ -327,15 +327,14 @@ class AkismetTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(expectedExceptions = [IllegalArgumentException::class])
|
||||||
fun invalidApiTest() {
|
fun invalidApiTest() {
|
||||||
akismet.executeMethod("https://.com".toHttpUrlOrNull(), emptyFormBody)
|
akismet.executeMethod("https://.com".toHttpUrl(), emptyFormBody)
|
||||||
assertTrue(akismet.errorMessage.startsWith("Invalid API"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun ioErrorTest() {
|
fun ioErrorTest() {
|
||||||
akismet.executeMethod("https://www.doesnotexists.com".toHttpUrlOrNull(), emptyFormBody)
|
akismet.executeMethod("https://www.foobarxyz.com".toHttpUrl(), emptyFormBody)
|
||||||
assertTrue(akismet.errorMessage.contains("IO error"))
|
assertTrue(akismet.errorMessage.contains("IO error"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,8 +374,8 @@ class AkismetTest {
|
||||||
|
|
||||||
akismet.appUserAgent = "My App/1.0"
|
akismet.appUserAgent = "My App/1.0"
|
||||||
assertEquals(
|
assertEquals(
|
||||||
akismet.buildUserAgent(), "${akismet.appUserAgent} | $libAgent",
|
akismet.buildUserAgent(), "${akismet.appUserAgent} | $libAgent",
|
||||||
"my app"
|
"my app"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,7 +397,7 @@ class AkismetTest {
|
||||||
`when`(getHeader("User-Agent")).thenReturn(comment.userAgent)
|
`when`(getHeader("User-Agent")).thenReturn(comment.userAgent)
|
||||||
`when`(getHeader("Accept-Encoding")).thenReturn("gzip")
|
`when`(getHeader("Accept-Encoding")).thenReturn("gzip")
|
||||||
`when`(headerNames).thenReturn(
|
`when`(headerNames).thenReturn(
|
||||||
Collections.enumeration(listOf("User-Agent", "referer", "Cookie", "Accept-Encoding", "Null"))
|
Collections.enumeration(listOf("User-Agent", "referer", "Cookie", "Accept-Encoding", "Null"))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return request
|
return request
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue