Skip to content

Commit a701505

Browse files
authored
fix: Translation can get into untranslated state when it has value (tolgee#1714)
1 parent 3341db2 commit a701505

File tree

4 files changed

+38
-8
lines changed

4 files changed

+38
-8
lines changed

backend/app/src/main/kotlin/io/tolgee/api/v2/controllers/translation/TranslationsController.kt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import io.tolgee.model.Language
3434
import io.tolgee.model.Permission
3535
import io.tolgee.model.Screenshot
3636
import io.tolgee.model.enums.ApiScope
37-
import io.tolgee.model.enums.TranslationState
37+
import io.tolgee.model.enums.AssignableTranslationState
3838
import io.tolgee.model.key.Key
3939
import io.tolgee.model.translation.Translation
4040
import io.tolgee.model.views.KeyWithTranslationsView
@@ -217,11 +217,14 @@ When null, resulting file will be a flat key-value object.
217217
@AccessWithProjectPermission(permission = Permission.ProjectPermissionType.TRANSLATE)
218218
@Operation(summary = "Sets translation state")
219219
@RequestActivity(ActivityType.SET_TRANSLATION_STATE)
220-
fun setTranslationState(@PathVariable translationId: Long, @PathVariable state: TranslationState): TranslationModel {
220+
fun setTranslationState(
221+
@PathVariable translationId: Long,
222+
@PathVariable state: AssignableTranslationState
223+
): TranslationModel {
221224
val translation = translationService.get(translationId)
222225
translation.checkFromProject()
223226
securityService.checkLanguageTranslatePermission(translation)
224-
return translationModelAssembler.toModel(translationService.setState(translation, state))
227+
return translationModelAssembler.toModel(translationService.setState(translation, state.translationState))
225228
}
226229

227230
@InitBinder("translationFilters")

backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/translations/v2TranslationsController/TranslationsControllerModificationTest.kt

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,17 +84,26 @@ class TranslationsControllerModificationTest : ProjectAuthControllerTest("/v2/pr
8484
fun `sets translation state`() {
8585
saveTestData()
8686
val id = testData.aKeyGermanTranslation.id
87-
performProjectAuthPut("/translations/$id/set-state/UNTRANSLATED", null).andIsOk
87+
performProjectAuthPut("/translations/$id/set-state/TRANSLATED", null).andIsOk
8888
.andAssertThatJson {
89-
node("state").isEqualTo("UNTRANSLATED")
89+
node("state").isEqualTo("TRANSLATED")
9090
node("id").isValidId.satisfies { id ->
9191
id.toLong().let {
92-
assertThat(translationService.find(it)?.state).isEqualTo(TranslationState.UNTRANSLATED)
92+
assertThat(translationService.find(it)?.state).isEqualTo(TranslationState.TRANSLATED)
9393
}
9494
}
9595
}
9696
}
9797

98+
@ProjectJWTAuthTestMethod
99+
@Test
100+
fun `cannot set UNTRANSLATED when contains value`() {
101+
saveTestData()
102+
val id = testData.aKeyGermanTranslation.id
103+
performProjectAuthPut("/translations/$id/set-state/UNTRANSLATED", null)
104+
.andIsBadRequest
105+
}
106+
98107
@ProjectApiKeyAuthTestMethod(scopes = [ApiScope.TRANSLATIONS_VIEW])
99108
@Test
100109
fun `sets translations for existing key API key forbidden`() {
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package io.tolgee.model.enums
2+
3+
enum class AssignableTranslationState(
4+
val translationState: TranslationState
5+
) {
6+
TRANSLATED(TranslationState.TRANSLATED),
7+
REVIEWED(TranslationState.REVIEWED),
8+
}

backend/data/src/main/kotlin/io/tolgee/model/translation/Translation.kt

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import javax.validation.constraints.NotNull
3434
]
3535
)
3636
@ActivityLoggedEntity
37-
@EntityListeners(Translation.Companion.UpdateStatsListener::class)
37+
@EntityListeners(Translation.Companion.UpdateStatsListener::class, Translation.Companion.StateListener::class)
3838
@ActivityEntityDescribingPaths(paths = ["key", "language"])
3939
class Translation(
4040
@Column(columnDefinition = "text")
@@ -93,10 +93,20 @@ class Translation(
9393
class UpdateStatsListener {
9494
@PrePersist
9595
@PreUpdate
96-
fun preRemove(translation: Translation) {
96+
fun preSave(translation: Translation) {
9797
translation.characterCount = TranslationStatsUtil.getCharacterCount(translation.text)
9898
translation.wordCount = TranslationStatsUtil.getWordCount(translation.text, translation.language.tag)
9999
}
100100
}
101+
102+
class StateListener {
103+
@PrePersist
104+
@PreUpdate
105+
fun preSave(translation: Translation) {
106+
if (!translation.text.isNullOrEmpty() && translation.state == TranslationState.UNTRANSLATED) {
107+
translation.state = TranslationState.TRANSLATED
108+
}
109+
}
110+
}
101111
}
102112
}

0 commit comments

Comments
 (0)