Viktor Orlyk
05/10/2023, 7:59 AMAleksei Tirman [JB]
05/10/2023, 9:05 AMViktor Orlyk
05/10/2023, 9:08 AMimport org.apache.commons.mail.HtmlEmail
// this thing will make request to sendgrid internally
<http://client.post|client.post>("/api/v1/auth/signup") {
headers.remove("Authorization")
contentType(ContentType.Application.Json)
setBody(body)
}
<http://client.post|client.post>("/api/v1/auth/confirm-email") {
headers.remove("Authorization")
contentType(ContentType.Application.Json)
setBody(ConfirmEmailDTO("this should be retrived from call which is made inside of service"))
}
BryanT
05/10/2023, 9:35 AMAleksei Tirman [JB]
05/10/2023, 9:40 AMViktor Orlyk
05/10/2023, 10:12 AMclass AuthSpec : FreeSpec({
val ds = createDataSourceTest()
"check login functionality" - {
"login confirmed user" - {
val signupData = SignupDTO("<mailto:giloja3553@andorem.com|giloja3553@andorem.com>", "<mailto:Giloja3553@andorem.com|Giloja3553@andorem.com>")
testApplication {
val client = createApplicationAndGetClient(ds)
<http://client.post|client.post>("/api/v1/auth/signup") {
headers.remove("Authorization")
contentType(ContentType.Application.Json)
setBody(body)
}
// somehow I need to intercept previout request to sendgrid and retrieve token and use it in request below
<http://client.post|client.post>("/api/v1/auth/confirm-email") {
headers.remove("Authorization")
contentType(ContentType.Application.Json)
setBody(ConfirmEmailDTO("hello"))
}
val loginResponse = <http://client.post|client.post>("/api/v1/auth/login"){
headers.remove("Authorization")
contentType(ContentType.Application.Json)
setBody(LoginDTO(signupData.email, signupData.password))
}
val body = loginResponse.body<LoginResponseDTO>()
body.access.shouldNotBeNull()
body.refresh.shouldNotBeNull()
}
}
}
})
my initial thought was to create a mock client but it fails for some reason
val mockEngine = MockEngine { call ->
when (call.url.toString()) {
"<https://api.sendgrid.com/v3/mail/send>" -> {
println(call.body)
respond(content = "Ok", status = HttpStatusCode.OK)
}
else -> {
error("Unhandled ${call.url}")
}
}
}
val mockClient = HttpClient(mockEngine){
install(ContentNegotiation){
json()
}
}
<http://mockClient.post|mockClient.post>("/api/v1/auth/signup").....
but it fails with next error
Unhandled <http://localhost/api/v1/auth/signup>
java.lang.IllegalStateException: Unhandled <http://localhost/api/v1/auth/signup>
at com.coinypal.features.auth.AuthSpec$1$1$1$1$mockEngine$1.invokeSuspend(AuthSpec.kt:29)
at com.coinypal.features.auth.AuthSpec$1$1$1$1$mockEngine$1.invoke(AuthSpec.kt)
at com.coinypal.features.auth.AuthSpec$1$1$1$1$mockEngine$1.invoke(AuthSpec.kt)
at io.ktor.client.engine.mock.MockEngine.execute(MockEngine.kt:71)
at io.ktor.client.engine.HttpClientEngine$executeWithinCallContext$2.invokeSuspend(HttpClientEngine.kt:99)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
if I use this mockClient instead of client which was created and returned in the first code block
fun ApplicationTestBuilder.createApplicationAndGetClient(ds:DataSource): HttpClient {
application{
DbFactory.init(ds)
configureExceptions()
configureDependencyInjection()
configureMustache()
configureCors()
configureSerialization()
configureAuthentication()
configureRouting()
}
return createClient {
install(ContentNegotiation){
json()
}
}
}
Aleksei Tirman [JB]
05/11/2023, 2:48 PMapplication
block of testApplication
by manually calling the module function.Viktor Orlyk
05/11/2023, 3:26 PM"login confirmed user" - {
val signupData = SignupDTO("<mailto:giloja3553@andorem.com|giloja3553@andorem.com>", "<mailto:Giloja3553@andorem.com|Giloja3553@andorem.com>")
testApplication {
var token: String = "this should be changed"
val mockClient = createClient {
engine {
MockEngine { call ->
when (call.url.toString()) {
"<https://api.sendgrid.com/v3/mail/send>" -> {
println("hello ${call.body}")
token = call.body.toString() // here I will find the token
respond(content = "Ok", status = HttpStatusCode.OK)
}
else -> {
error("Unhandled ${call.url}")
}
}
}
}
install(ContentNegotiation){
json()
}
}
val client = createApplicationAndGetClient(ds)
<http://mockClient.post|mockClient.post>("/api/v1/auth/signup") {
headers.remove("Authorization")
contentType(ContentType.Application.Json)
setBody(body)
}
<http://client.post|client.post>("/api/v1/auth/confirm-email") {
headers.remove("Authorization")
contentType(ContentType.Application.Json)
setBody(ConfirmEmailDTO(token))
}
val loginResponse = <http://client.post|client.post>("/api/v1/auth/login"){
headers.remove("Authorization")
contentType(ContentType.Application.Json)
setBody(LoginDTO(signupData.email, signupData.password))
}
val body = loginResponse.body<LoginResponseDTO>()
body.access.shouldNotBeNull()
body.refresh.shouldNotBeNull()
}
}
Aleksei Tirman [JB]
05/15/2023, 7:28 AMMockEngine
inside the engine
’s block but don’t assign it. You can’t change the engine of the client inside the testApplication
.