Skip to content

Commit

Permalink
feat: Translation history - Backend
Browse files Browse the repository at this point in the history
  • Loading branch information
JanCizmar committed Mar 17, 2022
1 parent cedd6c3 commit c7c4312
Show file tree
Hide file tree
Showing 46 changed files with 312 additions and 88 deletions.
1 change: 1 addition & 0 deletions backend/app/build.gradle
Expand Up @@ -54,6 +54,7 @@ allOpen {
annotation("org.springframework.stereotype.Service")
annotation("org.springframework.transaction.annotation.Transactional")
annotation("org.springframework.beans.factory.annotation.Configurable")
annotation("org.springframework.boot.test.context.SpringBootTest")
}

compileKotlin {
Expand Down
Expand Up @@ -36,7 +36,9 @@ import io.tolgee.service.ProjectService
import io.tolgee.service.UserAccountService
import org.springdoc.api.annotations.ParameterObject
import org.springframework.data.domain.Pageable
import org.springframework.data.domain.Sort
import org.springframework.data.web.PagedResourcesAssembler
import org.springframework.data.web.SortDefault
import org.springframework.hateoas.CollectionModel
import org.springframework.hateoas.MediaTypes
import org.springframework.hateoas.PagedModel
Expand Down Expand Up @@ -141,7 +143,7 @@ class OrganizationController(
@Operation(summary = "Returns all users in organization")
fun getAllUsers(
@PathVariable("id") id: Long,
@ParameterObject pageable: Pageable,
@ParameterObject @SortDefault(sort = ["name"], direction = Sort.Direction.ASC) pageable: Pageable,
@RequestParam("search") search: String?
): PagedModel<UserAccountWithOrganizationRoleModel> {
organizationRoleService.checkUserIsMemberOrOwner(id)
Expand Down
Expand Up @@ -96,7 +96,6 @@ class V2ProjectsController(
private val invitationService: InvitationService,
private val organizationService: OrganizationService,
private val organizationRoleService: OrganizationRoleService,
private val projectMachineTranslationServiceConfigService: MtServiceConfigService,
private val imageUploadService: ImageUploadService,
private val mtServiceConfigService: MtServiceConfigService,
private val autoTranslateService: AutoTranslationService
Expand Down
Expand Up @@ -13,6 +13,8 @@ import io.swagger.v3.oas.annotations.tags.Tags
import io.tolgee.api.v2.hateoas.translations.KeysWithTranslationsPageModel
import io.tolgee.api.v2.hateoas.translations.KeysWithTranslationsPagedResourcesAssembler
import io.tolgee.api.v2.hateoas.translations.SetTranslationsResponseModel
import io.tolgee.api.v2.hateoas.translations.TranslationHistoryModel
import io.tolgee.api.v2.hateoas.translations.TranslationHistoryModelAssembler
import io.tolgee.api.v2.hateoas.translations.TranslationModel
import io.tolgee.api.v2.hateoas.translations.TranslationModelAssembler
import io.tolgee.controllers.IController
Expand Down Expand Up @@ -45,7 +47,6 @@ import io.tolgee.service.query_builders.CursorUtil
import org.springdoc.api.annotations.ParameterObject
import org.springframework.data.domain.Pageable
import org.springframework.data.web.PagedResourcesAssembler
import org.springframework.hateoas.EntityModel
import org.springframework.hateoas.PagedModel
import org.springframework.web.bind.annotation.CrossOrigin
import org.springframework.web.bind.annotation.GetMapping
Expand Down Expand Up @@ -77,6 +78,7 @@ class V2TranslationsController(
private val keyService: KeyService,
private val pagedAssembler: KeysWithTranslationsPagedResourcesAssembler,
private val historyPagedAssembler: PagedResourcesAssembler<TranslationHistoryView>,
private val translationHistoryModelAssembler: TranslationHistoryModelAssembler,
private val translationModelAssembler: TranslationModelAssembler,
private val languageService: LanguageService,
private val securityService: SecurityService,
Expand Down Expand Up @@ -216,17 +218,19 @@ Sorting is not supported for supported. It is automatically sorted from newest t
fun getTranslationHistory(
@PathVariable translationId: Long,
@ParameterObject pageable: Pageable
): PagedModel<EntityModel<TranslationHistoryView>> {
): PagedModel<TranslationHistoryModel> {
val translation = translationService.get(translationId)
translation.checkFromProject()
val translations = translationService.getHistory(translationId, pageable)
return historyPagedAssembler.toModel(translations)
return historyPagedAssembler.toModel(translations, translationHistoryModelAssembler)
}

private fun getKeysWithScreenshots(keyIds: Collection<Long>): Map<Long, MutableSet<Screenshot>>? {
if (
!authenticationFacade.isApiKeyAuthentication ||
authenticationFacade.apiKey.scopesEnum.contains(ApiScope.SCREENSHOTS_VIEW)
) {
return screenshotService.getKeysWithScreenshots(keyIds).map { it.id to it.screenshots }.toMap()
return screenshotService.getKeysWithScreenshots(keyIds).associate { it.id to it.screenshots }
}
return null
}
Expand Down
Expand Up @@ -9,7 +9,7 @@ import org.springframework.hateoas.RepresentationModel
import org.springframework.hateoas.server.core.Relation

@Suppress("unused")
@Relation(collectionRelation = "translations", itemRelation = "translation")
@Relation(collectionRelation = "revisions", itemRelation = "revision")
open class TranslationHistoryModel(
@Schema(description = "Translation text")
val text: String?,
Expand Down
6 changes: 4 additions & 2 deletions backend/app/src/test/kotlin/io/tolgee/AuthTest.kt
Expand Up @@ -9,7 +9,7 @@ import io.tolgee.security.third_party.GithubOAuthDelegate.GithubEmailResponse
import io.tolgee.security.third_party.GithubOAuthDelegate.GithubUserResponse
import io.tolgee.testing.AbstractControllerTest
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.kotlin.any
import org.mockito.kotlin.eq
Expand All @@ -24,9 +24,11 @@ import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.MvcResult
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.setup.MockMvcBuilders
import org.springframework.transaction.annotation.Transactional
import org.springframework.web.client.RestTemplate
import java.util.*

@Transactional
class AuthTest : AbstractControllerTest() {
@Autowired
private val publicController: PublicController? = null
Expand All @@ -36,7 +38,7 @@ class AuthTest : AbstractControllerTest() {
private val restTemplate: RestTemplate? = null
private var authMvc: MockMvc? = null

@BeforeAll
@BeforeEach
fun setup() {
dbPopulator.createBase(generateUniqueString())
authMvc = MockMvcBuilders.standaloneSetup(publicController).setControllerAdvice(ExceptionHandlers()).build()
Expand Down
Expand Up @@ -14,8 +14,10 @@ import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.test.mock.mockito.SpyBean
import org.springframework.core.io.Resource
import org.springframework.transaction.annotation.Transactional

@Suppress("LateinitVarOverridesLateinitVar")
@Transactional
class StartupImportCommandLineRunnerTest : AbstractSpringTest() {

@Value("classpath:startup-import")
Expand Down
Expand Up @@ -24,6 +24,7 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMock
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.data.domain.PageRequest
import org.springframework.data.repository.findByIdOrNull
import org.springframework.transaction.annotation.Transactional

@SpringBootTest
@AutoConfigureMockMvc
Expand Down Expand Up @@ -109,8 +110,8 @@ class OrganizationControllerTest : AuthorizedControllerTest() {
.also { println(it.andReturn().response.contentAsString) }
.andAssertThatJson.node("_embedded.usersInOrganization").also {
it.isArray.hasSize(2)
it.node("[0].organizationRole").isEqualTo("OWNER")
it.node("[1].organizationRole").isEqualTo("MEMBER")
it.node("[0].organizationRole").isEqualTo("MEMBER")
it.node("[1].organizationRole").isEqualTo("OWNER")
}
}

Expand Down Expand Up @@ -304,6 +305,7 @@ class OrganizationControllerTest : AuthorizedControllerTest() {
}

@Test
@Transactional
fun testSetUserRole() {
this.organizationService.create(dummyDto, userAccount!!).let { organization ->
dbPopulator.createUserIfNotExists("superuser").let { createdUser ->
Expand Down
Expand Up @@ -13,8 +13,10 @@ import io.tolgee.testing.annotations.ProjectJWTAuthTestMethod
import io.tolgee.testing.assertions.Assertions.assertThat
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.springframework.transaction.annotation.Transactional
import java.math.BigDecimal

@Transactional
class TagsControllerTest : ProjectAuthControllerTest("/v2/projects/") {

lateinit var testData: TagsTestData
Expand Down
Expand Up @@ -14,15 +14,13 @@ import io.tolgee.testing.assertions.Assertions.assertThat
import net.javacrumbs.jsonunit.assertj.assertThatJson
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Test
import org.springframework.test.annotation.DirtiesContext
import org.springframework.test.web.servlet.MvcResult
import org.springframework.transaction.annotation.Transactional
import java.io.ByteArrayInputStream
import java.util.zip.ZipInputStream
import kotlin.system.measureTimeMillis

@ContextRecreatingTest
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS)
class V2ExportControllerTest : ProjectAuthControllerTest("/v2/projects/") {
lateinit var testData: TranslationsTestData

Expand Down
@@ -0,0 +1,118 @@
package io.tolgee.api.v2.controllers.translations.v2TranslationsController

import io.tolgee.controllers.ProjectAuthControllerTest
import io.tolgee.dtos.request.translation.SetTranslationsWithKeyDto
import io.tolgee.fixtures.andAssertThatJson
import io.tolgee.fixtures.andIsOk
import io.tolgee.fixtures.andPrettyPrint
import io.tolgee.fixtures.node
import io.tolgee.model.Permission
import io.tolgee.model.Project
import io.tolgee.model.UserAccount
import io.tolgee.model.translation.Translation
import io.tolgee.testing.annotations.ProjectJWTAuthTestMethod
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import java.util.*

@SpringBootTest
@AutoConfigureMockMvc
class V2TranslationsControllerHistoryTest : ProjectAuthControllerTest("/v2/projects/") {

lateinit var translation: Translation

lateinit var testUser: UserAccount
lateinit var testProject: Project

@BeforeEach
fun setup() {
testDataService.saveTestData {
addUserAccount {
username = "franta"
name = "Frantisek"
testUser = this
}.build buildUser@{
setAvatar("e2eTestResources/avatars/png_avatar.png")
addProject {
name = "Project"
userAccount = this@buildUser.self
testProject = this
}.build {
addPermission {
user = this@buildUser.self
type = Permission.ProjectPermissionType.TRANSLATE
project = testProject
}
val lang = addLanguage {
name = "Deutsch"
tag = "de"
}.self

addKey {
name = "yey"
}.build {
addTranslation {
language = lang
text = "Test text"
translation = this
}
}
}
}
}

userAccount = testUser
projectSupplier = { testProject }
}

@AfterEach
fun cleanup() {
projectService.deleteProject(project.id)
userAccountService.delete(userAccount!!)
}

@ProjectJWTAuthTestMethod
@Test
fun `returns history`() {
val testTranslation = translation
(1..20).forEach {
updateTranslation(testTranslation, "nt $it")
}

performProjectAuthGet("/translations/${testTranslation.id}/history").andPrettyPrint.andAssertThatJson {
node("_embedded.revisions") {
isArray.hasSize(20)
node("[0]") {
node("text").isEqualTo("nt 20")
node("state").isEqualTo("TRANSLATED")
node("auto").isEqualTo("false")
node("mtProvider").isEqualTo("null")
node("timestamp").isNumber.isLessThanOrEqualTo((Date().time * 1000).toBigDecimal())
node("revisionType").isEqualTo("MOD")
node("author") {
node("id").isNumber.isGreaterThan(0.toBigDecimal())
node("username").isEqualTo("franta")
node("name").isEqualTo("Frantisek")
node("avatar") {
node("large").isString.contains(".png")
node("thumbnail").isString.contains(".png")
}
}
}
}
node("page.totalElements").isEqualTo(21)
}
}

private fun updateTranslation(testTranslation: Translation, newText: String) {
performProjectAuthPut(
"/translations",
SetTranslationsWithKeyDto(
testTranslation.key.name, mutableMapOf(testTranslation.language.tag to newText)
)
).andIsOk
}
}
Expand Up @@ -25,8 +25,10 @@ import org.springframework.test.web.servlet.MvcResult
import org.springframework.test.web.servlet.RequestBuilder
import org.springframework.test.web.servlet.ResultActions
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.transaction.annotation.Transactional
import javax.servlet.DispatcherType

@Transactional
class V2ImportControllerAddFilesTest : AuthorizedControllerTest() {
@Value("classpath:import/zipOfJsons.zip")
lateinit var zipOfJsons: Resource
Expand Down
Expand Up @@ -17,9 +17,11 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMock
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.MediaType
import org.springframework.test.web.servlet.result.MockMvcResultMatchers
import org.springframework.transaction.annotation.Transactional

@SpringBootTest
@AutoConfigureMockMvc
@Transactional
class V2ProjectsControllerCreateTest : AuthorizedControllerTest() {
private val languageDTO = LanguageDto(
"English",
Expand Down
Expand Up @@ -20,7 +20,7 @@ import org.springframework.boot.test.context.SpringBootTest

@SpringBootTest
@AutoConfigureMockMvc
class V2ProjectsControllerTest : ProjectAuthControllerTest("/v2/projects/") {
open class V2ProjectsControllerTest : ProjectAuthControllerTest("/v2/projects/") {
@Test
fun getAll() {
dbPopulator.createBase("one", "kim")
Expand Down
Expand Up @@ -23,10 +23,12 @@ import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.mock.mockito.MockBean
import org.springframework.transaction.annotation.Transactional
import kotlin.system.measureTimeMillis

@SpringBootTest
@AutoConfigureMockMvc
@Transactional
class AutoTranslatingTest : ProjectAuthControllerTest("/v2/projects/"), MachineTranslationTest {

companion object {
Expand Down
@@ -1,6 +1,8 @@
package io.tolgee.configuration.tolgee

import io.tolgee.CleanDbBeforeClass
import io.tolgee.service.UserAccountService
import io.tolgee.testing.AbstractTransactionalTest
import io.tolgee.testing.ContextRecreatingTest
import io.tolgee.testing.assertions.Assertions.assertThat
import org.junit.jupiter.api.Test
Expand All @@ -15,7 +17,8 @@ import org.springframework.boot.test.context.SpringBootTest
"tolgee.authentication.jwtSecret=test_jwt_secret"
]
)
class AuthenticationPropertiesTest {
@CleanDbBeforeClass
class AuthenticationPropertiesTest : AbstractTransactionalTest() {
@set:Autowired
lateinit var tolgeeProperties: TolgeeProperties

Expand Down

0 comments on commit c7c4312

Please sign in to comment.