test(backend): add failing tests for step 6 — AiService

This commit is contained in:
2026-03-26 18:47:04 -03:00
parent 7d45586798
commit 8885a1fb96

View File

@@ -0,0 +1,88 @@
package com.condado.newsletter.service
import com.condado.newsletter.model.ParsedAiResponse
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import org.springframework.web.client.RestClient
class AiServiceTest {
private val mockRestClient: RestClient = mockk()
private val mockRequestBodyUriSpec: RestClient.RequestBodyUriSpec = mockk()
private val mockRequestBodySpec: RestClient.RequestBodySpec = mockk()
private val mockResponseSpec: RestClient.ResponseSpec = mockk()
private val service = AiService(
restClient = mockRestClient,
apiKey = "test-key",
model = "gpt-4o"
)
@Test
fun should_returnAiResponseText_when_apiCallSucceeds() {
val rawResponse = "SUBJECT: Test Subject\nBODY:\nTest body content"
stubRestClient(rawResponse)
val result = service.generate("My test prompt")
assertThat(result.subject).isEqualTo("Test Subject")
assertThat(result.body).isEqualTo("Test body content")
}
@Test
fun should_throwAiServiceException_when_apiReturnsError() {
every { mockRestClient.post() } throws RuntimeException("API unavailable")
assertThrows<AiServiceException> {
service.generate("My prompt")
}
}
@Test
fun should_extractSubjectAndBody_when_responseIsWellFormatted() {
val raw = "SUBJECT: Weekly Update\nBODY:\nDear colleagues,\n\nPlease note the snacks."
val result = service.parseResponse(raw)
assertThat(result.subject).isEqualTo("Weekly Update")
assertThat(result.body).isEqualTo("Dear colleagues,\n\nPlease note the snacks.")
}
@Test
fun should_throwParseException_when_responseIsMissingSubjectLine() {
val raw = "BODY:\nSome body without a subject"
assertThrows<AiParseException> {
service.parseResponse(raw)
}
}
@Test
fun should_throwParseException_when_responseIsMissingBodySection() {
val raw = "SUBJECT: Some Subject\nNo body section here"
assertThrows<AiParseException> {
service.parseResponse(raw)
}
}
// ── helper ──────────────────────────────────────────────────────────────
private fun stubRestClient(responseText: String) {
every { mockRestClient.post() } returns mockRequestBodyUriSpec
every { mockRequestBodyUriSpec.uri(any<String>()) } returns mockRequestBodySpec
every { mockRequestBodySpec.header(any(), any()) } returns mockRequestBodySpec
every { mockRequestBodySpec.body(any<Any>()) } returns mockRequestBodySpec
every { mockRequestBodySpec.retrieve() } returns mockResponseSpec
every { mockResponseSpec.body(String::class.java) } returns """
{
"choices": [
{ "message": { "content": "$responseText" } }
]
}
""".trimIndent()
}
}