From 2a80b49082cb716205a73e3ee20361fa8ffc1e52 Mon Sep 17 00:00:00 2001 From: Mark Allen <3417310+maallen@users.noreply.github.com> Date: Mon, 21 Oct 2024 15:08:33 +0100 Subject: [PATCH] Added unit tests for third party ai translation push --- .../thirdparty/ThirdPartyTMSSmartling.java | 2 +- .../StubSmartlingResultProcessor.java | 8 + .../ThirdPartyTMSSmartlingTest.java | 339 ++++++++++++++++++ 3 files changed, 348 insertions(+), 1 deletion(-) diff --git a/webapp/src/main/java/com/box/l10n/mojito/service/thirdparty/ThirdPartyTMSSmartling.java b/webapp/src/main/java/com/box/l10n/mojito/service/thirdparty/ThirdPartyTMSSmartling.java index 72d3dd92f3..3c68d9eb1d 100644 --- a/webapp/src/main/java/com/box/l10n/mojito/service/thirdparty/ThirdPartyTMSSmartling.java +++ b/webapp/src/main/java/com/box/l10n/mojito/service/thirdparty/ThirdPartyTMSSmartling.java @@ -985,7 +985,7 @@ private SmartlingFile uploadAiTranslationFile( logger.debug("Process translation batch for file: {}", fileName); List fileBatch = batch; SmartlingFile file = new SmartlingFile(); - file.setFileName(fileName); + file.setFileName(fileName + "_" + localeTag); try { logger.debug("Save target file to: {}", file.getFileName()); diff --git a/webapp/src/test/java/com/box/l10n/mojito/service/thirdparty/StubSmartlingResultProcessor.java b/webapp/src/test/java/com/box/l10n/mojito/service/thirdparty/StubSmartlingResultProcessor.java index 1784fb21ca..7f7a6fe225 100644 --- a/webapp/src/test/java/com/box/l10n/mojito/service/thirdparty/StubSmartlingResultProcessor.java +++ b/webapp/src/test/java/com/box/l10n/mojito/service/thirdparty/StubSmartlingResultProcessor.java @@ -10,6 +10,7 @@ public class StubSmartlingResultProcessor extends SmartlingResultProcessor { List pushFiles = new ArrayList<>(); List pushTranslationFiles = new ArrayList<>(); + List pushAITranslationFiles = new ArrayList<>(); SmartlingOptions options; public StubSmartlingResultProcessor() {} @@ -27,4 +28,11 @@ public String processPushTranslations(List files, SmartlingOption this.options = options; return ""; } + + @Override + public String processPushAiTranslations(List files, SmartlingOptions options) { + this.pushAITranslationFiles = files; + this.options = options; + return ""; + } } diff --git a/webapp/src/test/java/com/box/l10n/mojito/service/thirdparty/ThirdPartyTMSSmartlingTest.java b/webapp/src/test/java/com/box/l10n/mojito/service/thirdparty/ThirdPartyTMSSmartlingTest.java index aa73d536a4..6f942d0dc0 100644 --- a/webapp/src/test/java/com/box/l10n/mojito/service/thirdparty/ThirdPartyTMSSmartlingTest.java +++ b/webapp/src/test/java/com/box/l10n/mojito/service/thirdparty/ThirdPartyTMSSmartlingTest.java @@ -30,6 +30,8 @@ import com.box.l10n.mojito.entity.Repository; import com.box.l10n.mojito.entity.TM; import com.box.l10n.mojito.entity.TMTextUnit; +import com.box.l10n.mojito.entity.TMTextUnitVariant; +import com.box.l10n.mojito.entity.ThirdPartyTextUnit; import com.box.l10n.mojito.json.ObjectMapper; import com.box.l10n.mojito.quartz.QuartzJobInfo; import com.box.l10n.mojito.quartz.QuartzPollableTaskScheduler; @@ -159,6 +161,8 @@ public class ThirdPartyTMSSmartlingTest extends ServiceTestBase { @Autowired QuartzSchedulerManager schedulerManager; + @Autowired ThirdPartyTextUnitRepository thirdPartyTextUnitRepository; + StubSmartlingResultProcessor resultProcessor; @Mock TextUnitBatchImporterService mockTextUnitBatchImporterService; @@ -169,6 +173,8 @@ public class ThirdPartyTMSSmartlingTest extends ServiceTestBase { @Captor ArgumentCaptor> textUnitListCaptor; + @Captor ArgumentCaptor> variantIdsCaptor; + @Captor ArgumentCaptor> quartzJobInfoCaptor; @@ -205,6 +211,7 @@ public void setUp() throws SchedulerException { anyString(), anyString(), anyString(), + anyString(), anyString()); doReturn(null) .when(mockTextUnitBatchImporterService) @@ -1734,6 +1741,338 @@ public void testBatchesFor() { assertThat(tmsSmartling.batchesFor(21156)).isEqualTo(6); } + @Test + public void testPushAiTranslationsSingleFile() throws Exception { + List result; + Repository repository = + repositoryService.createRepository(testIdWatcher.getEntityName("pushAiTranslationsRepo")); + Locale frCA = localeService.findByBcp47Tag("fr-CA"); + Locale jaJP = localeService.findByBcp47Tag("ja-JP"); + repositoryService.addRepositoryLocale(repository, frCA.getBcp47Tag()); + repositoryService.addRepositoryLocale(repository, jaJP.getBcp47Tag()); + + PluralForm one = pluralFormService.findByPluralFormString("one"); + + TM tm = repository.getTm(); + Asset asset = + assetService.createAssetWithContent(repository.getId(), "fake_for_test", "fake for test"); + AssetExtraction assetExtraction = new AssetExtraction(); + assetExtraction.setAsset(asset); + assetExtraction = assetExtractionRepository.save(assetExtraction); + + int textUnits = 5; + + for (int i = 0; i < textUnits; i++) { + String name = "singular_message" + i; + String content = "Singular Message Test #" + i; + String comment = "Singular Comment" + i; + TMTextUnit textUnit = + tmService.addTMTextUnit(tm.getId(), asset.getId(), name, content, comment); + tmService.addTMTextUnitCurrentVariant( + textUnit.getId(), + frCA.getId(), + String.format("%s in %s", content, frCA.getBcp47Tag()), + "test comment", + TMTextUnitVariant.Status.MT_TRANSLATED); + tmService.addTMTextUnitCurrentVariant( + textUnit.getId(), + jaJP.getId(), + String.format("%s in %s", content, jaJP.getBcp47Tag()), + "test comment", + TMTextUnitVariant.Status.MT_TRANSLATED); + assetExtractionService.createAssetTextUnit(assetExtraction, name, content, comment); + + ThirdPartyTextUnit thirdPartyTextUnit = new ThirdPartyTextUnit(); + thirdPartyTextUnit.setTmTextUnit(textUnit); + thirdPartyTextUnit.setAsset(asset); + thirdPartyTextUnit.setUploadedFileUri("testSingularUploadedFileUri"); + thirdPartyTextUnitRepository.save(thirdPartyTextUnit); + } + + for (int i = 0; i < textUnits; i++) { + ZonedDateTime now = ZonedDateTime.now(); + String name = "plural_message" + i; + String content = "Plural Message Test #" + i; + String comment = "Plural Comment" + i; + String pluralFormOther = "plural_form_other" + i; + + TMTextUnit tu = + tmService.addTMTextUnit(tm, asset, name, content, comment, now, one, pluralFormOther); + assetExtractionService.createAssetTextUnit(assetExtraction, name, content, comment); + + tmService.addTMTextUnitCurrentVariant( + tu.getId(), + frCA.getId(), + String.format("%s in %s", content, frCA.getBcp47Tag()), + "test comment", + TMTextUnitVariant.Status.MT_TRANSLATED); + tmService.addTMTextUnitCurrentVariant( + tu.getId(), + jaJP.getId(), + String.format("%s in %s", content, jaJP.getBcp47Tag()), + "test comment", + TMTextUnitVariant.Status.MT_TRANSLATED); + + ThirdPartyTextUnit thirdPartyTextUnit = new ThirdPartyTextUnit(); + thirdPartyTextUnit.setTmTextUnit(tu); + thirdPartyTextUnit.setAsset(asset); + thirdPartyTextUnit.setUploadedFileUri("testPluralUploadedFileUri"); + thirdPartyTextUnitRepository.save(thirdPartyTextUnit); + } + + prepareAssetAndTextUnits(assetExtraction, asset, tm); + + tmsSmartling.pushAITranslations( + repository, + "projectId", + pluralSep, + ImmutableMap.of(), + null, + null, + null, + ImmutableList.of()); + result = resultProcessor.pushAITranslationFiles; + + assertThat(result).hasSize(4); + Stream.of(jaJP, frCA) + .forEach( + locale -> { + SmartlingFile singularFile = + result.stream() + .filter( + f -> + f.getFileName() + .matches("testSingularUploadedFileUri_" + locale.getBcp47Tag())) + .findFirst() + .get(); + + SmartlingFile pluralFile = + result.stream() + .filter( + f -> + f.getFileName() + .matches("testPluralUploadedFileUri_" + locale.getBcp47Tag())) + .findFirst() + .get(); + + assertThat(singularFile.getFileName()) + .isEqualTo("testSingularUploadedFileUri_" + locale.getBcp47Tag()); + List singulars = readTextUnits(singularFile, pluralSep); + assertThat(singulars) + .allSatisfy( + tu -> { + assertThat(tu.getComment()).startsWith("Singular Comment"); + assertThat(tu.getName()).startsWith("singular_message"); + assertThat(tu.getAssetPath()).isEqualTo("fake_for_test"); + assertThat(tu.getTarget()) + .matches("Singular Message Test #\\d in " + locale.getBcp47Tag()); + }); + + assertThat(pluralFile.getFileName()) + .isEqualTo("testPluralUploadedFileUri_" + locale.getBcp47Tag()); + List plurals = readTextUnits(pluralFile, pluralSep); + assertThat(plurals).hasSize(textUnits); + assertThat(plurals) + .allSatisfy( + tu -> { + assertThat(tu.getName()).endsWith("_one"); + assertThat(tu.getPluralForm()).isEqualTo("one"); + assertThat(tu.getTarget()) + .matches("Plural Message Test #\\d in " + locale.getBcp47Tag()); + }); + + verify(smartlingClient, times(1)) + .uploadLocalizedFile( + eq("projectId"), + eq("testSingularUploadedFileUri"), + eq("android"), + eq(locale.getBcp47Tag()), + startsWith(" result; + Repository repository = + repositoryService.createRepository(testIdWatcher.getEntityName("pushAiTranslationsRepo")); + Locale frCA = localeService.findByBcp47Tag("fr-CA"); + Locale jaJP = localeService.findByBcp47Tag("ja-JP"); + repositoryService.addRepositoryLocale(repository, frCA.getBcp47Tag()); + repositoryService.addRepositoryLocale(repository, jaJP.getBcp47Tag()); + + PluralForm one = pluralFormService.findByPluralFormString("one"); + + TM tm = repository.getTm(); + Asset asset = + assetService.createAssetWithContent(repository.getId(), "fake_for_test", "fake for test"); + AssetExtraction assetExtraction = new AssetExtraction(); + assetExtraction.setAsset(asset); + assetExtraction = assetExtractionRepository.save(assetExtraction); + + int textUnits = 5; + + for (int i = 0; i < textUnits; i++) { + String name = "singular_message" + i; + String content = "Singular Message Test #" + i; + String comment = "Singular Comment" + i; + TMTextUnit textUnit = + tmService.addTMTextUnit(tm.getId(), asset.getId(), name, content, comment); + tmService.addTMTextUnitCurrentVariant( + textUnit.getId(), + frCA.getId(), + String.format("%s in %s", content, frCA.getBcp47Tag()), + "test comment", + TMTextUnitVariant.Status.MT_TRANSLATED); + tmService.addTMTextUnitCurrentVariant( + textUnit.getId(), + jaJP.getId(), + String.format("%s in %s", content, jaJP.getBcp47Tag()), + "test comment", + TMTextUnitVariant.Status.MT_TRANSLATED); + assetExtractionService.createAssetTextUnit(assetExtraction, name, content, comment); + + ThirdPartyTextUnit thirdPartyTextUnit = new ThirdPartyTextUnit(); + thirdPartyTextUnit.setTmTextUnit(textUnit); + thirdPartyTextUnit.setAsset(asset); + thirdPartyTextUnit.setUploadedFileUri("testSingularUploadedFileUri_" + i); + thirdPartyTextUnitRepository.save(thirdPartyTextUnit); + } + + for (int i = 0; i < textUnits; i++) { + ZonedDateTime now = ZonedDateTime.now(); + String name = "plural_message" + i; + String content = "Plural Message Test #" + i; + String comment = "Plural Comment" + i; + String pluralFormOther = "plural_form_other" + i; + + TMTextUnit tu = + tmService.addTMTextUnit(tm, asset, name, content, comment, now, one, pluralFormOther); + assetExtractionService.createAssetTextUnit(assetExtraction, name, content, comment); + + tmService.addTMTextUnitCurrentVariant( + tu.getId(), + frCA.getId(), + String.format("%s in %s", content, frCA.getBcp47Tag()), + "test comment", + TMTextUnitVariant.Status.MT_TRANSLATED); + tmService.addTMTextUnitCurrentVariant( + tu.getId(), + jaJP.getId(), + String.format("%s in %s", content, jaJP.getBcp47Tag()), + "test comment", + TMTextUnitVariant.Status.MT_TRANSLATED); + + ThirdPartyTextUnit thirdPartyTextUnit = new ThirdPartyTextUnit(); + thirdPartyTextUnit.setTmTextUnit(tu); + thirdPartyTextUnit.setAsset(asset); + thirdPartyTextUnit.setUploadedFileUri("testPluralUploadedFileUri_" + i); + thirdPartyTextUnitRepository.save(thirdPartyTextUnit); + } + + prepareAssetAndTextUnits(assetExtraction, asset, tm); + + tmsSmartling.pushAITranslations( + repository, + "projectId", + pluralSep, + ImmutableMap.of(), + null, + null, + null, + ImmutableList.of()); + result = resultProcessor.pushAITranslationFiles; + + assertThat(result).hasSize(20); + Stream.of(jaJP, frCA) + .forEach( + locale -> { + SmartlingFile singularFile = + result.stream() + .filter( + f -> + f.getFileName().startsWith("testSingularUploadedFileUri_") + && f.getFileName().endsWith(locale.getBcp47Tag())) + .findFirst() + .get(); + + SmartlingFile pluralFile = + result.stream() + .filter( + f -> + f.getFileName().startsWith("testPluralUploadedFileUri_") + && f.getFileName().endsWith(locale.getBcp47Tag())) + .findFirst() + .get(); + + assertThat(singularFile.getFileName()) + .containsPattern("testSingularUploadedFileUri_[0-4]_" + locale.getBcp47Tag()); + assertThat(readTextUnits(singularFile, pluralSep)) + .allSatisfy( + tu -> { + assertThat(tu.getComment()).startsWith("Singular Comment"); + assertThat(tu.getName()).startsWith("singular_message"); + assertThat(tu.getAssetPath()).isEqualTo("fake_for_test"); + assertThat(tu.getTarget()) + .matches("Singular Message Test #\\d in " + locale.getBcp47Tag()); + }); + + assertThat(pluralFile.getFileName()) + .containsPattern("testPluralUploadedFileUri_[0-4]_" + locale.getBcp47Tag()); + List plurals = readTextUnits(pluralFile, pluralSep); + assertThat(plurals).hasSize(1); + assertThat(plurals) + .allSatisfy( + tu -> { + assertThat(tu.getName()).endsWith("_one"); + assertThat(tu.getPluralForm()).isEqualTo("one"); + assertThat(tu.getTarget()) + .matches("Plural Message Test #\\d in " + locale.getBcp47Tag()); + }); + for (int i = 0; i < textUnits; i++) { + verify(smartlingClient, times(1)) + .uploadLocalizedFile( + eq("projectId"), + eq("testSingularUploadedFileUri_" + i), + eq("android"), + eq(locale.getBcp47Tag()), + startsWith(" searchTextUnits(List ids) { TextUnitSearcherParameters params = new TextUnitSearcherParameters(); params.setTmTextUnitIds(ids);