From 8885a1fb96527bc8d3a71bff828eb849b68ee97b Mon Sep 17 00:00:00 2001 From: Gabriel Sancho Date: Thu, 26 Mar 2026 18:47:04 -0300 Subject: [PATCH] =?UTF-8?q?test(backend):=20add=20failing=20tests=20for=20?= =?UTF-8?q?step=206=20=E2=80=94=20AiService?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../newsletter/service/AiServiceTest.kt | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 backend/src/test/kotlin/com/condado/newsletter/service/AiServiceTest.kt diff --git a/backend/src/test/kotlin/com/condado/newsletter/service/AiServiceTest.kt b/backend/src/test/kotlin/com/condado/newsletter/service/AiServiceTest.kt new file mode 100644 index 0000000..0113390 --- /dev/null +++ b/backend/src/test/kotlin/com/condado/newsletter/service/AiServiceTest.kt @@ -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 { + 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 { + service.parseResponse(raw) + } + } + + @Test + fun should_throwParseException_when_responseIsMissingBodySection() { + val raw = "SUBJECT: Some Subject\nNo body section here" + + assertThrows { + service.parseResponse(raw) + } + } + + // ── helper ────────────────────────────────────────────────────────────── + + private fun stubRestClient(responseText: String) { + every { mockRestClient.post() } returns mockRequestBodyUriSpec + every { mockRequestBodyUriSpec.uri(any()) } returns mockRequestBodySpec + every { mockRequestBodySpec.header(any(), any()) } returns mockRequestBodySpec + every { mockRequestBodySpec.body(any()) } returns mockRequestBodySpec + every { mockRequestBodySpec.retrieve() } returns mockResponseSpec + every { mockResponseSpec.body(String::class.java) } returns """ + { + "choices": [ + { "message": { "content": "$responseText" } } + ] + } + """.trimIndent() + } +}