From c6ba65d8dabcd1820bb87e27aefb308778dd48cb Mon Sep 17 00:00:00 2001 From: Mark Allen <3417310+maallen@users.noreply.github.com> Date: Thu, 10 Aug 2023 11:47:09 +0100 Subject: [PATCH] Added unit tests to verify short circuit logic --- .../ThirdPartyTMSSmartlingTest.java | 265 ++++++++++++++++++ 1 file changed, 265 insertions(+) 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 b685285f5d..33540f7812 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 @@ -1213,6 +1213,271 @@ public void testPullDryRunNoBatches() throws RepositoryLocaleCreationException { .importTextUnits(textUnitListCaptor.capture(), eq(false), eq(true)); } + @Test + public void testPullShortCircuitIfNoChangesInTranslatedFiles() + throws RepositoryNameAlreadyUsedException, RepositoryLocaleCreationException { + + int batchSize = 3; + List tus; + List locales = new ArrayList<>(); + Map localeMapping = Collections.emptyMap(); + tmsSmartling = + new ThirdPartyTMSSmartling( + smartlingClient, + textUnitSearcher, + assetPathAndTextUnitNameKeys, + mockTextUnitBatchImporterService, + resultProcessor, + mockThirdPartyTMSSmartlingWithJson, + mockThirdPartyTMSSmartlingGlossary, + assetTextUnitToTMTextUnitRepository, + batchSize, + meterRegistry, + mockThirdPartyFileChecksumRepository); + Repository repository = + repositoryService.createRepository(testIdWatcher.getEntityName("batchRepo")); + Locale frCA = localeService.findByBcp47Tag("fr-CA"); + Locale jaJP = localeService.findByBcp47Tag("ja-JP"); + repositoryService.addRepositoryLocale(repository, frCA.getBcp47Tag()); + repositoryService.addRepositoryLocale(repository, jaJP.getBcp47Tag()); + locales.add(frCA); + locales.add(jaJP); + + 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); + + PluralForm one = pluralFormService.findByPluralFormString("one"); + + List singularIds = new ArrayList<>(); + int singularTextUnits = 14; + int singularBatches = 5; + + for (int i = 0; i < singularTextUnits; i++) { + String name = "singular_message_test" + i; + String content = "Singular Message Test #" + i; + String comment = "Singular Comment" + i; + TMTextUnit textUnit = + tmService.addTMTextUnit(tm.getId(), asset.getId(), name, content, comment); + singularIds.add(textUnit.getId()); + assetExtractionService.createAssetTextUnit(assetExtraction, name, content, comment); + } + + List pluralIds = new ArrayList<>(); + int pluralTextUnits = 8; + int pluralBatches = 3; + + for (int i = 0; i < pluralTextUnits; i++) { + String name = "plural_message" + i + "_one"; + String content = "Plural Message Test #" + i; + String comment = "Plural Comment" + i; + String pluralFormOther = "plural_form_other" + i; + + TMTextUnit textUnit = + tmService.addTMTextUnit(tm, asset, name, content, comment, null, one, pluralFormOther); + pluralIds.add(textUnit.getId()); + assetExtractionService.createAssetTextUnit(assetExtraction, name, content, comment); + } + + prepareAssetAndTextUnits(assetExtraction, asset, tm); + + tus = searchTextUnits(singularIds); + Iterable> singularIt = Iterables.partition(tus, batchSize); + int i = 0; + for (List textUnits : singularIt) { + for (Locale l : locales) { + doReturn(localizedContent(textUnits, l)) + .when(smartlingClient) + .downloadPublishedFile( + eq("projectId"), + eq(l.getBcp47Tag()), + eq(singularFileName(repository, i)), + eq(false)); + } + i++; + } + + tus = searchTextUnits(pluralIds); + Iterable> pluralIt = Iterables.partition(tus, batchSize); + i = 0; + for (List textUnits : pluralIt) { + for (Locale l : locales) { + doReturn(localizedContent(textUnits, l)) + .when(smartlingClient) + .downloadPublishedFile( + eq("projectId"), eq(l.getBcp47Tag()), eq(pluralFileName(repository, i)), eq(false)); + } + i++; + } + + // Execute an initial pull that will record translated files checksums and verify text units are + // imported + tmsSmartling.pull( + repository, "projectId", pluralSep, localeMapping, null, null, Collections.emptyList()); + + verify(mockTextUnitBatchImporterService, atLeastOnce()) + .importTextUnits(textUnitListCaptor.capture(), eq(false), eq(true)); + + Mockito.clearInvocations(mockTextUnitBatchImporterService); + + // Now run the same pull again, text unit imports should be skipped as file checksums from + // previous run exist and match. + tmsSmartling.pull( + repository, "projectId", pluralSep, localeMapping, null, null, Collections.emptyList()); + + verify(mockTextUnitBatchImporterService, times(0)) + .importTextUnits(textUnitListCaptor.capture(), eq(false), eq(true)); + } + + @Test + public void testPullShortCircuitIfChangesInTranslatedFiles() + throws RepositoryNameAlreadyUsedException, RepositoryLocaleCreationException { + + int batchSize = 3; + List tus; + List locales = new ArrayList<>(); + Map localeMapping = Collections.emptyMap(); + tmsSmartling = + new ThirdPartyTMSSmartling( + smartlingClient, + textUnitSearcher, + assetPathAndTextUnitNameKeys, + mockTextUnitBatchImporterService, + resultProcessor, + mockThirdPartyTMSSmartlingWithJson, + mockThirdPartyTMSSmartlingGlossary, + assetTextUnitToTMTextUnitRepository, + batchSize, + meterRegistry, + mockThirdPartyFileChecksumRepository); + Repository repository = + repositoryService.createRepository(testIdWatcher.getEntityName("batchRepo")); + Locale frCA = localeService.findByBcp47Tag("fr-CA"); + Locale jaJP = localeService.findByBcp47Tag("ja-JP"); + repositoryService.addRepositoryLocale(repository, frCA.getBcp47Tag()); + repositoryService.addRepositoryLocale(repository, jaJP.getBcp47Tag()); + locales.add(frCA); + locales.add(jaJP); + + 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); + + PluralForm one = pluralFormService.findByPluralFormString("one"); + + List singularIds = new ArrayList<>(); + int singularTextUnits = 14; + int singularBatches = 5; + + for (int i = 0; i < singularTextUnits; i++) { + String name = "singular_message_test" + i; + String content = "Singular Message Test #" + i; + String comment = "Singular Comment" + i; + TMTextUnit textUnit = + tmService.addTMTextUnit(tm.getId(), asset.getId(), name, content, comment); + singularIds.add(textUnit.getId()); + assetExtractionService.createAssetTextUnit(assetExtraction, name, content, comment); + } + + List pluralIds = new ArrayList<>(); + int pluralTextUnits = 8; + int pluralBatches = 3; + + for (int i = 0; i < pluralTextUnits; i++) { + String name = "plural_message" + i + "_one"; + String content = "Plural Message Test #" + i; + String comment = "Plural Comment" + i; + String pluralFormOther = "plural_form_other" + i; + + TMTextUnit textUnit = + tmService.addTMTextUnit(tm, asset, name, content, comment, null, one, pluralFormOther); + pluralIds.add(textUnit.getId()); + assetExtractionService.createAssetTextUnit(assetExtraction, name, content, comment); + } + + prepareAssetAndTextUnits(assetExtraction, asset, tm); + + tus = searchTextUnits(singularIds); + Iterable> singularIt = Iterables.partition(tus, batchSize); + int i = 0; + for (List textUnits : singularIt) { + for (Locale l : locales) { + doReturn(localizedContent(textUnits, l)) + .when(smartlingClient) + .downloadPublishedFile( + eq("projectId"), + eq(l.getBcp47Tag()), + eq(singularFileName(repository, i)), + eq(false)); + } + i++; + } + + tus = searchTextUnits(pluralIds); + Iterable> pluralIt = Iterables.partition(tus, batchSize); + i = 0; + for (List textUnits : pluralIt) { + for (Locale l : locales) { + doReturn(localizedContent(textUnits, l)) + .when(smartlingClient) + .downloadPublishedFile( + eq("projectId"), eq(l.getBcp47Tag()), eq(pluralFileName(repository, i)), eq(false)); + } + i++; + } + + // Execute an initial pull that will record translated files checksums and verify text units are + // imported + tmsSmartling.pull( + repository, "projectId", pluralSep, localeMapping, null, null, Collections.emptyList()); + + verify(mockTextUnitBatchImporterService, atLeastOnce()) + .importTextUnits(textUnitListCaptor.capture(), eq(false), eq(true)); + + Mockito.clearInvocations(mockTextUnitBatchImporterService); + + i = 0; + for (List textUnits : singularIt) { + for (Locale l : locales) { + // add a new line to translated file to trigger checksum change + doReturn(localizedContent(textUnits, l) + "\n") + .when(smartlingClient) + .downloadPublishedFile( + eq("projectId"), + eq(l.getBcp47Tag()), + eq(singularFileName(repository, i)), + eq(false)); + } + i++; + } + + i = 0; + for (List textUnits : pluralIt) { + for (Locale l : locales) { + // add a new line to translated file to trigger checksum change + doReturn(localizedContent(textUnits, l) + "\n") + .when(smartlingClient) + .downloadPublishedFile( + eq("projectId"), eq(l.getBcp47Tag()), eq(pluralFileName(repository, i)), eq(false)); + } + i++; + } + + // Run the same pull again, text unit imports should occur as file checksums have changed since + // previous run + tmsSmartling.pull( + repository, "projectId", pluralSep, localeMapping, null, null, Collections.emptyList()); + + verify(mockTextUnitBatchImporterService, atLeastOnce()) + .importTextUnits(textUnitListCaptor.capture(), eq(false), eq(true)); + } + @Test public void testPullInBatchesWithSingularsAndPlurals() throws RepositoryNameAlreadyUsedException, RepositoryLocaleCreationException {