From 8a83431422d71e64b1d05432a7f1c3919df7992d Mon Sep 17 00:00:00 2001 From: lincmba Date: Wed, 8 Jan 2025 19:13:31 +0300 Subject: [PATCH] Add option to run tests bu hitting the actual API --- .../quest/ui/speechtoform/GeminiModel.kt | 1 + .../quest/ui/speechtoform/SpeechToTextTest.kt | 49 ++++++++++++------- .../quest/ui/speechtoform/TextToFormTest.kt | 34 ++++++++++--- 3 files changed, 59 insertions(+), 25 deletions(-) diff --git a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/speechtoform/GeminiModel.kt b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/speechtoform/GeminiModel.kt index 0fca9b57c7..febc59b091 100644 --- a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/speechtoform/GeminiModel.kt +++ b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/speechtoform/GeminiModel.kt @@ -45,6 +45,7 @@ class GeminiModel() { SafetySetting(HarmCategory.DANGEROUS_CONTENT, BlockThreshold.MEDIUM_AND_ABOVE), ), ) + /** * Returns the configured GenerativeModel instance. * diff --git a/android/quest/src/test/java/org/smartregister/fhircore/quest/ui/speechtoform/SpeechToTextTest.kt b/android/quest/src/test/java/org/smartregister/fhircore/quest/ui/speechtoform/SpeechToTextTest.kt index 76388fb630..424041b2dc 100644 --- a/android/quest/src/test/java/org/smartregister/fhircore/quest/ui/speechtoform/SpeechToTextTest.kt +++ b/android/quest/src/test/java/org/smartregister/fhircore/quest/ui/speechtoform/SpeechToTextTest.kt @@ -38,29 +38,47 @@ class SpeechToTextTest { private lateinit var speechToText: SpeechToText private lateinit var mockSpeechClient: SpeechClient + private val useRealApi = System.getProperty("USE_REAL_API")?.toBoolean() ?: false @Before fun setUp() { - // Initialize the SpeechToText instance and mock dependencies - mockSpeechClient = mockk(relaxed = true) - mockkStatic(SpeechClient::class) - every { SpeechClient.create() } returns mockSpeechClient - + if (!useRealApi) { + mockSpeechClient = mockk(relaxed = true) + mockkStatic(SpeechClient::class) + every { SpeechClient.create() } returns mockSpeechClient + } speechToText = SpeechToText() } @After fun tearDown() { - unmockkAll() + if (!useRealApi) unmockkAll() } @Test - fun transcribeAudioToTextShouldReturnTemporaryFileWithTranscription() { + fun testTranscribeAudioToTextShouldReturnTemporaryFileWithTranscription() { + if (useRealApi) { + testTranscribeAudioToTextRealApi() + } else { + testTranscribeAudioToTextMock() + } + } + + private fun testTranscribeAudioToTextRealApi() { + val testFile = File("src/test/resources/sample_audio.wav") + require(testFile.exists()) { "Test audio file not found at ${testFile.absolutePath}" } + + val resultFile = speechToText.transcribeAudioToText(testFile) + assertNotNull(resultFile, "Result file should not be null") + assertTrue(resultFile.exists(), "Result file should exist") + println("Transcription result: ${resultFile.readText()}") + } + + private fun testTranscribeAudioToTextMock() { val mockAudioFile = mockk(relaxed = true) val mockAudioBytes = "test audio bytes".toByteArray() every { mockAudioFile.readBytes() } returns mockAudioBytes - // Mock SpeechClient response val mockRecognitionAudio = RecognitionAudio.newBuilder() .setContent(com.google.protobuf.ByteString.copyFrom(mockAudioBytes)) @@ -78,16 +96,9 @@ class SpeechToTextTest { val mockResponse = RecognizeResponse.newBuilder().addResults(mockResult).build() every { mockSpeechClient.recognize(mockConfig, mockRecognitionAudio) } returns mockResponse - var resultFile: File? = null - try { - resultFile = speechToText.transcribeAudioToText(mockAudioFile) - - assertNotNull(resultFile, "Result file should not be null") - assertTrue(resultFile.exists(), "Result file should exist") - assertEquals("Hello World", resultFile.readText(), "Transcription content should match") - } finally { - resultFile?.delete() - assertTrue(resultFile?.exists() == false, "Result file should be deleted") - } + val resultFile = speechToText.transcribeAudioToText(mockAudioFile) + assertNotNull(resultFile, "Result file should not be null") + assertTrue(resultFile.exists(), "Result file should exist") + assertEquals("Hello World", resultFile.readText(), "Transcription content should match") } } diff --git a/android/quest/src/test/java/org/smartregister/fhircore/quest/ui/speechtoform/TextToFormTest.kt b/android/quest/src/test/java/org/smartregister/fhircore/quest/ui/speechtoform/TextToFormTest.kt index 6546c22858..a956f91947 100644 --- a/android/quest/src/test/java/org/smartregister/fhircore/quest/ui/speechtoform/TextToFormTest.kt +++ b/android/quest/src/test/java/org/smartregister/fhircore/quest/ui/speechtoform/TextToFormTest.kt @@ -34,21 +34,44 @@ class TextToFormTest { private lateinit var textToForm: TextToForm private lateinit var mockGenerativeModel: GenerativeModel + private val useRealApi = System.getProperty("USE_REAL_API")?.toBoolean() ?: false @Before fun setUp() { - // Initialize the TextToForm instance and mock dependencies - mockGenerativeModel = mockk(relaxed = true) - textToForm = TextToForm(mockGenerativeModel) + if (!useRealApi) { + mockGenerativeModel = mockk(relaxed = true) + textToForm = TextToForm(mockGenerativeModel) + } else { + val geminiModel = GeminiModel() + textToForm = TextToForm(geminiModel.getModel()) + } } @After fun tearDown() { - unmockkAll() + if (!useRealApi) unmockkAll() } @Test - fun generateQuestionnaireResponseShouldReturnQuestionnaireResponse() = runTest { + fun testGenerateQuestionnaireResponseShouldReturnQuestionnaireResponse() = runTest { + if (useRealApi) { + testGenerateQuestionnaireResponseRealApi() + } else { + testGenerateQuestionnaireResponseMock() + } + } + + private suspend fun testGenerateQuestionnaireResponseRealApi() { + val testFile = File("src/test/resources/sample_transcript.txt") + require(testFile.exists()) { "Test transcript file not found at ${testFile.absolutePath}" } + val mockQuestionnaire = Questionnaire() + + val result = textToForm.generateQuestionnaireResponse(testFile, mockQuestionnaire) + assertNotNull(result, "QuestionnaireResponse should not be null") + println("Generated QuestionnaireResponse: ${result.id}") + } + + private suspend fun testGenerateQuestionnaireResponseMock() { val mockTranscriptFile = mockk(relaxed = true) val mockQuestionnaire = mockk(relaxed = true) val mockResponseJson = "{'id': '123'}" // Mock JSON response @@ -58,7 +81,6 @@ class TextToFormTest { mockk { every { text } returns "```json\n$mockResponseJson\n```" } val result = textToForm.generateQuestionnaireResponse(mockTranscriptFile, mockQuestionnaire) - assertNotNull(result, "QuestionnaireResponse should not be null") assertEquals("123", result.id, "QuestionnaireResponse ID should match") }