From 59c5263ad05441668f8d4b40361d0cb0194bcf8d Mon Sep 17 00:00:00 2001 From: Elena_Moshnikova Date: Sat, 23 Nov 2024 12:59:14 +0300 Subject: [PATCH] 2647 manage voices --- .../com/epam/brn/dto/AudioFileMetaData.kt | 2 +- src/main/kotlin/com/epam/brn/enums/Voice.kt | 2 + .../service/impl/UserAnalyticsServiceImpl.kt | 24 +++++- .../brn/service/UserAnalyticsServiceTest.kt | 76 +++++++++++++++---- src/test/resources/application.properties | 2 +- 5 files changed, 87 insertions(+), 19 deletions(-) diff --git a/src/main/kotlin/com/epam/brn/dto/AudioFileMetaData.kt b/src/main/kotlin/com/epam/brn/dto/AudioFileMetaData.kt index 34b51687d..f682af83a 100644 --- a/src/main/kotlin/com/epam/brn/dto/AudioFileMetaData.kt +++ b/src/main/kotlin/com/epam/brn/dto/AudioFileMetaData.kt @@ -5,7 +5,7 @@ import com.epam.brn.dto.azure.tts.AzureRates data class AudioFileMetaData( var text: String, val locale: String, - val voice: String, + var voice: String, var speedFloat: String = "1", var speedCode: AzureRates = AzureRates.DEFAULT, val gender: String? = null, diff --git a/src/main/kotlin/com/epam/brn/enums/Voice.kt b/src/main/kotlin/com/epam/brn/enums/Voice.kt index 2c98aebea..ebabad909 100644 --- a/src/main/kotlin/com/epam/brn/enums/Voice.kt +++ b/src/main/kotlin/com/epam/brn/enums/Voice.kt @@ -5,6 +5,8 @@ enum class Voice { NICK, ERKANYAVAS, OKSANA, + marina, + lera, ALYSS, SILAERKAN } diff --git a/src/main/kotlin/com/epam/brn/service/impl/UserAnalyticsServiceImpl.kt b/src/main/kotlin/com/epam/brn/service/impl/UserAnalyticsServiceImpl.kt index 919e691e3..398c9b5c3 100644 --- a/src/main/kotlin/com/epam/brn/service/impl/UserAnalyticsServiceImpl.kt +++ b/src/main/kotlin/com/epam/brn/service/impl/UserAnalyticsServiceImpl.kt @@ -4,7 +4,9 @@ import com.epam.brn.dto.AudioFileMetaData import com.epam.brn.dto.response.UserWithAnalyticsResponse import com.epam.brn.dto.statistics.DayStudyStatistics import com.epam.brn.enums.ExerciseType +import com.epam.brn.enums.Voice import com.epam.brn.model.StudyHistory +import com.epam.brn.model.UserAccount import com.epam.brn.repo.ExerciseRepository import com.epam.brn.repo.StudyHistoryRepository import com.epam.brn.repo.UserAccountRepository @@ -17,6 +19,7 @@ import com.epam.brn.service.statistics.UserPeriodStatisticsService import org.springframework.data.domain.Pageable import org.springframework.stereotype.Service import java.io.InputStream +import java.time.LocalDate import java.time.LocalTime import java.time.temporal.WeekFields import java.util.Locale @@ -72,20 +75,33 @@ class UserAnalyticsServiceImpl( ) override fun prepareAudioFileMetaData(exerciseId: Long, audioFileMetaData: AudioFileMetaData): AudioFileMetaData { - val currentUserId = userAccountService.getCurrentUserId() - val lastExerciseHistory = studyHistoryRepository - .findLastByUserAccountIdAndExerciseId(currentUserId, exerciseId) val seriesType = ExerciseType.valueOf(exerciseRepository.findTypeByExerciseId(exerciseId)) val text = audioFileMetaData.text if (!listTextExercises.contains(seriesType)) audioFileMetaData.text = text.replace(" ", ", ") + val currentUser = userAccountService.getCurrentUser() + audioFileMetaData.voice = choseVoiceForUser(currentUser) + setSpeedForUser(currentUser, exerciseId, audioFileMetaData) + return audioFileMetaData + } + + fun setSpeedForUser(user: UserAccount, exerciseId: Long, audioFileMetaData: AudioFileMetaData) { + val lastExerciseHistory = studyHistoryRepository + .findLastByUserAccountIdAndExerciseId(user.id!!, exerciseId) if (lastExerciseHistory == null) audioFileMetaData.setSpeedNormal() else if (isDoneBad(lastExerciseHistory)) audioFileMetaData.setSpeedSlow() else if (isDoneWell(lastExerciseHistory)) audioFileMetaData.setSpeedFaster() - return audioFileMetaData + } + + fun choseVoiceForUser(user: UserAccount): String { + if (user.bornYear == null) + return Voice.marina.name + val ages = LocalDate.now().year - user.bornYear!! + return if (ages < 19) Voice.marina.name + else Voice.lera.name } fun isDoneBad(lastHistory: StudyHistory?): Boolean = diff --git a/src/test/kotlin/com/epam/brn/service/UserAnalyticsServiceTest.kt b/src/test/kotlin/com/epam/brn/service/UserAnalyticsServiceTest.kt index ccaec2986..8bfab974a 100644 --- a/src/test/kotlin/com/epam/brn/service/UserAnalyticsServiceTest.kt +++ b/src/test/kotlin/com/epam/brn/service/UserAnalyticsServiceTest.kt @@ -119,7 +119,10 @@ internal class UserAnalyticsServiceTest { fun `should prepareAudioFileMetaData with adding comma and slow speed for words with good stat WORDS`() { // GIVEN val studyHistory = mockk() - every { userAccountService.getCurrentUserId() } returns currentUserId + val currentUser = mockk() + every { userAccountService.getCurrentUser() } returns currentUser + every { currentUser.bornYear } returns 2023 + every { currentUser.id } returns currentUserId every { studyHistoryRepository.findLastByUserAccountIdAndExerciseId(currentUserId, exerciseId) } returns studyHistory @@ -140,7 +143,10 @@ internal class UserAnalyticsServiceTest { fun `should prepareAudioFileMetaData without adding comma and slow speed for words with good stat PHRASES`() { // GIVEN val studyHistory = mockk() - every { userAccountService.getCurrentUserId() } returns currentUserId + val currentUser = mockk() + every { userAccountService.getCurrentUser() } returns currentUser + every { currentUser.bornYear } returns 2023 + every { currentUser.id } returns currentUserId every { studyHistoryRepository.findLastByUserAccountIdAndExerciseId(currentUserId, exerciseId) } returns studyHistory @@ -158,10 +164,13 @@ internal class UserAnalyticsServiceTest { } @Test - fun `should prepareAudioFileMetaData with adding comma and slowest speed for words with bad stat WORDS`() { + fun `should prepareAudioFileMetaData with adding comma and slowest speed for words with bad stat WORDS `() { // GIVEN val studyHistory = mockk() - every { userAccountService.getCurrentUserId() } returns currentUserId + val currentUser = mockk() + every { userAccountService.getCurrentUser() } returns currentUser + every { currentUser.bornYear } returns 2023 + every { currentUser.id } returns currentUserId every { studyHistoryRepository.findLastByUserAccountIdAndExerciseId(currentUserId, exerciseId) } returns studyHistory @@ -177,13 +186,38 @@ internal class UserAnalyticsServiceTest { metaDataResult.speedFloat shouldBe "0.8" metaDataResult.speedCode shouldBe AzureRates.SLOW metaDataResult.text shouldBe "мама, папа" + metaDataResult.voice shouldBe Voice.marina.name + } + + @Test + fun `should prepareAudioFileMetaData with lera voice up to 18 years old user`() { + // GIVEN + val studyHistory = mockk() + val currentUser = mockk() + every { userAccountService.getCurrentUser() } returns currentUser + every { currentUser.bornYear } returns 2000 + every { currentUser.id } returns currentUserId + every { + studyHistoryRepository.findLastByUserAccountIdAndExerciseId(currentUserId, exerciseId) + } returns studyHistory + every { exerciseService.isDoneWell(studyHistory) } returns true + every { exerciseRepository.findTypeByExerciseId(exerciseId) } returns ExerciseType.SINGLE_SIMPLE_WORDS.name + val audioFileMetaData = + AudioFileMetaData("мама папа", BrnLocale.RU.locale, "", "1", AzureRates.DEFAULT) + // WHEN + val metaDataResult = userAnalyticsService.prepareAudioFileMetaData(exerciseId, audioFileMetaData) + // THEN + metaDataResult.voice shouldBe Voice.lera.name } @Test fun `should prepareAudioFileMetaData without adding comma and slowest speed for words with bad stat PHRASES`() { // GIVEN val studyHistory = mockk() - every { userAccountService.getCurrentUserId() } returns currentUserId + val currentUser = mockk() + every { userAccountService.getCurrentUser() } returns currentUser + every { currentUser.bornYear } returns 2023 + every { currentUser.id } returns currentUserId every { studyHistoryRepository.findLastByUserAccountIdAndExerciseId(currentUserId, exerciseId) } returns studyHistory @@ -205,13 +239,17 @@ internal class UserAnalyticsServiceTest { fun `should prepareAudioFileMetaData default speed correctly for one word and good statistics`() { // GIVEN val studyHistory = mockk() - every { userAccountService.getCurrentUserId() } returns currentUserId + val currentUser = mockk() + every { userAccountService.getCurrentUser() } returns currentUser + every { currentUser.bornYear } returns 2023 + every { currentUser.id } returns currentUserId every { studyHistoryRepository.findLastByUserAccountIdAndExerciseId(currentUserId, exerciseId) } returns studyHistory every { exerciseService.isDoneWell(studyHistory) } returns true every { exerciseRepository.findTypeByExerciseId(exerciseId) } returns ExerciseType.SINGLE_SIMPLE_WORDS.name - val audioFileMetaData = AudioFileMetaData("мама", BrnLocale.RU.locale, Voice.FILIPP.name, "1", AzureRates.DEFAULT) + val audioFileMetaData = + AudioFileMetaData("мама", BrnLocale.RU.locale, Voice.FILIPP.name, "1", AzureRates.DEFAULT) // WHEN val metaDataResult = userAnalyticsService.prepareAudioFileMetaData(exerciseId, audioFileMetaData) @@ -226,13 +264,17 @@ internal class UserAnalyticsServiceTest { fun `should prepareAudioFileMetaData slow correctly for single word and bad statistics`() { // GIVEN val studyHistory = mockk() - every { userAccountService.getCurrentUserId() } returns currentUserId + val currentUser = mockk() + every { userAccountService.getCurrentUser() } returns currentUser + every { currentUser.bornYear } returns 2023 + every { currentUser.id } returns currentUserId every { studyHistoryRepository.findLastByUserAccountIdAndExerciseId(currentUserId, exerciseId) } returns studyHistory every { exerciseService.isDoneWell(studyHistory) } returns false every { exerciseRepository.findTypeByExerciseId(exerciseId) } returns ExerciseType.SINGLE_SIMPLE_WORDS.name - val audioFileMetaData = AudioFileMetaData("text", BrnLocale.RU.locale, Voice.FILIPP.name, "1", AzureRates.DEFAULT) + val audioFileMetaData = + AudioFileMetaData("text", BrnLocale.RU.locale, Voice.FILIPP.name, "1", AzureRates.DEFAULT) // WHEN val metaDataResult = userAnalyticsService.prepareAudioFileMetaData(exerciseId, audioFileMetaData) @@ -245,12 +287,16 @@ internal class UserAnalyticsServiceTest { @Test fun `should prepareAudioFileMetaData normal speed for single word`() { // GIVEN - every { userAccountService.getCurrentUserId() } returns currentUserId + val currentUser = mockk() + every { userAccountService.getCurrentUser() } returns currentUser + every { currentUser.bornYear } returns 2023 + every { currentUser.id } returns currentUserId every { studyHistoryRepository.findLastByUserAccountIdAndExerciseId(currentUserId, exerciseId) } returns null every { exerciseRepository.findTypeByExerciseId(exerciseId) } returns ExerciseType.SINGLE_SIMPLE_WORDS.name - val audioFileMetaData = AudioFileMetaData("text", BrnLocale.RU.locale, Voice.FILIPP.name, "1", AzureRates.DEFAULT) + val audioFileMetaData = + AudioFileMetaData("text", BrnLocale.RU.locale, Voice.FILIPP.name, "1", AzureRates.DEFAULT) // WHEN val metaDataResult = userAnalyticsService.prepareAudioFileMetaData(exerciseId, audioFileMetaData) // THEN @@ -263,13 +309,17 @@ internal class UserAnalyticsServiceTest { // GIVEN val studyHistory = mockk() val audioStreamMock = InputStream.nullInputStream() - every { userAccountService.getCurrentUserId() } returns currentUserId + val currentUser = mockk() + every { userAccountService.getCurrentUser() } returns currentUser + every { currentUser.bornYear } returns 2023 + every { currentUser.id } returns currentUserId every { studyHistoryRepository.findLastByUserAccountIdAndExerciseId(currentUserId, exerciseId) } returns studyHistory every { exerciseService.isDoneWell(studyHistory) } returns false every { exerciseRepository.findTypeByExerciseId(exerciseId) } returns ExerciseType.SINGLE_SIMPLE_WORDS.name - val audioFileMetaData = AudioFileMetaData("text", BrnLocale.RU.locale, Voice.FILIPP.name, "1", AzureRates.DEFAULT) + val audioFileMetaData = + AudioFileMetaData("text", BrnLocale.RU.locale, Voice.FILIPP.name, "1", AzureRates.DEFAULT) every { textToSpeechService.generateAudioOggStreamWithValidation(audioFileMetaData) } returns audioStreamMock // WHEN val audioStreamResult = userAnalyticsService.prepareAudioStreamForUser(exerciseId, audioFileMetaData) diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index 6bd08dfd7..c90744a63 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -48,7 +48,7 @@ yandex.getTokenLink=https://iam.api.cloud.yandex.net/iam/v1/tokens yandex.generationAudioLink=https://tts.api.cloud.yandex.net/speech/v1/tts:synthesize yandex.folderId=b1gqn2760f5ongt82lm3 yandex.format=oggopus -yandex.emotions=good +yandex.emotions=friendly yandex.folderForFiles=audioTest brn.resources.default-pictures.path=pictures/