mirror of
https://github.com/hmalik144/api-testing-automation-framework.git
synced 2025-12-10 02:55:21 +00:00
Tests pass but logging is still required
This commit is contained in:
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@@ -8,7 +8,7 @@
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_20" default="true" project-jdk-name="20" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17 (2)" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
47
pom.xml
47
pom.xml
@@ -65,6 +65,14 @@
|
||||
<mainClass>MainKt</mainClass>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>8</source>
|
||||
<target>8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
@@ -81,18 +89,17 @@
|
||||
<version>5.10.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>5.10.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib</artifactId>
|
||||
<version>1.9.0</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/io.rest-assured/rest-assured -->
|
||||
<dependency>
|
||||
<groupId>io.rest-assured</groupId>
|
||||
<artifactId>rest-assured</artifactId>
|
||||
<version>5.5.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- jUnit -->
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
@@ -111,6 +118,12 @@
|
||||
<artifactId>retrofit</artifactId>
|
||||
<version>2.11.0</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/com.squareup.retrofit2/converter-gson -->
|
||||
<dependency>
|
||||
<groupId>com.squareup.retrofit2</groupId>
|
||||
<artifactId>converter-gson</artifactId>
|
||||
<version>2.9.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>logging-interceptor</artifactId>
|
||||
@@ -121,19 +134,11 @@
|
||||
<artifactId>api-testing-automation-framework</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/com.squareup.retrofit2/converter-gson -->
|
||||
<dependency>
|
||||
<groupId>com.squareup.retrofit2</groupId>
|
||||
<artifactId>converter-gson</artifactId>
|
||||
<version>2.11.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlinx</groupId>
|
||||
<artifactId>kotlinx-coroutines-core</artifactId>
|
||||
<version>1.6.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
@@ -144,6 +149,18 @@
|
||||
<artifactId>log4j-api</artifactId>
|
||||
<version>2.19.0</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.assertj/assertj-core -->
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>3.26.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sf.jasperreports</groupId>
|
||||
<artifactId>jasperreports</artifactId>
|
||||
<version>6.20.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -1,26 +1,54 @@
|
||||
package api
|
||||
|
||||
import com.google.gson.GsonBuilder
|
||||
import okhttp3.OkHttpClient
|
||||
import java.util.concurrent.TimeUnit
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.converter.gson.GsonConverterFactory
|
||||
import java.security.SecureRandom
|
||||
import java.security.cert.CertificateException
|
||||
import java.security.cert.X509Certificate
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.net.ssl.SSLContext
|
||||
import javax.net.ssl.TrustManager
|
||||
import javax.net.ssl.X509TrustManager
|
||||
|
||||
|
||||
class BookerApi {
|
||||
private val baseUrl = "https://restful-booker.herokuapp.com/"
|
||||
|
||||
private val loggingInterceptor = HttpLoggingInterceptor().apply {
|
||||
level = HttpLoggingInterceptor.Level.BODY
|
||||
var trustAllCerts = arrayOf<TrustManager>(
|
||||
object : X509TrustManager {
|
||||
@Throws(CertificateException::class)
|
||||
override fun checkClientTrusted(chain: Array<X509Certificate?>?, authType: String?) {
|
||||
}
|
||||
|
||||
@Throws(CertificateException::class)
|
||||
override fun checkServerTrusted(chain: Array<X509Certificate?>?, authType: String?) {
|
||||
}
|
||||
|
||||
override fun getAcceptedIssuers(): Array<X509Certificate?> {
|
||||
return arrayOfNulls<X509Certificate>(0)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
var gson = GsonBuilder()
|
||||
.setLenient()
|
||||
.create()
|
||||
|
||||
|
||||
private fun buildOkHttpClient(timeoutSeconds: Long = 30L): OkHttpClient {
|
||||
val builder = OkHttpClient.Builder()
|
||||
|
||||
val sslContext = SSLContext.getInstance("SSL")
|
||||
sslContext.init(null, trustAllCerts, SecureRandom())
|
||||
|
||||
builder
|
||||
.addInterceptor(loggingInterceptor)
|
||||
.connectTimeout(timeoutSeconds, TimeUnit.SECONDS)
|
||||
.writeTimeout(timeoutSeconds, TimeUnit.SECONDS)
|
||||
.readTimeout(timeoutSeconds, TimeUnit.SECONDS)
|
||||
.sslSocketFactory(sslContext.socketFactory, trustAllCerts[0] as X509TrustManager)
|
||||
.hostnameVerifier { _, _ -> true }
|
||||
|
||||
return builder.build()
|
||||
}
|
||||
@@ -30,7 +58,7 @@ class BookerApi {
|
||||
return Retrofit.Builder()
|
||||
.client(okHttpClient)
|
||||
.baseUrl(baseUrl)
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
.addConverterFactory(GsonConverterFactory.create(gson))
|
||||
.build()
|
||||
.create(RestfulBookerApi::class.java)
|
||||
}
|
||||
|
||||
@@ -6,19 +6,15 @@ import retrofit2.http.*
|
||||
|
||||
interface RestfulBookerApi {
|
||||
|
||||
@Headers("Content-Type:application/json")
|
||||
@Headers("Content-Type:application/json", "Accept: application/json")
|
||||
@POST("auth")
|
||||
suspend fun createAuthToken(
|
||||
@Field("username") username: String,
|
||||
@Field("password") password: String,
|
||||
@Body authRequest: AuthRequest
|
||||
): Response<AuthResponse>
|
||||
|
||||
@GET("booking")
|
||||
suspend fun getBookingIds(
|
||||
@Field("firstname") firstname: String? = null,
|
||||
@Field("lastname") lastname: String? = null,
|
||||
@Field("checkin") checkin: String? = null,
|
||||
@Field("checkout") checkout: String? = null,
|
||||
|
||||
): Response<List<BookingIdResponse>>
|
||||
|
||||
@GET("booking/{id}")
|
||||
@@ -26,7 +22,7 @@ interface RestfulBookerApi {
|
||||
@Path("id") id: String
|
||||
): Response<BookingResponse>
|
||||
|
||||
@Headers("Content-Type:application/json")
|
||||
@Headers("Content-Type:application/json", "Accept: application/json")
|
||||
@POST("booking")
|
||||
suspend fun createBooking(
|
||||
@Body booking: BookingRequest,
|
||||
@@ -45,17 +41,12 @@ interface RestfulBookerApi {
|
||||
suspend fun partialUpdateBooking(
|
||||
@Path("id") id: String,
|
||||
@Header("Authorization") token: String,
|
||||
@Field("firstname") firstname: String? = null,
|
||||
@Field("lastname") lastname: String? = null,
|
||||
@Field("totalprice") totalprice: Float? = null,
|
||||
@Field("depositpaid") depositpaid: Boolean? = null,
|
||||
@Field("checkin") checkin: String? = null,
|
||||
@Field("checkout") checkout: String? = null,
|
||||
@Field("additionalneeds") additionalneeds: String? = null
|
||||
@Body update: UpdateBookingRequest
|
||||
): Response<BookingResponse>
|
||||
|
||||
@DELETE("booking/{id}")
|
||||
suspend fun deleteBooking(
|
||||
@Path("id") id: String
|
||||
@Path("id") id: String,
|
||||
@Header("Authorization") token: String
|
||||
): Response<Any>
|
||||
}
|
||||
6
src/main/kotlin/model/AuthRequest.kt
Normal file
6
src/main/kotlin/model/AuthRequest.kt
Normal file
@@ -0,0 +1,6 @@
|
||||
package model
|
||||
|
||||
data class AuthRequest(
|
||||
val username: String,
|
||||
val password: String
|
||||
)
|
||||
@@ -1,5 +1,5 @@
|
||||
package model
|
||||
|
||||
class AuthResponse {
|
||||
var token: String? = null
|
||||
}
|
||||
data class AuthResponse (
|
||||
val token: String
|
||||
)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
package model
|
||||
|
||||
class BookingIdResponse {
|
||||
var bookingid = 0
|
||||
}
|
||||
data class BookingIdResponse(
|
||||
val bookingid: Int
|
||||
)
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package model
|
||||
|
||||
data class BookingRequest (
|
||||
var firstname: String? = null,
|
||||
var lastname: String? = null,
|
||||
var totalprice: Int = 0,
|
||||
var depositpaid: Boolean = false,
|
||||
var bookingdates: Bookingdates? = null,
|
||||
var additionalneeds: String? = null,
|
||||
var firstname: String,
|
||||
var lastname: String,
|
||||
var totalprice: Int,
|
||||
var depositpaid: Boolean,
|
||||
var bookingdates: Bookingdates,
|
||||
var additionalneeds: String,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@ package model
|
||||
|
||||
|
||||
data class BookingResponse(
|
||||
var firstname: String? = null,
|
||||
var lastname: String? = null,
|
||||
var totalprice: Int = 0,
|
||||
var depositpaid: Boolean = false,
|
||||
var bookingdates: Bookingdates? = null,
|
||||
var additionalneeds: String? = null
|
||||
var firstname: String,
|
||||
var lastname: String,
|
||||
var totalprice: Int,
|
||||
var depositpaid: Boolean,
|
||||
var bookingdates: Bookingdates,
|
||||
var additionalneeds: String
|
||||
)
|
||||
@@ -1,6 +1,6 @@
|
||||
package model
|
||||
|
||||
data class Bookingdates (
|
||||
var checkin: String? = null,
|
||||
var checkout: String? = null,
|
||||
var checkin: String,
|
||||
var checkout: String,
|
||||
)
|
||||
@@ -1,6 +1,6 @@
|
||||
package model
|
||||
|
||||
class CreateBookingResponse {
|
||||
var bookingid = 0
|
||||
var booking: BookingResponse? = null
|
||||
}
|
||||
data class CreateBookingResponse(
|
||||
var bookingid: Int,
|
||||
var booking: BookingResponse
|
||||
)
|
||||
10
src/main/kotlin/model/UpdateBookingRequest.kt
Normal file
10
src/main/kotlin/model/UpdateBookingRequest.kt
Normal file
@@ -0,0 +1,10 @@
|
||||
package model
|
||||
|
||||
data class UpdateBookingRequest(
|
||||
var firstname: String? = null,
|
||||
var lastname: String? = null,
|
||||
var totalprice: Int? = null,
|
||||
var depositpaid: Boolean? = null,
|
||||
var bookingdates: Bookingdates? = null,
|
||||
var additionalneeds: String? = null,
|
||||
)
|
||||
92
src/main/kotlin/storage/OrdersDatabase.kt
Normal file
92
src/main/kotlin/storage/OrdersDatabase.kt
Normal file
@@ -0,0 +1,92 @@
|
||||
package storage
|
||||
|
||||
import model.BookingResponse
|
||||
import model.Bookingdates
|
||||
|
||||
class OrdersDatabase {
|
||||
private val storage = mutableMapOf<Int, BookingResponse>()
|
||||
|
||||
// Create
|
||||
fun insertBooking(id: Int, booking: BookingResponse) {
|
||||
if (storage.contains(id)) {
|
||||
storage.replace(id, booking)
|
||||
} else {
|
||||
storage[id] = booking
|
||||
}
|
||||
}
|
||||
|
||||
// Read
|
||||
fun getIdsOfBookingsAvailable() = storage.keys.toList()
|
||||
fun getBookingsAvailable() = storage.values.toList()
|
||||
fun getIdsAndBookings() = storage.toMap()
|
||||
|
||||
fun getIdsOfOrderBasedOnValues(
|
||||
firstname: String? = null,
|
||||
lastname: String? = null,
|
||||
totalprice: Int? = null,
|
||||
depositpaid: Boolean? = null,
|
||||
checkin: String? = null,
|
||||
checkout: String? = null,
|
||||
additionalneeds: String? = null
|
||||
): List<Int> {
|
||||
return storage.filterValues {
|
||||
firstname?.let { f -> f == it.firstname } ?: true &&
|
||||
lastname?.let { f -> f == it.lastname } ?: true &&
|
||||
totalprice?.let { f -> f == it.totalprice } ?: true &&
|
||||
depositpaid?.let { f -> f == it.depositpaid } ?: true &&
|
||||
checkin?.let { f -> f == it.bookingdates.checkin } ?: true &&
|
||||
checkout?.let { f -> f == it.bookingdates.checkout } ?: true &&
|
||||
additionalneeds?.let { f -> f == it.additionalneeds } ?: true
|
||||
}.keys.toList()
|
||||
}
|
||||
|
||||
fun getIdsOfOrderBasedOnValues(
|
||||
id: Int
|
||||
): BookingResponse? {
|
||||
return storage[id]
|
||||
}
|
||||
|
||||
// Update
|
||||
fun updateCompleteOrder(id: Int, newBookingResponse: BookingResponse) {
|
||||
insertBooking(id, newBookingResponse)
|
||||
}
|
||||
|
||||
fun updateOrderPartial(
|
||||
id: Int,
|
||||
firstname: String? = null,
|
||||
lastname: String? = null,
|
||||
totalprice: Int? = null,
|
||||
depositpaid: Boolean? = null,
|
||||
checkin: String? = null,
|
||||
checkout: String? = null,
|
||||
additionalneeds: String? = null
|
||||
) {
|
||||
if (storage.keys.remove(id)) {
|
||||
storage.compute(id) { k, v ->
|
||||
val mFirstName = firstname ?: v!!.firstname
|
||||
val mlastname = lastname ?: v!!.lastname
|
||||
val mTotalprice = totalprice ?: v!!.totalprice
|
||||
val mDepositpaid = depositpaid ?: v!!.depositpaid
|
||||
val mCheckin = checkin ?: v!!.bookingdates.checkin
|
||||
val mCheckout = checkout ?: v!!.bookingdates.checkout
|
||||
val mAdditionalneeds = additionalneeds ?: v!!.additionalneeds
|
||||
BookingResponse(
|
||||
firstname = mFirstName,
|
||||
lastname = mlastname,
|
||||
totalprice = mTotalprice,
|
||||
depositpaid = mDepositpaid,
|
||||
bookingdates = Bookingdates(
|
||||
checkin = mCheckin,
|
||||
checkout = mCheckout
|
||||
),
|
||||
additionalneeds = mAdditionalneeds
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete
|
||||
fun clearAllData() = storage.clear()
|
||||
|
||||
fun deleteSingleEntry(id: Int) = storage.remove(id)
|
||||
}
|
||||
27
src/main/resources/Log4j2.xml
Normal file
27
src/main/resources/Log4j2.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Configuration status="warn">
|
||||
<Properties>
|
||||
<Property name="basePath">C:\\logs</Property>
|
||||
</Properties>
|
||||
<Appenders>
|
||||
<RollingFile name="fileLogger" fileName="${basePath}/app-info.html"
|
||||
filePattern="${basePath}/app-info-%d{yyyy-MM-dd}.html">
|
||||
<HTMLLayout charset="UTF-8" title="Howtodoinjava Info Logs" locationInfo="true" />
|
||||
<Policies>
|
||||
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
|
||||
<SizeBasedTriggeringPolicy size="10 MB" />
|
||||
</Policies>
|
||||
</RollingFile>
|
||||
<Console name="console" target="SYSTEM_OUT">
|
||||
<PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n" />
|
||||
</Console>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
<Logger name="com.howtodoinjava" level="debug" additivity="false">
|
||||
<appender-ref ref="fileLogger" level="debug" />
|
||||
</Logger>
|
||||
<Root level="debug" additivity="false">
|
||||
<appender-ref ref="console" />
|
||||
</Root>
|
||||
</Loggers>
|
||||
</Configuration>
|
||||
@@ -4,6 +4,7 @@ import java.io.IOException
|
||||
|
||||
abstract class NetworkTests {
|
||||
|
||||
// Call retrofit API and unwrap response or throw exception
|
||||
fun <T : Any> responseUnwrap(
|
||||
call: suspend () -> Response<T>
|
||||
): T {
|
||||
@@ -12,9 +13,11 @@ abstract class NetworkTests {
|
||||
if (response.isSuccessful) {
|
||||
return response.body()!!
|
||||
} else {
|
||||
val error = response.errorBody()?.string()
|
||||
val error = StringBuilder().append(response.code()).append(" : ")
|
||||
.append(response.errorBody()?.string() ?: "Unable to handle end point").toString()
|
||||
print(response.raw())
|
||||
throw IOException(error)
|
||||
}
|
||||
}
|
||||
|
||||
throw IOException(error ?: "Unable to handle end point")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,35 +1,56 @@
|
||||
import api.BookerApi
|
||||
import api.RestfulBookerApi
|
||||
import io.restassured.RestAssured.given
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import model.AuthRequest
|
||||
import model.BookingRequest
|
||||
import model.Bookingdates
|
||||
import model.UpdateBookingRequest
|
||||
import net.sf.jasperreports.engine.JasperCompileManager
|
||||
import net.sf.jasperreports.engine.JasperFillManager
|
||||
import net.sf.jasperreports.engine.JasperReport
|
||||
import net.sf.jasperreports.engine.export.HtmlExporter
|
||||
import net.sf.jasperreports.engine.util.JRSaver
|
||||
import net.sf.jasperreports.export.SimpleHtmlExporterOutput
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import org.junit.FixMethodOrder
|
||||
import org.junit.jupiter.api.AfterAll
|
||||
import org.junit.jupiter.api.BeforeAll
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.runners.MethodSorters
|
||||
import org.apache.logging.log4j.message.MessageFormatMessage
|
||||
import org.assertj.core.api.AssertionsForClassTypes.assertThat
|
||||
import org.junit.jupiter.api.*
|
||||
import storage.OrdersDatabase
|
||||
import utils.FileReader
|
||||
import java.io.InputStream
|
||||
import java.util.*
|
||||
|
||||
@FixMethodOrder(MethodSorters.DEFAULT)
|
||||
|
||||
@TestMethodOrder(MethodOrderer.OrderAnnotation::class)
|
||||
class Tests : NetworkTests() {
|
||||
|
||||
companion object {
|
||||
private lateinit var bookerApi: RestfulBookerApi
|
||||
private lateinit var fileReader: FileReader
|
||||
private val logger = LogManager.getLogger(Tests::class.java)
|
||||
private val fileReader = FileReader()
|
||||
private val logger = LogManager.getLogger("Test")
|
||||
|
||||
val bookingsReportStream: InputStream = javaClass.getResourceAsStream("/bookingsReport.jrxml")
|
||||
val jasperReport: JasperReport = JasperCompileManager.compileReport(bookingsReportStream)
|
||||
|
||||
private val storage = OrdersDatabase()
|
||||
|
||||
private lateinit var bookingRequestTestOne: BookingRequest
|
||||
private lateinit var bookingRequestTestTwo: BookingRequest
|
||||
|
||||
@BeforeAll
|
||||
@JvmStatic
|
||||
internal fun beforeAll() {
|
||||
bookerApi = BookerApi().invoke()
|
||||
|
||||
bookingRequestTestOne = fileReader.readJsonFileFromResources("test1", BookingRequest::class.java)
|
||||
bookingRequestTestTwo = fileReader.readJsonFileFromResources("test2", BookingRequest::class.java)
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
@JvmStatic
|
||||
internal fun afterAll() {
|
||||
storage.clearAllData()
|
||||
|
||||
JRSaver.saveObject(jasperReport, "bookingReport.jasper");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,10 +61,11 @@ class Tests : NetworkTests(){
|
||||
* o Above added 3 new booking details
|
||||
*/
|
||||
@Test()
|
||||
@Order(1)
|
||||
fun testScenarioOne() {
|
||||
// Given
|
||||
val bookingRequestOne = fileReader.readJsonFileFromResources<BookingRequest>("test1")
|
||||
val bookingRequestTwo = fileReader.readJsonFileFromResources<BookingRequest>("test2")
|
||||
/*
|
||||
* Given
|
||||
*/
|
||||
val bookingRequestThree = BookingRequest(
|
||||
firstname = "Mark",
|
||||
lastname = "Wahlberg",
|
||||
@@ -56,17 +78,36 @@ class Tests : NetworkTests(){
|
||||
additionalneeds = "Breakfast"
|
||||
)
|
||||
|
||||
// When
|
||||
val createBookingOneResponse = responseUnwrap { bookerApi.createBooking(bookingRequestOne) }
|
||||
val createBookingTwoResponse = responseUnwrap { bookerApi.createBooking(bookingRequestTwo) }
|
||||
/*
|
||||
* When
|
||||
*/
|
||||
val createBookingOneResponse = responseUnwrap { bookerApi.createBooking(bookingRequestTestOne) }
|
||||
val createBookingTwoResponse = responseUnwrap { bookerApi.createBooking(bookingRequestTestTwo) }
|
||||
val createBookingThreeResponse = responseUnwrap { bookerApi.createBooking(bookingRequestThree) }
|
||||
val bookingResponses = listOf(createBookingOneResponse, createBookingTwoResponse, createBookingThreeResponse)
|
||||
|
||||
// Then
|
||||
/*
|
||||
* Then
|
||||
*/
|
||||
val bookingIds = responseUnwrap { bookerApi.getBookingIds() }
|
||||
assertThat(bookingIds.size)
|
||||
.withFailMessage("Did not find 3 bookings")
|
||||
.isGreaterThanOrEqualTo(3)
|
||||
|
||||
JasperFillManager.
|
||||
logger.trace("Available booking IDs: ${bookingIds.joinToString()}")
|
||||
bookingIds.forEach {
|
||||
val currentBookingResponse = responseUnwrap { bookerApi.getSingleBooking("$it") }
|
||||
logger.trace(currentBookingResponse)
|
||||
|
||||
// Add the booking details and idea for later
|
||||
bookingResponses.forEach { response ->
|
||||
storage.insertBooking(response.bookingid, response.booking)
|
||||
|
||||
logger.trace(
|
||||
MessageFormatMessage(
|
||||
"Booking with ID: {0} has been added: {1}",
|
||||
response.bookingid,
|
||||
response.booking
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,29 +118,133 @@ class Tests : NetworkTests(){
|
||||
*
|
||||
*/
|
||||
@Test()
|
||||
@Order(2)
|
||||
fun testScenarioTwo() {
|
||||
// Given
|
||||
/*
|
||||
* Given
|
||||
*/
|
||||
// Find my booking ids
|
||||
val orderIdTestOne = storage.getIdsOfOrderBasedOnValues(
|
||||
firstname = bookingRequestTestOne.firstname,
|
||||
lastname = bookingRequestTestOne.lastname,
|
||||
checkin = bookingRequestTestOne.bookingdates.checkin,
|
||||
checkout = bookingRequestTestOne.bookingdates.checkout
|
||||
).first()
|
||||
val orderIdTestTwo = storage.getIdsOfOrderBasedOnValues(
|
||||
firstname = bookingRequestTestTwo.firstname,
|
||||
lastname = bookingRequestTestTwo.lastname,
|
||||
checkin = bookingRequestTestTwo.bookingdates.checkin,
|
||||
checkout = bookingRequestTestTwo.bookingdates.checkout
|
||||
).first()
|
||||
|
||||
// When
|
||||
/*
|
||||
* 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 updateTestOneResponse = responseUnwrap {
|
||||
bookerApi.partialUpdateBooking(
|
||||
id = orderIdTestOne.toString(),
|
||||
token = tokenBuilder,
|
||||
update = UpdateBookingRequest(
|
||||
totalprice = 1000
|
||||
)
|
||||
)
|
||||
}.also {
|
||||
storage.updateCompleteOrder(orderIdTestOne, it)
|
||||
}
|
||||
val updateTestTwoResponse = responseUnwrap {
|
||||
bookerApi.partialUpdateBooking(
|
||||
id = orderIdTestTwo.toString(),
|
||||
token = tokenBuilder,
|
||||
update = UpdateBookingRequest(
|
||||
totalprice = 1500
|
||||
)
|
||||
)
|
||||
}.also {
|
||||
storage.updateCompleteOrder(orderIdTestTwo, it)
|
||||
}
|
||||
val updateResponseList = listOf(updateTestOneResponse, updateTestTwoResponse)
|
||||
|
||||
// Then
|
||||
/*
|
||||
* Then
|
||||
*/
|
||||
logger.trace(
|
||||
MessageFormatMessage(
|
||||
"Booking with ID: {0} has been updated to the following: {1}",
|
||||
orderIdTestOne,
|
||||
updateTestOneResponse
|
||||
)
|
||||
)
|
||||
logger.trace(
|
||||
MessageFormatMessage(
|
||||
"Booking with ID: {0} has been updated to the following: {1}",
|
||||
orderIdTestTwo,
|
||||
updateTestTwoResponse
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test()
|
||||
@Order(3)
|
||||
fun testScenarioThree() {
|
||||
// Given
|
||||
/*
|
||||
* Given
|
||||
*/
|
||||
val idOfAny = storage.getIdsOfBookingsAvailable().random()
|
||||
val tokenBuilder =
|
||||
StringBuilder("Basic ").append(Base64.getEncoder().encodeToString("admin:password123".toByteArray()))
|
||||
.toString()
|
||||
|
||||
// When
|
||||
/*
|
||||
* When
|
||||
*/
|
||||
val deleteResponse = responseUnwrap {
|
||||
bookerApi.deleteBooking(id = idOfAny.toString(), tokenBuilder)
|
||||
}.also { storage.deleteSingleEntry(id = idOfAny) }
|
||||
|
||||
// Then
|
||||
/*
|
||||
* Then
|
||||
*/
|
||||
logger.trace(
|
||||
MessageFormatMessage(
|
||||
"Booking with ID: {0} has been delete and given the following response: {1}",
|
||||
idOfAny,
|
||||
deleteResponse
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test()
|
||||
@Order(4)
|
||||
fun testScenarioFour() {
|
||||
// Given
|
||||
/*
|
||||
* Given
|
||||
*/
|
||||
|
||||
// When
|
||||
/*
|
||||
* When
|
||||
*/
|
||||
|
||||
// Then
|
||||
/*
|
||||
* Then
|
||||
*/
|
||||
val exporter = HtmlExporter()
|
||||
|
||||
// Set input ...
|
||||
|
||||
// Set input ...
|
||||
exporter.exporterOutput = SimpleHtmlExporterOutput("bookingsReport.html")
|
||||
|
||||
exporter.exportReport()
|
||||
}
|
||||
}
|
||||
@@ -3,19 +3,19 @@ package utils
|
||||
import com.google.gson.Gson
|
||||
import java.io.BufferedReader
|
||||
import java.lang.reflect.ParameterizedType
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
class FileReader {
|
||||
|
||||
private val gson by lazy { Gson() }
|
||||
|
||||
fun <T : Any?> readJsonFileFromResources(fileName: String): T {
|
||||
val iStream = this::class.java.getResourceAsStream("$fileName.json")
|
||||
/**
|
||||
* Read json files from resources and turn into object of type <T>
|
||||
*/
|
||||
fun <T : Any?> readJsonFileFromResources(fileName: String, clazz: Class<T>): T {
|
||||
val iStream = this::class.java.getResourceAsStream("/$fileName.json")
|
||||
?: throw IllegalStateException("Unable to read the file requested")
|
||||
val data = iStream.bufferedReader().use(BufferedReader::readText)
|
||||
val genericType = ((javaClass.genericSuperclass as? ParameterizedType)
|
||||
?.actualTypeArguments?.getOrNull(0) as? Class<T>)
|
||||
?: throw IllegalStateException("Can not find class from generic argument")
|
||||
|
||||
return gson.fromJson(data, genericType)
|
||||
return gson.fromJson(data, clazz)
|
||||
}
|
||||
}
|
||||
28
src/test/resources/reportTemplate.jrxml
Normal file
28
src/test/resources/reportTemplate.jrxml
Normal file
@@ -0,0 +1,28 @@
|
||||
<jasperReport>
|
||||
<field name="FIRST_NAME" class="java.lang.String"/>
|
||||
<field name="LAST_NAME" class="java.lang.String"/>
|
||||
<field name="SALARY" class="java.lang.Double"/>
|
||||
<field name="ID" class="java.lang.Integer"/>
|
||||
<detail>
|
||||
<band height="51" splitType="Stretch">
|
||||
<textField>
|
||||
<reportElement x="0" y="0" width="100" height="20"/>
|
||||
<textElement/>
|
||||
<textFieldExpression class="java.lang.String">
|
||||
<![CDATA[$F{FIRST_NAME}]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField>
|
||||
<reportElement x="100" y="0" width="100" height="20"/>
|
||||
<textElement/>
|
||||
<textFieldExpression class="java.lang.String">
|
||||
<![CDATA[$F{LAST_NAME}]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField>
|
||||
<reportElement x="200" y="0" width="100" height="20"/>
|
||||
<textElement/>
|
||||
<textFieldExpression class="java.lang.String">
|
||||
<![CDATA[$F{SALARY}]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</detail>
|
||||
</jasperReport>
|
||||
11
src/test/resources/test3.json
Normal file
11
src/test/resources/test3.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"firstname" : "Jim",
|
||||
"lastname" : "Brown",
|
||||
"totalprice" : 500,
|
||||
"depositpaid" : true,
|
||||
"bookingdates" : {
|
||||
"checkin" : "2025-01-01",
|
||||
"checkout" : "2025-01-10"
|
||||
},
|
||||
"additionalneeds" : "Lunch"
|
||||
}
|
||||
Reference in New Issue
Block a user