readme.md added

This commit is contained in:
2024-07-22 13:40:23 +01:00
parent 97773c7b01
commit 59c657eb05
15 changed files with 211 additions and 85 deletions

View File

@@ -0,0 +1,7 @@
package org.example.api
import java.util.*
fun createBasicAuthTokenForHeader(username: String, password: String) =
StringBuilder("Basic ").append(Base64.getEncoder().encodeToString("$username:$password".toByteArray()))
.toString()

View File

@@ -36,7 +36,6 @@ class BookerApi {
.setLenient()
.create()
private fun buildOkHttpClient(timeoutSeconds: Long = 30L): OkHttpClient {
val builder = OkHttpClient.Builder()

View File

@@ -33,20 +33,20 @@ interface RestfulBookerApi {
suspend fun updateBooking(
@Path("id") id: String,
@Body booking: BookingRequest,
@Header("Authorization") token: String
@Header("Authorization") basicHeaderToken: String
): Response<BookingResponse>
@Headers("Content-Type:application/json", "Accept: application/json")
@PATCH("booking/{id}")
suspend fun partialUpdateBooking(
@Path("id") id: String,
@Header("Authorization") token: String,
@Header("Authorization") basicHeaderToken: String,
@Body update: UpdateBookingRequest
): Response<BookingResponse>
@DELETE("booking/{id}")
suspend fun deleteBooking(
@Path("id") id: String,
@Header("Authorization") token: String
@Header("Authorization") basicHeaderToken: String
): Response<Any>
}

View File

@@ -7,5 +7,5 @@ data class BookingResponse(
var totalprice: Int,
var depositpaid: Boolean,
var bookingdates: Bookingdates,
var additionalneeds: String
var additionalneeds: String?
)

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
<Properties>
<Property name="basePath">Classpath</Property>
<Property name="basePath">./</Property>
</Properties>
<Appenders>
<RollingFile name="fileLogger" fileName="${basePath}/app-info.html"

View File

@@ -1,10 +1,16 @@
package org.example
import io.github.cdimascio.dotenv.dotenv
import kotlinx.coroutines.runBlocking
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.message.MessageFormatMessage
import retrofit2.Response
import java.io.IOException
abstract class NetworkTests {
abstract class BaseNetworkTests {
private val logger = LogManager.getLogger(Tests::javaClass)
private val env by lazy { dotenv() }
// Call retrofit API and unwrap response or throw exception
fun <T : Any> responseUnwrap(
@@ -22,4 +28,8 @@ abstract class NetworkTests {
}
}
fun getStoredVariable(key: String) = env.get(key)
fun logMessage(logMessage: String) = logger.info(logMessage)
fun logMessage(logMessage: MessageFormatMessage) = logger.info(logMessage)
}

View File

@@ -2,26 +2,25 @@ package org.example
import org.example.api.BookerApi
import org.example.api.RestfulBookerApi
import org.example.model.AuthRequest
import org.example.model.BookingRequest
import org.example.model.Bookingdates
import org.example.model.UpdateBookingRequest
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.message.MessageFormatMessage
import org.assertj.core.api.AssertionsForClassTypes.assertThat
import org.example.api.createBasicAuthTokenForHeader
import org.junit.jupiter.api.*
import org.example.storage.OrdersDatabase
import org.example.utils.FileReader
import org.example.utils.TestHelper
import org.example.utils.PASSWORD_KEY
import org.example.utils.USERNAME_KEY
import java.util.*
@TestMethodOrder(MethodOrderer.OrderAnnotation::class)
class Tests : NetworkTests() {
class Tests : BaseNetworkTests() {
companion object {
private lateinit var bookerApi: RestfulBookerApi
private val fileReader = FileReader()
private val logger = LogManager.getLogger(Tests::javaClass)
private val testHelper = TestHelper()
private val storage = OrdersDatabase()
@@ -33,8 +32,8 @@ class Tests : NetworkTests() {
internal fun beforeAll() {
bookerApi = BookerApi().invoke()
bookingRequestTestOne = fileReader.readJsonFileFromResources("test1", BookingRequest::class.java)
bookingRequestTestTwo = fileReader.readJsonFileFromResources("test2", BookingRequest::class.java)
bookingRequestTestOne = testHelper.readJsonFileFromResources("test1", BookingRequest::class.java)
bookingRequestTestTwo = testHelper.readJsonFileFromResources("test2", BookingRequest::class.java)
}
@AfterAll
@@ -56,17 +55,7 @@ class Tests : NetworkTests() {
/*
* Given
*/
val bookingRequestThree = BookingRequest(
firstname = "Mark",
lastname = "Wahlberg",
totalprice = 750,
depositpaid = true,
bookingdates = Bookingdates(
checkin = "2025-01-01",
checkout = "2025-01-10"
),
additionalneeds = "Breakfast"
)
val bookingRequestThree = testHelper.readJsonFileFromResources("test3", BookingRequest::class.java)
/*
* When
@@ -85,17 +74,17 @@ class Tests : NetworkTests() {
.isGreaterThanOrEqualTo(3)
val bookingIds = bookingIdsResponse.map { it.bookingid }.joinToString()
logger.info("Available booking IDs: $bookingIds")
logMessage("Available booking IDs: $bookingIds")
// Add the booking details and idea for later
bookingResponses.forEach { response ->
storage.insertBooking(response.bookingid, response.booking)
logger.trace(
logMessage(
MessageFormatMessage(
"Booking with ID: {0} has been added: {1}",
response.bookingid,
response.booking
testHelper.toJsonString(response.booking)
)
)
}
@@ -130,21 +119,11 @@ class Tests : NetworkTests() {
/*
* When
*/
val auth = responseUnwrap {
bookerApi.createAuthToken(
AuthRequest(
UUID.randomUUID().toString(),
UUID.randomUUID().toString()
)
)
}
val tokenBuilder =
StringBuilder("Basic ").append(Base64.getEncoder().encodeToString("admin:password123".toByteArray()))
.toString()
val tokenBuilder = buildBasicAuthToken()
val updateTestOneResponse = responseUnwrap {
bookerApi.partialUpdateBooking(
id = orderIdTestOne.toString(),
token = tokenBuilder,
basicHeaderToken = tokenBuilder,
update = UpdateBookingRequest(
totalprice = 1000
)
@@ -155,7 +134,7 @@ class Tests : NetworkTests() {
val updateTestTwoResponse = responseUnwrap {
bookerApi.partialUpdateBooking(
id = orderIdTestTwo.toString(),
token = tokenBuilder,
basicHeaderToken = tokenBuilder,
update = UpdateBookingRequest(
totalprice = 1500
)
@@ -163,23 +142,22 @@ class Tests : NetworkTests() {
}.also {
storage.updateCompleteOrder(orderIdTestTwo, it)
}
val updateResponseList = listOf(updateTestOneResponse, updateTestTwoResponse)
/*
* Then
*/
logger.info(
logMessage(
MessageFormatMessage(
"Booking with ID: {0} has been updated to the following: {1}",
orderIdTestOne,
updateTestOneResponse
testHelper.toJsonString(updateTestOneResponse)
)
)
logger.info(
logMessage(
MessageFormatMessage(
"Booking with ID: {0} has been updated to the following: {1}",
orderIdTestTwo,
updateTestTwoResponse
testHelper.toJsonString(updateTestTwoResponse)
)
)
}
@@ -205,11 +183,11 @@ class Tests : NetworkTests() {
/*
* Then
*/
logger.info(
logMessage(
MessageFormatMessage(
"Booking with ID: {0} has been delete and given the following response: {1}",
idOfAny,
deleteResponse
testHelper.toJsonString(deleteResponse)
)
)
}
@@ -220,6 +198,7 @@ class Tests : NetworkTests() {
/*
* Given
*/
println("The log4j library will create the report in the root of the folder")
/*
* When
@@ -229,4 +208,14 @@ class Tests : NetworkTests() {
* Then
*/
}
/**
* build a basic header token needed for using end points like partial update
*/
private fun buildBasicAuthToken(): String {
val username = getStoredVariable(USERNAME_KEY)
val password = getStoredVariable(PASSWORD_KEY)
return createBasicAuthTokenForHeader(username, password)
}
}

View File

@@ -0,0 +1,4 @@
package org.example.utils
const val USERNAME_KEY = "API_USERNAME"
const val PASSWORD_KEY = "API_PASSWORD"

View File

@@ -2,10 +2,8 @@ package org.example.utils
import com.google.gson.Gson
import java.io.BufferedReader
import java.lang.reflect.ParameterizedType
import kotlin.reflect.KClass
class FileReader {
class TestHelper {
private val gson by lazy { Gson() }
@@ -18,4 +16,6 @@ class FileReader {
val data = iStream.bufferedReader().use(BufferedReader::readText)
return gson.fromJson(data, clazz)
}
fun toJsonString(any: Any) = gson.toJson(any)
}

View File

@@ -1,11 +1,10 @@
{
"firstname" : "Jim",
"lastname" : "Brown",
"totalprice" : 500,
"depositpaid" : true,
"firstname" : "Andrea",
"lastname" : "Sims",
"totalprice" : 1000,
"depositpaid" : false,
"bookingdates" : {
"checkin" : "2025-01-01",
"checkout" : "2025-01-10"
},
"additionalneeds" : "Lunch"
}
}

View File

@@ -1,11 +1,11 @@
{
"firstname" : "Jim",
"lastname" : "Brown",
"totalprice" : 500,
"firstname" : "Mark",
"lastname" : "Wahlberg",
"totalprice" : 1500,
"depositpaid" : true,
"bookingdates" : {
"checkin" : "2025-01-01",
"checkout" : "2025-01-10"
},
"additionalneeds" : "Lunch"
"additionalneeds" : "Lunch|Dinner"
}