Split tests
This commit is contained in:
parent
9b5047e5fa
commit
a41119d195
5 changed files with 478 additions and 265 deletions
88
src/test/kotlin/net/thauvin/erik/jokeapi/ApiCallTest.kt
Normal file
88
src/test/kotlin/net/thauvin/erik/jokeapi/ApiCallTest.kt
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* ApiCallTest.kt
|
||||
*
|
||||
* Copyright (c) 2022, 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.jokeapi
|
||||
|
||||
import net.thauvin.erik.jokeapi.JokeApi.Companion.apiCall
|
||||
import net.thauvin.erik.jokeapi.JokeApi.Companion.logger
|
||||
import net.thauvin.erik.jokeapi.models.Format
|
||||
import net.thauvin.erik.jokeapi.models.Language
|
||||
import net.thauvin.erik.jokeapi.models.Parameter
|
||||
import org.json.JSONObject
|
||||
import org.junit.jupiter.api.Assertions.assertFalse
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.BeforeAll
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertAll
|
||||
import java.util.logging.ConsoleHandler
|
||||
import java.util.logging.Level
|
||||
|
||||
internal class ApiCallTest {
|
||||
@Test
|
||||
fun `Get Flags`() {
|
||||
// See https://v2.jokeapi.dev/#flags-endpoint
|
||||
val response = apiCall(endPoint = "flags")
|
||||
val json = JSONObject(response)
|
||||
assertAll("Validate JSON",
|
||||
{ assertFalse(json.getBoolean("error"), "should not be an error") },
|
||||
{ assertTrue(json.getJSONArray("flags").length() > 0, "should have flags") },
|
||||
{ assertTrue(json.getLong("timestamp") > 0, "should have a timestamp") })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Language Code`() {
|
||||
// See https://v2.jokeapi.dev/#langcode-endpoint
|
||||
val lang = apiCall(
|
||||
endPoint = "langcode", path = "french",
|
||||
params = mapOf(Parameter.FORMAT to Format.YAML.value)
|
||||
)
|
||||
assertTrue(lang.contains("code: \"fr\"")) { "should contain ${Language.FR.value}" }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Ping Response`() {
|
||||
// See https://v2.jokeapi.dev/#ping-endpoint
|
||||
val ping = apiCall(endPoint = "ping", params = mapOf(Parameter.FORMAT to Format.TXT.value))
|
||||
assertTrue(ping.startsWith("Pong!"), "should return pong")
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
@BeforeAll
|
||||
fun beforeAll() {
|
||||
with(logger) {
|
||||
addHandler(ConsoleHandler().apply { level = Level.FINE })
|
||||
level = Level.FINE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
106
src/test/kotlin/net/thauvin/erik/jokeapi/ExceptionsTest.kt
Normal file
106
src/test/kotlin/net/thauvin/erik/jokeapi/ExceptionsTest.kt
Normal file
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* ExceptionsTest.kt
|
||||
*
|
||||
* Copyright (c) 2022, 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.jokeapi
|
||||
|
||||
import net.thauvin.erik.jokeapi.JokeApi.Companion.fetchUrl
|
||||
import net.thauvin.erik.jokeapi.JokeApi.Companion.getJoke
|
||||
import net.thauvin.erik.jokeapi.JokeApi.Companion.logger
|
||||
import net.thauvin.erik.jokeapi.exceptions.HttpErrorException
|
||||
import net.thauvin.erik.jokeapi.exceptions.JokeException
|
||||
import net.thauvin.erik.jokeapi.models.Category
|
||||
import org.junit.jupiter.api.Assertions
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertFalse
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.BeforeAll
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertAll
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import org.junit.jupiter.params.ParameterizedTest
|
||||
import org.junit.jupiter.params.provider.ValueSource
|
||||
import java.util.logging.ConsoleHandler
|
||||
import java.util.logging.Level
|
||||
|
||||
internal class ExceptionsTest {
|
||||
@Test
|
||||
fun `Validate Joke Exception`() {
|
||||
val e = assertThrows<JokeException> {
|
||||
getJoke(categories = setOf(Category.CHRISTMAS), search = "foo")
|
||||
}
|
||||
logger.fine(e.debug())
|
||||
assertAll("JokeException Validation",
|
||||
{ assertEquals(106, e.code, "code should be valid") },
|
||||
{ assertTrue(e.error, "should be an error") },
|
||||
{ assertFalse(e.internalError, "should not be internal error") },
|
||||
{ assertEquals("No matching joke found", e.message, "message should match") },
|
||||
{ assertEquals(1, e.causedBy.size, "causedBy size should be 1") },
|
||||
{ assertTrue(e.causedBy[0].startsWith("No jokes"), "causedBy should start with no jokes") },
|
||||
{ assertTrue(e.additionalInfo.isNotEmpty(), "additional info should not be empty") },
|
||||
{ assertTrue(e.timestamp > 0, "timestamp should be > 0") })
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "HTTP Status Code: {0}")
|
||||
@ValueSource(ints = [400, 404, 403, 413, 414, 429, 500, 523])
|
||||
fun `Validate HTTP Error Exceptions`(input: Int) {
|
||||
val e = assertThrows<HttpErrorException> {
|
||||
fetchUrl("https://httpstat.us/$input")
|
||||
}
|
||||
assertAll("HttpErrorException Validation",
|
||||
{ assertEquals(input, e.statusCode) { "status code should be $input" } },
|
||||
{ assertTrue(e.message!!.isNotEmpty()) { "message for $input should not be empty" } },
|
||||
{ assertTrue(e.cause!!.message!!.isNotEmpty()) { "cause of $input should not be empty" } })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Fetch Invalid URL`() {
|
||||
val statusCode = 999
|
||||
val e = assertThrows<HttpErrorException> {
|
||||
fetchUrl("https://httpstat.us/$statusCode")
|
||||
}
|
||||
Assertions.assertAll("JokeException Validation",
|
||||
{ assertEquals(statusCode, e.statusCode) { "status code should be $statusCode" } },
|
||||
{ assertTrue(e.message!!.isNotEmpty(), "message should not be empty") },
|
||||
{ assertTrue(e.cause == null, "cause should be null") })
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
@BeforeAll
|
||||
fun beforeAll() {
|
||||
with(logger) {
|
||||
addHandler(ConsoleHandler().apply { level = Level.FINE })
|
||||
level = Level.FINE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
193
src/test/kotlin/net/thauvin/erik/jokeapi/GetJokeTest.kt
Normal file
193
src/test/kotlin/net/thauvin/erik/jokeapi/GetJokeTest.kt
Normal file
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* JokeApiTest.kt
|
||||
*
|
||||
* Copyright (c) 2022, 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.jokeapi
|
||||
|
||||
import net.thauvin.erik.jokeapi.JokeApi.Companion.fetchUrl
|
||||
import net.thauvin.erik.jokeapi.JokeApi.Companion.getJoke
|
||||
import net.thauvin.erik.jokeapi.JokeApi.Companion.logger
|
||||
import net.thauvin.erik.jokeapi.exceptions.HttpErrorException
|
||||
import net.thauvin.erik.jokeapi.exceptions.JokeException
|
||||
import net.thauvin.erik.jokeapi.models.Category
|
||||
import net.thauvin.erik.jokeapi.models.Flag
|
||||
import net.thauvin.erik.jokeapi.models.IdRange
|
||||
import net.thauvin.erik.jokeapi.models.Language
|
||||
import net.thauvin.erik.jokeapi.models.Type
|
||||
import org.junit.jupiter.api.Assertions.assertAll
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertFalse
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.BeforeAll
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import java.util.logging.ConsoleHandler
|
||||
import java.util.logging.Level
|
||||
|
||||
internal class GetJokeTest {
|
||||
@Test
|
||||
fun `Get Joke`() {
|
||||
val joke = getJoke()
|
||||
logger.fine(joke.toString())
|
||||
assertAll("No Param Joke",
|
||||
{ assertFalse(joke.error, "error should be false") },
|
||||
{ assertTrue(joke.joke.isNotEmpty(), "joke should not be empty") },
|
||||
{ assertTrue(joke.type == Type.TWOPART || joke.type == Type.SINGLE, "type should validate") },
|
||||
{ assertTrue(joke.id >= 0, "id should be >= 0") },
|
||||
{ assertEquals(Language.EN, joke.language, "language should be english") })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Joke without Blacklist Flags`() {
|
||||
val joke = getJoke(flags = setOf(Flag.ALL))
|
||||
assertTrue(joke.flags.isEmpty(), "flags should be empty.")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Joke without any Blacklist Flags`() {
|
||||
val allFlags = Flag.values().filter { it != Flag.ALL }.toSet()
|
||||
val joke = getJoke(flags = allFlags)
|
||||
assertTrue(joke.flags.isEmpty(), "flags should be empty.")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Joke with ID`() {
|
||||
val id = 172
|
||||
val joke = getJoke(idRange = IdRange(id))
|
||||
logger.fine(joke.toString())
|
||||
assertAll("Joke by ID",
|
||||
{ assertTrue(joke.flags.contains(Flag.NSFW) && joke.flags.contains(Flag.EXPLICIT), "nsfw & explicit") },
|
||||
{ assertEquals(172, joke.id) { "id is $id" } },
|
||||
{ assertEquals(Category.PUN, joke.category, "category should be pun") })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Joke with ID Range`() {
|
||||
val idRange = IdRange(1, 100)
|
||||
val joke = getJoke(idRange = idRange)
|
||||
logger.fine(joke.toString())
|
||||
assertTrue(joke.id >= idRange.start && joke.id <= idRange.end, "id should be in range")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Joke with invalid ID Range`() {
|
||||
val joke = getJoke(idRange = IdRange(100, 1))
|
||||
logger.fine(joke.toString())
|
||||
assertFalse(joke.error, "should not be an error")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Joke with max ID Range`() {
|
||||
val e = assertThrows<JokeException> { getJoke(idRange = IdRange(1, 30000)) }
|
||||
assertAll("Joke w/ max ID Range",
|
||||
{ assertTrue(e.error, "should be an error") },
|
||||
{ assertTrue(e.additionalInfo.contains("ID range"), "should contain ID range") })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Joke with two Categories`() {
|
||||
val joke = getJoke(categories = setOf(Category.PROGRAMMING, Category.MISC))
|
||||
logger.fine(joke.toString())
|
||||
assertTrue(joke.category == Category.PROGRAMMING || joke.category == Category.MISC) {
|
||||
"category should be ${Category.PROGRAMMING.value} or ${Category.MISC.value}"
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Joke with each Categories`() {
|
||||
Category.values().filter { it != Category.ANY }.forEach {
|
||||
val joke = getJoke(categories = setOf(it))
|
||||
logger.fine(joke.toString())
|
||||
assertEquals(it.value, joke.category.value) { "category should be ${it.value}" }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Joke with each Languages`() {
|
||||
Language.values().forEach {
|
||||
val joke = getJoke(language = it)
|
||||
assertEquals(it.value, joke.language.value) { "language should be ${it.value}" }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Joke with Newline`() {
|
||||
val joke = getJoke(
|
||||
categories = setOf(Category.DARK), type = Type.SINGLE, idRange = IdRange(178), splitNewLine = false
|
||||
)
|
||||
assertTrue(joke.joke.toString().contains("\n"), "should contain newline")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Safe Joke`() {
|
||||
val joke = getJoke(safe = true)
|
||||
logger.fine(joke.toString())
|
||||
assertAll("Safe Joke",
|
||||
{ assertTrue(joke.safe, "should be safe") },
|
||||
{ assertTrue(joke.flags.isEmpty(), "flags should be empty") })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Single Joke`() {
|
||||
val joke = getJoke(type = Type.SINGLE)
|
||||
logger.fine(joke.toString())
|
||||
assertEquals(Type.SINGLE, joke.type, "type should be single")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Two-Parts Joke`() {
|
||||
val joke = getJoke(type = Type.TWOPART)
|
||||
logger.fine(joke.toString())
|
||||
assertAll("Two-Parts Joke",
|
||||
{ assertEquals(Type.TWOPART, joke.type, "type should be two-part") },
|
||||
{ assertTrue(joke.joke.size > 1, "should have multiple lines") })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Joke using Search`() {
|
||||
val id = 265
|
||||
val joke =
|
||||
getJoke(search = "his wife", categories = setOf(Category.PROGRAMMING), idRange = IdRange(id), safe = true)
|
||||
logger.fine(joke.toString())
|
||||
assertEquals(id, joke.id) { "id should be $id" }
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
@BeforeAll
|
||||
fun beforeAll() {
|
||||
with(logger) {
|
||||
addHandler(ConsoleHandler().apply { level = Level.FINE })
|
||||
level = Level.FINE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
91
src/test/kotlin/net/thauvin/erik/jokeapi/GetRawJokeTest.kt
Normal file
91
src/test/kotlin/net/thauvin/erik/jokeapi/GetRawJokeTest.kt
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* GetRawJokeTest.kt
|
||||
*
|
||||
* Copyright (c) 2022, 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.jokeapi
|
||||
|
||||
import net.thauvin.erik.jokeapi.JokeApi.Companion.getRawJoke
|
||||
import net.thauvin.erik.jokeapi.JokeApi.Companion.logger
|
||||
import net.thauvin.erik.jokeapi.models.Format
|
||||
import org.junit.jupiter.api.Assertions.assertFalse
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.BeforeAll
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertAll
|
||||
import java.util.logging.ConsoleHandler
|
||||
import java.util.logging.Level
|
||||
|
||||
internal class GetRawJokeTest {
|
||||
@Test
|
||||
fun `Get Raw Joke with TXT`() {
|
||||
val response = getRawJoke(format = Format.TEXT)
|
||||
assertAll("Plain Text",
|
||||
{ assertTrue(response.isNotEmpty(), "should be not empty") },
|
||||
{ assertFalse(response.startsWith("Error "), "should not be an error") })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Raw Joke with invalid Amount`() {
|
||||
val response = getRawJoke(amount = 100)
|
||||
assertFalse(response.contains("\"amount\":"), "should not have amount")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Raw Joke with XML`() {
|
||||
val response = getRawJoke(format = Format.XML)
|
||||
assertTrue(
|
||||
response.startsWith("<?xml version='1.0'?>\n<data>\n <error>false</error>"), "should be xml"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Raw Joke with YAML`() {
|
||||
val response = getRawJoke(format = Format.YAML)
|
||||
assertTrue(response.startsWith("error: false"), "should be yaml")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Raw Jokes`() {
|
||||
val response = getRawJoke(amount = 2)
|
||||
assertTrue(response.contains("\"amount\": 2"), "amount should be 2")
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
@BeforeAll
|
||||
fun beforeAll() {
|
||||
with(logger) {
|
||||
addHandler(ConsoleHandler().apply { level = Level.FINE })
|
||||
level = Level.FINE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,265 +0,0 @@
|
|||
/*
|
||||
* JokeApiTest.kt
|
||||
*
|
||||
* Copyright (c) 2022, 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.jokeapi
|
||||
|
||||
import net.thauvin.erik.jokeapi.JokeApi.Companion.fetchUrl
|
||||
import net.thauvin.erik.jokeapi.JokeApi.Companion.getJoke
|
||||
import net.thauvin.erik.jokeapi.JokeApi.Companion.getRawJoke
|
||||
import net.thauvin.erik.jokeapi.JokeApi.Companion.logger
|
||||
import net.thauvin.erik.jokeapi.exceptions.HttpErrorException
|
||||
import net.thauvin.erik.jokeapi.exceptions.JokeException
|
||||
import net.thauvin.erik.jokeapi.models.Category
|
||||
import net.thauvin.erik.jokeapi.models.Flag
|
||||
import net.thauvin.erik.jokeapi.models.Format
|
||||
import net.thauvin.erik.jokeapi.models.IdRange
|
||||
import net.thauvin.erik.jokeapi.models.Language
|
||||
import net.thauvin.erik.jokeapi.models.Type
|
||||
import org.junit.jupiter.api.Assertions.assertAll
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertFalse
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.BeforeAll
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import org.junit.jupiter.params.ParameterizedTest
|
||||
import org.junit.jupiter.params.provider.ValueSource
|
||||
import java.util.logging.ConsoleHandler
|
||||
import java.util.logging.Level
|
||||
|
||||
internal class JokeApiTest {
|
||||
@Test
|
||||
fun `Get Joke`() {
|
||||
val joke = getJoke()
|
||||
logger.fine(joke.toString())
|
||||
assertAll("no param",
|
||||
{ assertFalse(joke.error) { "error should be false" } },
|
||||
{ assertTrue(joke.joke.isNotEmpty()) { "joke should not be empty" } },
|
||||
{ assertTrue(joke.type == Type.TWOPART || joke.type == Type.SINGLE) { "type should validate" } },
|
||||
{ assertTrue(joke.id >= 0) { "id should be >= 0" } },
|
||||
{ assertEquals(Language.EN, joke.language) { "language should be english" } })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Joke with all Blacklist Flags`() {
|
||||
val joke = getJoke(flags = setOf(Flag.ALL))
|
||||
assertAll("joke with all flags", { assertTrue(joke.flags.isEmpty()) { "flags should be empty." } })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Joke with no Blacklist Flags`() {
|
||||
val noFlags = Flag.values().filter { it != Flag.ALL }.toSet()
|
||||
val joke = getJoke(flags = noFlags)
|
||||
assertAll("joke with no flags", { assertTrue(joke.flags.isEmpty()) { "flags should be empty." } })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Joke with ID`() {
|
||||
val id = 172
|
||||
val joke = getJoke(idRange = IdRange(id))
|
||||
logger.fine(joke.toString())
|
||||
assertAll("joke by id",
|
||||
{ assertTrue(joke.flags.contains(Flag.NSFW) && joke.flags.contains(Flag.EXPLICIT)) { "nsfw & explicit" } },
|
||||
{ assertEquals(172, joke.id) { "id is $id" } },
|
||||
{ assertEquals(Category.PUN, joke.category) { "category should be pun" } })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Joke with ID Range`() {
|
||||
val idRange = IdRange(1, 100)
|
||||
val joke = getJoke(idRange = idRange)
|
||||
logger.fine(joke.toString())
|
||||
assertTrue(joke.id >= idRange.start && joke.id <= idRange.end) { "id should be in range" }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Joke with invalid ID Range`() {
|
||||
val joke = getJoke(idRange = IdRange(100, 1))
|
||||
logger.fine(joke.toString())
|
||||
assertFalse(joke.error) { "should not be an error" }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Joke with max ID Range`() {
|
||||
val e = assertThrows<JokeException> { getJoke(idRange = IdRange(1, 30000)) }
|
||||
assertAll("joke with max ID range",
|
||||
{ assertTrue(e.error) { "should be an error" } },
|
||||
{ assertTrue(e.additionalInfo.contains("ID range")) { "should contain ID range" } }
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Joke with each Categories`() {
|
||||
Category.values().filter { it != Category.ANY }.forEach {
|
||||
val joke = getJoke(categories = setOf(it))
|
||||
assertEquals(it.value, joke.category.value) { "category should be ${it.value}" }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Joke with each Languages`() {
|
||||
Language.values().forEach {
|
||||
val joke = getJoke(language = it)
|
||||
assertEquals(it.value, joke.language.value) { "language should be ${it.value}" }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Joke with Newline`() {
|
||||
val joke = getJoke(
|
||||
categories = setOf(Category.DARK),
|
||||
type = Type.SINGLE,
|
||||
idRange = IdRange(178),
|
||||
splitNewLine = false
|
||||
)
|
||||
assertTrue(joke.joke.toString().contains("\n")) { "should contain newline" }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Safe Joke`() {
|
||||
val joke = getJoke(safe = true)
|
||||
logger.fine(joke.toString())
|
||||
assertAll("safe joke",
|
||||
{ assertTrue(joke.safe) { "should be safe" } },
|
||||
{ assertTrue(joke.flags.isEmpty()) { "flags should be empty" } })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Single Joke`() {
|
||||
val joke = getJoke(type = Type.SINGLE)
|
||||
logger.fine(joke.toString())
|
||||
assertEquals(Type.SINGLE, joke.type) { "type should be single" }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Two-Parts Joke`() {
|
||||
val joke = getJoke(type = Type.TWOPART)
|
||||
logger.fine(joke.toString())
|
||||
assertAll("two-part joke",
|
||||
{ assertEquals(Type.TWOPART, joke.type) { "type should be two-part" } },
|
||||
{ assertTrue(joke.joke.size > 1) { "should have multiple lines" } })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Joke using Search`() {
|
||||
val id = 1
|
||||
val joke = getJoke(search = "man", categories = setOf(Category.PROGRAMMING), idRange = IdRange(id), safe = true)
|
||||
logger.fine(joke.toString())
|
||||
assertEquals(id, joke.id) { "id should be $id" }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Raw Joke with TXT`() {
|
||||
val response = getRawJoke(format = Format.TEXT)
|
||||
assertAll("plain text",
|
||||
{ assertTrue(response.isNotEmpty()) { "should be not empty" } },
|
||||
{ assertFalse(response.startsWith("Error ")) { "should not be an error" } })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Raw Joke with invalid Amount`() {
|
||||
val response = getRawJoke(amount = 100)
|
||||
assertFalse(response.contains("\"amount\":")) { "should not have amount" }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Raw Joke with XML`() {
|
||||
val response = getRawJoke(format = Format.XML)
|
||||
assertTrue(response.startsWith("<?xml version='1.0'?>\n<data>\n <error>false</error>")) { "should be xml" }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Raw Joke with YAML`() {
|
||||
val response = getRawJoke(format = Format.YAML)
|
||||
assertTrue(response.startsWith("error: false")) { "should be yaml" }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get Raw Jokes`() {
|
||||
val response = getRawJoke(amount = 2)
|
||||
assertTrue(response.contains("\"amount\": 2")) { "amount should be 2" }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Fetch Invalid URL`() {
|
||||
val statusCode = 999
|
||||
val e = assertThrows<HttpErrorException> {
|
||||
fetchUrl("https://httpstat.us/$statusCode")
|
||||
}
|
||||
assertAll("JokeException validation",
|
||||
{ assertEquals(statusCode, e.statusCode) { "status code should be $statusCode" } },
|
||||
{ assertTrue(e.message!!.isNotEmpty()) { "message should not be empty" } },
|
||||
{ assertTrue(e.cause == null) { "cause should be null" } })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Validate Joke Exception`() {
|
||||
val e = assertThrows<JokeException> {
|
||||
getJoke(categories = setOf(Category.CHRISTMAS), search = "foo")
|
||||
}
|
||||
logger.fine(e.debug())
|
||||
assertAll("JokeException validation",
|
||||
{ assertEquals(106, e.code) { "code should be valid" } },
|
||||
{ assertTrue(e.error) { "should be an error" } },
|
||||
{ assertFalse(e.internalError) { "should not be internal error" } },
|
||||
{ assertEquals("No matching joke found", e.message) { "message should match" } },
|
||||
{ assertEquals(1, e.causedBy.size) { "causedBy size should be 1" } },
|
||||
{ assertTrue(e.causedBy[0].startsWith("No jokes")) { "causedBy should start with no jokes" } },
|
||||
{ assertTrue(e.additionalInfo.isNotEmpty()) { "additional info should not be empty" } },
|
||||
{ assertTrue(e.timestamp > 0) { "timestamp should be > 0" } })
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(ints = [400, 404, 403, 413, 414, 429, 500, 523])
|
||||
fun `Validate HTTP Error Exceptions`(input: Int) {
|
||||
val e = assertThrows<HttpErrorException> {
|
||||
fetchUrl("https://httpstat.us/$input")
|
||||
}
|
||||
assertAll("HttpErrorException validation",
|
||||
{ assertEquals(input, e.statusCode) { "status code should be $input" } },
|
||||
{ assertTrue(e.message!!.isNotEmpty()) { "message for $input should not be empty" } },
|
||||
{ assertTrue(e.cause!!.message!!.isNotEmpty()) { "cause of $input should not be empty" } })
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
@BeforeAll
|
||||
fun beforeAll() {
|
||||
with(logger) {
|
||||
addHandler(ConsoleHandler().apply { level = Level.FINE })
|
||||
level = Level.FINE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue