Skip to content

Commit

Permalink
More partner routing web tests
Browse files Browse the repository at this point in the history
  • Loading branch information
chrissearle committed Nov 16, 2023
1 parent c8390e7 commit 138288a
Show file tree
Hide file tree
Showing 2 changed files with 256 additions and 27 deletions.
152 changes: 152 additions & 0 deletions src/test/kotlin/no/java/partner/plugins/PartnerRoutingErrorTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package no.java.partner.plugins

import arrow.core.left
import com.typesafe.config.ConfigFactory
import io.kotest.matchers.shouldBe
import io.ktor.client.HttpClient
import io.ktor.client.call.body
import io.ktor.client.request.accept
import io.ktor.client.request.get
import io.ktor.client.request.post
import io.ktor.client.request.setBody
import io.ktor.http.ContentType
import io.ktor.http.HttpStatusCode
import io.ktor.http.contentType
import io.ktor.server.config.HoconApplicationConfig
import io.ktor.server.testing.ApplicationTestBuilder
import io.ktor.server.testing.testApplication
import io.mockk.every
import io.mockk.mockk
import io.mockk.slot
import no.java.partner.ContactNotFound
import no.java.partner.PartnerNotFound
import no.java.partner.app
import no.java.partner.model.web.CreateContact
import no.java.partner.model.web.CreatePartner
import no.java.partner.service.PartnerService
import no.java.partner.testClient
import org.junit.jupiter.api.Test

class PartnerRoutingErrorTest {
@Test
fun `GET partner 1 returns correct error when not found`() {
val partnerService = mockk<PartnerService>()

val idSlot = slot<Long>()

every { partnerService.partnerById(capture(idSlot)) } returns PartnerNotFound.left()

testApplication {
val client = setup(partnerService)

val response = client.get("/partner/1") {
accept(ContentType.Application.Json)
}

response.status shouldBe HttpStatusCode.NotFound

idSlot.captured shouldBe 1L

val message = response.body<ApiErrorResponse>()

message.message shouldBe "Partner not found"
}
}

@Test
fun `POST partner returns correct error if partner not able to be created`() {
val partnerService = mockk<PartnerService>()

val partnerSlot = slot<CreatePartner>()

every { partnerService.createPartner(capture(partnerSlot)) } returns PartnerNotFound.left()

testApplication {
val client = setup(partnerService)

val response = client.post("/partner") {
contentType(ContentType.Application.Json)
accept(ContentType.Application.Json)
setBody(PartnerRoutingTest.testCreatePartner)
}

response.status shouldBe HttpStatusCode.NotFound

partnerSlot.captured shouldBe PartnerRoutingTest.testCreatePartner

val message = response.body<ApiErrorResponse>()

message.message shouldBe "Partner not found"
}
}

@Test
fun `POST contact returns correct error if partner not found`() {
val partnerService = mockk<PartnerService>()

val idSlot = slot<Long>()
val contactSlot = slot<CreateContact>()

every { partnerService.createContact(capture(idSlot), capture(contactSlot)) } returns PartnerNotFound.left()

testApplication {
val client = setup(partnerService)

val response = client.post("/partner/1/contact") {
contentType(ContentType.Application.Json)
accept(ContentType.Application.Json)
setBody(PartnerRoutingTest.testCreateContact)
}

response.status shouldBe HttpStatusCode.NotFound

idSlot.captured shouldBe 1L
contactSlot.captured shouldBe PartnerRoutingTest.testCreateContact

val message = response.body<ApiErrorResponse>()

message.message shouldBe "Partner not found"
}
}

@Test
fun `POST contact returns correct error if contact not able to be created`() {
val partnerService = mockk<PartnerService>()

val idSlot = slot<Long>()
val contactSlot = slot<CreateContact>()

every { partnerService.createContact(capture(idSlot), capture(contactSlot)) } returns ContactNotFound.left()

testApplication {
val client = setup(partnerService)

val response = client.post("/partner/1/contact") {
contentType(ContentType.Application.Json)
accept(ContentType.Application.Json)
setBody(PartnerRoutingTest.testCreateContact)
}

response.status shouldBe HttpStatusCode.NotFound

idSlot.captured shouldBe 1L
contactSlot.captured shouldBe PartnerRoutingTest.testCreateContact

val message = response.body<ApiErrorResponse>()

message.message shouldBe "Contact not found"
}
}

private fun ApplicationTestBuilder.setup(partnerService: PartnerService): HttpClient {
environment {
config = HoconApplicationConfig(ConfigFactory.parseMap(emptyMap()))
}

app {
configurePartnerRouting(partnerService)
}

return testClient()
}
}
131 changes: 104 additions & 27 deletions src/test/kotlin/no/java/partner/plugins/PartnerRoutingTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ import io.ktor.client.HttpClient
import io.ktor.client.call.body
import io.ktor.client.request.accept
import io.ktor.client.request.get
import io.ktor.client.request.post
import io.ktor.client.request.setBody
import io.ktor.http.ContentType
import io.ktor.http.HttpStatusCode
import io.ktor.http.contentType
import io.ktor.server.config.HoconApplicationConfig
import io.ktor.server.testing.ApplicationTestBuilder
import io.ktor.server.testing.testApplication
Expand All @@ -20,19 +23,20 @@ import no.java.partner.model.Contact
import no.java.partner.model.InfoList
import no.java.partner.model.Partner
import no.java.partner.model.web.BasicPartner
import no.java.partner.model.web.CreateContact
import no.java.partner.model.web.CreatePartner
import no.java.partner.model.web.PartnerWithContacts
import no.java.partner.service.PartnerService
import no.java.partner.testClient
import org.junit.jupiter.api.Test

class PartnerRoutingTest {

@Test
fun `GET partner returns partner list`() {
val partnerService = mockk<PartnerService>()

every { partnerService.allPartners() } returns listOf(
Partner(id = 1, name = "Test Partner 1", domainName = "test.domain.tld", contacts = emptyList()),
)
every { partnerService.allPartners() } returns listOf(testPartner)

testApplication {
val client = setup(partnerService)
Expand All @@ -58,30 +62,9 @@ class PartnerRoutingTest {
fun `GET partner 1 returns partner`() {
val partnerService = mockk<PartnerService>()

val slot = slot<Long>()
val idSlot = slot<Long>()

every { partnerService.partnerById(capture(slot)) } returns Partner(
id = 1,
name = "Test Partner 1",
domainName = "test.domain.tld",
contacts = listOf(
Contact(
id = 1L,
name = "Test Contact 1",
email = "[email protected]",
telephone = "Test Telephone",
source = "Test Source",
lists = listOf(
InfoList(
id = 1L,
name = "Test List 1",
contacts = emptyList(),
unsubscribed = emptyList(),
),
),
),
),
).right()
every { partnerService.partnerById(capture(idSlot)) } returns testPartner.right()

testApplication {
val client = setup(partnerService)
Expand All @@ -92,7 +75,7 @@ class PartnerRoutingTest {

response.status shouldBe HttpStatusCode.OK

slot.captured shouldBe 1L
idSlot.captured shouldBe 1L

val partner = response.body<PartnerWithContacts>()

Expand All @@ -117,6 +100,66 @@ class PartnerRoutingTest {
}
}

@Test
fun `POST partner creates partner`() {
val partnerService = mockk<PartnerService>()

val partnerSlot = slot<CreatePartner>()

every { partnerService.createPartner(capture(partnerSlot)) } returns testPartner.right()

testApplication {
val client = setup(partnerService)

val response = client.post("/partner") {
contentType(ContentType.Application.Json)
accept(ContentType.Application.Json)
setBody(testCreatePartner)
}

response.status shouldBe HttpStatusCode.OK

partnerSlot.captured shouldBe testCreatePartner

val partner = response.body<BasicPartner>()

partner.id shouldBe 1L
partner.name shouldBe "Test Partner 1"
partner.domainName shouldBe "test.domain.tld"
}
}

@Test
fun `POST contact creates contact`() {
val partnerService = mockk<PartnerService>()

val idSlot = slot<Long>()
val contactSlot = slot<CreateContact>()

every { partnerService.createContact(capture(idSlot), capture(contactSlot)) } returns testPartner.right()

testApplication {
val client = setup(partnerService)

val response = client.post("/partner/1/contact") {
contentType(ContentType.Application.Json)
accept(ContentType.Application.Json)
setBody(testCreateContact)
}

response.status shouldBe HttpStatusCode.OK

idSlot.captured shouldBe 1L
contactSlot.captured shouldBe testCreateContact

val partner = response.body<PartnerWithContacts>()

partner.id shouldBe 1L
partner.name shouldBe "Test Partner 1"
partner.domainName shouldBe "test.domain.tld"
}
}

private fun ApplicationTestBuilder.setup(partnerService: PartnerService): HttpClient {
environment {
config = HoconApplicationConfig(ConfigFactory.parseMap(emptyMap()))
Expand All @@ -128,4 +171,38 @@ class PartnerRoutingTest {

return testClient()
}

companion object {
val testCreatePartner = CreatePartner(name = "Test Partner", domainName = "Test Domain Name")

val testCreateContact = CreateContact(
name = "Test Contact",
email = "[email protected]",
telephone = "Test Telephone",
source = "Test Source",
)

val testPartner = Partner(
id = 1,
name = "Test Partner 1",
domainName = "test.domain.tld",
contacts = listOf(
Contact(
id = 1L,
name = "Test Contact 1",
email = "[email protected]",
telephone = "Test Telephone",
source = "Test Source",
lists = listOf(
InfoList(
id = 1L,
name = "Test List 1",
contacts = emptyList(),
unsubscribed = emptyList(),
),
),
),
),
)
}
}

0 comments on commit 138288a

Please sign in to comment.