diff --git a/api/topicservice.yml b/api/topicservice.yml index 9efc3174..d8b0805f 100644 --- a/api/topicservice.yml +++ b/api/topicservice.yml @@ -229,6 +229,24 @@ components: registrationDropdown: type: string example: "Beratung xyz" + TitlesMultilingualDTO: + type: object + properties: + short: + type: object + additionalProperties: + type: string + long: + type: object + additionalProperties: + type: string + welcome: + type: string + example: "Herzlich Willkommen zu Beratung xyz" + registrationDropdown: + type: string + example: "Beratung xyz" + TopicGroupsDTO: type: object required: @@ -349,7 +367,7 @@ components: welcomeMessage: $ref: '#/components/schemas/WelcomeMessage' titles: - $ref: '#/components/schemas/TitlesDTO' + $ref: '#/components/schemas/TitlesMultilingualDTO' Translation: type: object diff --git a/src/main/java/de/caritas/cob/consultingtypeservice/api/converter/TopicConverter.java b/src/main/java/de/caritas/cob/consultingtypeservice/api/converter/TopicConverter.java index 8611dc02..4420516a 100644 --- a/src/main/java/de/caritas/cob/consultingtypeservice/api/converter/TopicConverter.java +++ b/src/main/java/de/caritas/cob/consultingtypeservice/api/converter/TopicConverter.java @@ -2,6 +2,7 @@ import static de.caritas.cob.consultingtypeservice.api.util.JsonConverter.convertMapFromJson; import static de.caritas.cob.consultingtypeservice.api.util.JsonConverter.convertToJson; +import static de.caritas.cob.consultingtypeservice.api.util.TranslationUtils.getTranslatedStringFromMap; import de.caritas.cob.consultingtypeservice.api.model.*; import de.caritas.cob.consultingtypeservice.api.service.TranslationService; @@ -9,7 +10,6 @@ import java.time.ZoneOffset; import java.util.Collection; import java.util.List; -import java.util.Map; import java.util.stream.Collectors; import lombok.NonNull; import lombok.RequiredArgsConstructor; @@ -23,8 +23,6 @@ public class TopicConverter { private final @NonNull TranslationService translationService; - public static final String DE = "de"; - public TopicDTO toDTO(final TopicEntity topic, final String lang) { final var topicDTO = new TopicDTO() @@ -36,7 +34,7 @@ public TopicDTO toDTO(final TopicEntity topic, final String lang) { .fallbackAgencyId(topic.getFallbackAgencyId()) .fallbackUrl(topic.getFallbackUrl()) .welcomeMessage(topic.getWelcomeMessage()) - .titles(toTitlesDTO(topic)) + .titles(toTitlesDTO(topic, lang)) .internalIdentifier(topic.getInternalIdentifier()); if (topic.getCreateDate() != null) { topicDTO.setCreateDate(topic.getCreateDate().toString()); @@ -47,10 +45,10 @@ public TopicDTO toDTO(final TopicEntity topic, final String lang) { return topicDTO; } - private static TitlesDTO toTitlesDTO(TopicEntity topic) { + private static TitlesDTO toTitlesDTO(TopicEntity topic, String lang) { return new TitlesDTO() - ._short(topic.getTitlesShort()) - ._long(topic.getTitlesLong()) + ._short(getTranslatedStringFromMap(topic.getTitlesShort(), lang)) + ._long(getTranslatedStringFromMap(topic.getTitlesLong(), lang)) .welcome(topic.getTitlesWelcome()) .registrationDropdown(topic.getTitlesDropdown()); } @@ -71,7 +69,7 @@ public TopicMultilingualDTO toMultilingualDTO(final TopicEntity topic) { .fallbackAgencyId(topic.getFallbackAgencyId()) .fallbackUrl(topic.getFallbackUrl()) .welcomeMessage(topic.getWelcomeMessage()) - .titles(toTitlesDTO(topic)) + .titles(toMultilingualTitlesDTO(topic)) .internalIdentifier(topic.getInternalIdentifier()); if (topic.getCreateDate() != null) { topicMultilingualDTO.setCreateDate(topic.getCreateDate().toString()); @@ -82,6 +80,14 @@ public TopicMultilingualDTO toMultilingualDTO(final TopicEntity topic) { return topicMultilingualDTO; } + private TitlesMultilingualDTO toMultilingualTitlesDTO(TopicEntity topic) { + return new TitlesMultilingualDTO() + ._short(convertMapFromJson(topic.getTitlesShort())) + ._long(convertMapFromJson(topic.getTitlesLong())) + .welcome(topic.getTitlesWelcome()) + .registrationDropdown(topic.getTitlesDropdown()); + } + public List toMultilingualDTOList( final Collection topicEntities) { return topicEntities.stream().map(this::toMultilingualDTO).collect(Collectors.toList()); @@ -103,13 +109,29 @@ public TopicEntity toEntity(final TopicMultilingualDTO topicDTO) { topicEntity.setFallbackAgencyId(topicDTO.getFallbackAgencyId()); topicEntity.setFallbackUrl(topicDTO.getFallbackUrl()); topicEntity.setWelcomeMessage(topicDTO.getWelcomeMessage()); - topicEntity.setTitlesShort(topicDTO.getTitles().getShort()); - topicEntity.setTitlesLong(topicDTO.getTitles().getLong()); - topicEntity.setTitlesWelcome(topicDTO.getTitles().getWelcome()); - topicEntity.setTitlesDropdown(topicDTO.getTitles().getRegistrationDropdown()); + titlesToEntity(topicDTO, topicEntity); return topicEntity; } + private void titlesToEntity(TopicMultilingualDTO topicDTO, TopicEntity topicEntity) { + TitlesMultilingualDTO titles = topicDTO.getTitles(); + if (titles != null) { + topicEntity.setTitlesShort(convertToJson(titles.getShort())); + topicEntity.setTitlesLong(convertToJson(titles.getLong())); + topicEntity.setTitlesWelcome(convertToJson(titles.getWelcome())); + topicEntity.setTitlesDropdown(convertToJson(titles.getRegistrationDropdown())); + } else { + nullifyTitleAttributes(topicEntity); + } + } + + private void nullifyTitleAttributes(TopicEntity topicEntity) { + topicEntity.setTitlesLong(null); + topicEntity.setTitlesShort(null); + topicEntity.setTitlesWelcome(null); + topicEntity.setTitlesDropdown(null); + } + public TopicEntity toEntity(final TopicEntity targetEntity, final TopicMultilingualDTO topicDTO) { targetEntity.setName(convertToJson(topicDTO.getName())); targetEntity.setSlug(topicDTO.getSlug()); @@ -120,24 +142,7 @@ public TopicEntity toEntity(final TopicEntity targetEntity, final TopicMultiling targetEntity.setFallbackAgencyId(topicDTO.getFallbackAgencyId()); targetEntity.setFallbackUrl(topicDTO.getFallbackUrl()); targetEntity.setWelcomeMessage(topicDTO.getWelcomeMessage()); - targetEntity.setTitlesShort(topicDTO.getTitles().getShort()); - targetEntity.setTitlesLong(topicDTO.getTitles().getLong()); - targetEntity.setTitlesWelcome(topicDTO.getTitles().getWelcome()); - targetEntity.setTitlesDropdown(topicDTO.getTitles().getRegistrationDropdown()); + titlesToEntity(topicDTO, targetEntity); return targetEntity; } - - private static String getTranslatedStringFromMap(final String jsonValue, final String lang) { - final Map translations = convertMapFromJson(jsonValue); - if (lang == null || !translations.containsKey(lang)) { - if (translations.containsKey(DE)) { - return translations.get(DE); - } else { - log.warn("Default translation for value not available"); - return ""; - } - } else { - return translations.get(lang); - } - } } diff --git a/src/main/java/de/caritas/cob/consultingtypeservice/api/converter/TopicGroupConverter.java b/src/main/java/de/caritas/cob/consultingtypeservice/api/converter/TopicGroupConverter.java index 5f8503ab..bd9ef86d 100644 --- a/src/main/java/de/caritas/cob/consultingtypeservice/api/converter/TopicGroupConverter.java +++ b/src/main/java/de/caritas/cob/consultingtypeservice/api/converter/TopicGroupConverter.java @@ -4,30 +4,43 @@ import de.caritas.cob.consultingtypeservice.api.model.TopicGroupsDTO; import de.caritas.cob.consultingtypeservice.api.model.TopicGroupsDTOData; import de.caritas.cob.consultingtypeservice.api.model.TopicGroupsDTODataItemsInner; +import de.caritas.cob.consultingtypeservice.api.service.TranslationService; +import de.caritas.cob.consultingtypeservice.api.util.TranslationUtils; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; @Component +@RequiredArgsConstructor public class TopicGroupConverter { + private final @NonNull TranslationService translationService; + public TopicGroupsDTO toTopicGroupsDTO(Collection topicGroups) { return new TopicGroupsDTO().data(new TopicGroupsDTOData().items(itemsOf(topicGroups))); } - private static List itemsOf( - Collection topicGroups) { + private List itemsOf(Collection topicGroups) { + final String lang = translationService.getCurrentLanguageContext(); + return topicGroups.stream() .map( topicGroup -> new TopicGroupsDTODataItemsInner() .topicIds(topicIdsOf(topicGroup)) .id(topicGroup.getId().intValue()) - .name(topicGroup.getName())) + .name( + resolveNameForGivenLanguageOrFallbackToGerman(topicGroup.getName(), lang))) .collect(Collectors.toList()); } + private String resolveNameForGivenLanguageOrFallbackToGerman(String nameAsJson, String lang) { + return TranslationUtils.getTranslatedStringFromMap(nameAsJson, lang); + } + private static List topicIdsOf(TopicGroupEntity topicGroup) { return topicGroup.getTopicEntities().stream() .map(topicEntity -> topicEntity.getId().intValue()) diff --git a/src/main/java/de/caritas/cob/consultingtypeservice/api/util/TranslationUtils.java b/src/main/java/de/caritas/cob/consultingtypeservice/api/util/TranslationUtils.java new file mode 100644 index 00000000..a87bfa72 --- /dev/null +++ b/src/main/java/de/caritas/cob/consultingtypeservice/api/util/TranslationUtils.java @@ -0,0 +1,30 @@ +package de.caritas.cob.consultingtypeservice.api.util; + +import static de.caritas.cob.consultingtypeservice.api.util.JsonConverter.convertMapFromJson; + +import java.util.Map; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class TranslationUtils { + + public static final String DE = "de"; + + private TranslationUtils() { + throw new IllegalStateException("Utility class"); + } + + public static String getTranslatedStringFromMap(final String jsonValue, final String lang) { + final Map translations = convertMapFromJson(jsonValue); + if (lang == null || !translations.containsKey(lang)) { + if (translations.containsKey(DE)) { + return translations.get(DE); + } else { + log.warn("Default translation for value not available"); + return ""; + } + } else { + return translations.get(lang); + } + } +} diff --git a/src/main/resources/db/changelog/changeset/0010_change_topic_and_topic_groups_to_be_i18n_aware/0010_change_topic_and_topic_groups_to_be_i18n_aware-rollback.sql b/src/main/resources/db/changelog/changeset/0010_change_topic_and_topic_groups_to_be_i18n_aware/0010_change_topic_and_topic_groups_to_be_i18n_aware-rollback.sql new file mode 100644 index 00000000..bbb14a5d --- /dev/null +++ b/src/main/resources/db/changelog/changeset/0010_change_topic_and_topic_groups_to_be_i18n_aware/0010_change_topic_and_topic_groups_to_be_i18n_aware-rollback.sql @@ -0,0 +1,11 @@ +ALTER TABLE consultingtypeservice.`topic` + MODIFY COLUMN titles_short varchar (100); +ALTER TABLE consultingtypeservice.`topic` + MODIFY COLUMN titles_long varchar (100); +ALTER TABLE consultingtypeservice.`topic` + MODIFY COLUMN name varchar (100); +ALTER TABLE consultingtypeservice.`topic` + MODIFY COLUMN description varchar (100); +ALTER TABLE consultingtypeservice.`topic_group` + MODIFY COLUMN name varchar (100); + diff --git a/src/main/resources/db/changelog/changeset/0010_change_topic_and_topic_groups_to_be_i18n_aware/0010_change_topic_and_topic_groups_to_be_i18n_aware.sql b/src/main/resources/db/changelog/changeset/0010_change_topic_and_topic_groups_to_be_i18n_aware/0010_change_topic_and_topic_groups_to_be_i18n_aware.sql new file mode 100644 index 00000000..9dece3c4 --- /dev/null +++ b/src/main/resources/db/changelog/changeset/0010_change_topic_and_topic_groups_to_be_i18n_aware/0010_change_topic_and_topic_groups_to_be_i18n_aware.sql @@ -0,0 +1,11 @@ +ALTER TABLE consultingtypeservice.`topic` + MODIFY COLUMN titles_short varchar (4092); +ALTER TABLE consultingtypeservice.`topic` + MODIFY COLUMN titles_long varchar (4092); +ALTER TABLE consultingtypeservice.`topic` + MODIFY COLUMN name varchar (4092); +ALTER TABLE consultingtypeservice.`topic` + MODIFY COLUMN description varchar (4092); +ALTER TABLE consultingtypeservice.`topic_group` + MODIFY COLUMN name varchar (4092); + diff --git a/src/main/resources/db/changelog/changeset/0010_change_topic_and_topic_groups_to_be_i18n_aware/0010_change_topic_and_topic_groups_to_be_i18n_aware.xml b/src/main/resources/db/changelog/changeset/0010_change_topic_and_topic_groups_to_be_i18n_aware/0010_change_topic_and_topic_groups_to_be_i18n_aware.xml new file mode 100644 index 00000000..7463e753 --- /dev/null +++ b/src/main/resources/db/changelog/changeset/0010_change_topic_and_topic_groups_to_be_i18n_aware/0010_change_topic_and_topic_groups_to_be_i18n_aware.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/main/resources/db/changelog/consultingtypeservice-dev-master.xml b/src/main/resources/db/changelog/consultingtypeservice-dev-master.xml index 82a9f637..1c13ed9b 100644 --- a/src/main/resources/db/changelog/consultingtypeservice-dev-master.xml +++ b/src/main/resources/db/changelog/consultingtypeservice-dev-master.xml @@ -15,4 +15,5 @@ + diff --git a/src/main/resources/db/changelog/consultingtypeservice-local-master.xml b/src/main/resources/db/changelog/consultingtypeservice-local-master.xml index 28e10052..936e4122 100644 --- a/src/main/resources/db/changelog/consultingtypeservice-local-master.xml +++ b/src/main/resources/db/changelog/consultingtypeservice-local-master.xml @@ -16,4 +16,5 @@ + diff --git a/src/main/resources/db/changelog/consultingtypeservice-prod-master.xml b/src/main/resources/db/changelog/consultingtypeservice-prod-master.xml index 351fab7c..4a75ff88 100644 --- a/src/main/resources/db/changelog/consultingtypeservice-prod-master.xml +++ b/src/main/resources/db/changelog/consultingtypeservice-prod-master.xml @@ -16,4 +16,5 @@ + diff --git a/src/main/resources/db/changelog/consultingtypeservice-staging-master.xml b/src/main/resources/db/changelog/consultingtypeservice-staging-master.xml index 351fab7c..4a75ff88 100644 --- a/src/main/resources/db/changelog/consultingtypeservice-staging-master.xml +++ b/src/main/resources/db/changelog/consultingtypeservice-staging-master.xml @@ -16,4 +16,5 @@ + diff --git a/src/main/resources/db/changelog/consultingtypeservice-testing-master.xml b/src/main/resources/db/changelog/consultingtypeservice-testing-master.xml index 9bfe7b32..e536700f 100644 --- a/src/main/resources/db/changelog/consultingtypeservice-testing-master.xml +++ b/src/main/resources/db/changelog/consultingtypeservice-testing-master.xml @@ -13,4 +13,5 @@ + diff --git a/src/test/java/de/caritas/cob/consultingtypeservice/api/controller/TopicAdminControllerIT.java b/src/test/java/de/caritas/cob/consultingtypeservice/api/controller/TopicAdminControllerIT.java index 0febfc01..ac614532 100644 --- a/src/test/java/de/caritas/cob/consultingtypeservice/api/controller/TopicAdminControllerIT.java +++ b/src/test/java/de/caritas/cob/consultingtypeservice/api/controller/TopicAdminControllerIT.java @@ -16,7 +16,7 @@ import de.caritas.cob.consultingtypeservice.ConsultingTypeServiceApplication; import de.caritas.cob.consultingtypeservice.api.auth.UserRole; -import de.caritas.cob.consultingtypeservice.api.model.TitlesDTO; +import de.caritas.cob.consultingtypeservice.api.model.TitlesMultilingualDTO; import de.caritas.cob.consultingtypeservice.api.model.TopicMultilingualDTO; import de.caritas.cob.consultingtypeservice.api.model.TopicStatus; import de.caritas.cob.consultingtypeservice.api.service.TenantService; @@ -26,6 +26,7 @@ import de.caritas.cob.consultingtypeservice.tenantservice.generated.web.model.RestrictedTenantDTO; import de.caritas.cob.consultingtypeservice.tenantservice.generated.web.model.Settings; import de.caritas.cob.consultingtypeservice.testHelper.TopicPathConstants; +import java.util.HashMap; import java.util.Map; import org.assertj.core.util.Maps; import org.assertj.core.util.Sets; @@ -107,7 +108,11 @@ void updateTopic_Should_returnStatusOk_When_calledWithValidCreateParamsAndValidA .withInternalIdentifier("new ident") .withStatus(TopicStatus.INACTIVE.toString()) .withTitles( - new TitlesDTO()._short("l")._long("l").welcome("l").registrationDropdown("dd")) + new TitlesMultilingualDTO() + ._short(translateableMapWithGermanEntryFor("l")) + ._long(translateableMapWithGermanEntryFor("l")) + .welcome("l") + .registrationDropdown("dd")) .jsonify(); final Authentication authentication = givenMockAuthentication(UserRole.TOPIC_ADMIN); @@ -209,9 +214,9 @@ void createTopic_Should_returnStatusOk_When_calledWithValidCreateParamsAndValidA topicDTO.setStatus(TopicStatus.INACTIVE.toString()); topicDTO.setSlug("slug"); topicDTO.setTitles( - new TitlesDTO() - ._short("short") - ._long("long") + new TitlesMultilingualDTO() + ._short(translateableMapWithGermanEntryFor("short")) + ._long(translateableMapWithGermanEntryFor("long")) .welcome("welcome") .registrationDropdown("dd")); final String payload = JsonConverter.convertToJson(topicDTO); @@ -228,6 +233,8 @@ void createTopic_Should_returnStatusOk_When_calledWithValidCreateParamsAndValidA .andExpect(jsonPath("$.name").exists()) .andExpect(jsonPath("$.slug").exists()) .andExpect(jsonPath("$.description").exists()) + .andExpect(jsonPath("$.titles.short").exists()) + .andExpect(jsonPath("$.titles.long").exists()) .andExpect(jsonPath("$.status").value("INACTIVE")) .andExpect(jsonPath("$.internalIdentifier").exists()) .andExpect(jsonPath("$.createDate").exists()); @@ -333,4 +340,10 @@ private void givenOtherClaimsAreDefinedForToken(final AccessToken token) { claimMap.put("userId", "some userid"); when(token.getOtherClaims()).thenReturn(claimMap); } + + private static Map translateableMapWithGermanEntryFor(String value) { + final Map description = new HashMap<>(); + description.put("de", value); + return description; + } } diff --git a/src/test/java/de/caritas/cob/consultingtypeservice/api/controller/TopicGroupsControllerIT.java b/src/test/java/de/caritas/cob/consultingtypeservice/api/controller/TopicGroupsControllerIT.java index 13957a7a..ea8aeff5 100644 --- a/src/test/java/de/caritas/cob/consultingtypeservice/api/controller/TopicGroupsControllerIT.java +++ b/src/test/java/de/caritas/cob/consultingtypeservice/api/controller/TopicGroupsControllerIT.java @@ -53,14 +53,14 @@ void getAllTopicGroups_Should_ReturnTopicGroupsDTO_When_UserIsAuthenticated() th val tge1 = TopicGroupEntity.builder() .id(1L) - .name("1") + .name("{\"de\":\"1\"}") .topicEntities( Set.of(TopicEntity.builder().id(1L).build(), TopicEntity.builder().id(2L).build())) .build(); val tge2 = TopicGroupEntity.builder() .id(2L) - .name("2") + .name("{\"de\":\"2\"}") .topicEntities( Set.of(TopicEntity.builder().id(3L).build(), TopicEntity.builder().id(4L).build())) .build(); diff --git a/src/test/java/de/caritas/cob/consultingtypeservice/api/converter/TopicConverterTest.java b/src/test/java/de/caritas/cob/consultingtypeservice/api/converter/TopicConverterTest.java index 225d5bb2..a3a9a10c 100644 --- a/src/test/java/de/caritas/cob/consultingtypeservice/api/converter/TopicConverterTest.java +++ b/src/test/java/de/caritas/cob/consultingtypeservice/api/converter/TopicConverterTest.java @@ -1,5 +1,6 @@ package de.caritas.cob.consultingtypeservice.api.converter; +import static de.caritas.cob.consultingtypeservice.api.util.JsonConverter.convertToJson; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.when; @@ -24,20 +25,20 @@ class TopicConverterTest { @Test void toEntity_should_convertToEntityAndBackToMultilingualDTO() { // given - final Map name = new HashMap<>(); - name.put("de", "name"); - final Map description = new HashMap<>(); - description.put("de", "desc"); final var topicDTO = new TopicMultilingualDTO() .id(1L) .status(TopicStatus.ACTIVE.toString()) .internalIdentifier("identifier") - .name(name) + .name(translateableMapWithGermanEntryFor("name")) .slug("slug") .titles( - new TitlesDTO()._short("ts")._long("tl").registrationDropdown("td").welcome("tw")) - .description(description); + new TitlesMultilingualDTO() + ._short(translateableMapWithGermanEntryFor("ts")) + ._long(translateableMapWithGermanEntryFor("tl")) + .registrationDropdown("td") + .welcome("tw")) + .description(translateableMapWithGermanEntryFor("desc")); // when final var entity = topicConverter.toEntity(topicDTO); @@ -47,6 +48,14 @@ void toEntity_should_convertToEntityAndBackToMultilingualDTO() { assertThat(actual.getName()).isEqualTo(topicDTO.getName().get("de")); assertThat(actual.getSlug()).isEqualTo(topicDTO.getSlug()); assertThat(actual.getDescription()).isEqualTo(topicDTO.getDescription().get("de")); + assertThat(actual.getTitles().getShort()).isEqualTo("ts"); + assertThat(actual.getTitles().getLong()).isEqualTo("tl"); + } + + private static Map translateableMapWithGermanEntryFor(String value) { + final Map description = new HashMap<>(); + description.put("de", value); + return description; } @Test @@ -61,10 +70,10 @@ void toDTOList_Should_convertCollectionOfTopicEntitiesToListOfTopicDTOsWithCorre .name("{\"de\":\"name de\", \"en\":\"name en\"}") .description("{\"de\":\"desc de\", \"en\":\"desc en\"}") .slug("slug") - .titlesShort("ts") - .titlesLong("tl") - .titlesDropdown("td") + .titlesShort("{\"de\":\"ts\", \"en\":\"ts en\"}") + .titlesLong("{\"de\":\"tl\", \"en\":\"tl en\"}") .titlesWelcome("tw") + .titlesDropdown("td") .build(); final var topicEntity2 = TopicEntity.builder() @@ -74,8 +83,8 @@ void toDTOList_Should_convertCollectionOfTopicEntitiesToListOfTopicDTOsWithCorre .name("{\"de\":\"name 2 de\", \"en\":\"name 2 en\"}") .description("{\"de\":\"desc 2 de\", \"en\":\"desc 2 en\"}") .slug("slug") - .titlesShort("ts") - .titlesLong("tl") + .titlesShort("{\"de\":\"ts\", \"en\":\"ts en\"}") + .titlesLong("{\"de\":\"tl\", \"en\":\"tl en\"}") .titlesDropdown("td") .titlesWelcome("tw") .build(); @@ -86,20 +95,21 @@ void toDTOList_Should_convertCollectionOfTopicEntitiesToListOfTopicDTOsWithCorre .id(1L) .status(TopicStatus.ACTIVE.toString()) .internalIdentifier("identifier") - .name("name en") + .name("name de") .slug("slug") .titles(titles) - .description("desc en"); + .description("desc de"); final var topicDTO2 = new TopicDTO() .id(2L) .status(TopicStatus.ACTIVE.toString()) .internalIdentifier("identifier 2") - .name("name 2 en") + .name("name 2 de") .slug("slug") .titles(titles) - .description("desc 2 en"); + .description("desc 2 de"); + when(translationService.getCurrentLanguageContext()).thenReturn("de"); // when final var entities = topicConverter.toDTOList(List.of(topicEntity1, topicEntity2)); @@ -120,8 +130,8 @@ void toDTOList_Should_convertCollectionOfTopicEntitiesToListOfTopicDTOsWithCorre .name("{\"de\":\"name de\", \"en\":\"name en\"}") .description("{\"de\":\"desc de\", \"en\":\"desc en\"}") .slug("slug") - .titlesShort("ts") - .titlesLong("tl") + .titlesShort("{\"de\":\"ts\", \"en\":\"ts en\"}") + .titlesLong("{\"de\":\"tl\", \"en\":\"tl en\"}") .titlesDropdown("td") .titlesWelcome("tw") .build(); @@ -133,8 +143,8 @@ void toDTOList_Should_convertCollectionOfTopicEntitiesToListOfTopicDTOsWithCorre .name("{\"de\":\"name 2 de\", \"en\":\"name 2 en\"}") .description("{\"de\":\"desc 2 de\", \"en\":\"desc 2 en\"}") .slug("slug") - .titlesShort("ts") - .titlesLong("tl") + .titlesShort("{\"de\":\"ts\", \"en\":\"ts en\"}") + .titlesLong("{\"de\":\"tl\", \"en\":\"tl en\"}") .titlesDropdown("td") .titlesWelcome("tw") .build(); @@ -159,6 +169,7 @@ void toDTOList_Should_convertCollectionOfTopicEntitiesToListOfTopicDTOsWithCorre .titles(titles) .description("desc 2 de"); + when(translationService.getCurrentLanguageContext()).thenReturn("de"); // when final var entities = topicConverter.toDTOList(List.of(topicEntity1, topicEntity2)); @@ -170,7 +181,12 @@ void toDTOList_Should_convertCollectionOfTopicEntitiesToListOfTopicDTOsWithCorre void toMultilingualDTOList_Should_convertCollectionOfTopicEntitiesToListOfTopicMultilingualDTOs() { // given - val titles = new TitlesDTO()._long("l")._short("s").registrationDropdown("r").welcome("w"); + val titles = + new TitlesMultilingualDTO() + ._long(translateableMapWithGermanEntryFor("l")) + ._short(translateableMapWithGermanEntryFor("s")) + .registrationDropdown("r") + .welcome("w"); final var topicEntity1 = TopicEntity.builder() .id(1L) @@ -179,8 +195,8 @@ void toDTOList_Should_convertCollectionOfTopicEntitiesToListOfTopicDTOsWithCorre .name("{\"de\":\"name de\", \"en\":\"name en\"}") .description("{\"de\":\"desc de\", \"en\":\"desc en\"}") .slug("slug") - .titlesLong(titles.getLong()) - .titlesShort(titles.getShort()) + .titlesLong(convertToJson(titles.getLong())) + .titlesShort(convertToJson(titles.getShort())) .titlesDropdown(titles.getRegistrationDropdown()) .titlesWelcome(titles.getWelcome()) .build(); @@ -192,8 +208,8 @@ void toDTOList_Should_convertCollectionOfTopicEntitiesToListOfTopicDTOsWithCorre .name("{\"de\":\"name 2 de\", \"en\":\"name 2 en\"}") .description("{\"de\":\"desc 2 de\", \"en\":\"desc 2 en\"}") .slug("slug") - .titlesLong(titles.getLong()) - .titlesShort(titles.getShort()) + .titlesLong(convertToJson(titles.getLong())) + .titlesShort(convertToJson(titles.getShort())) .titlesWelcome(titles.getWelcome()) .titlesDropdown(titles.getRegistrationDropdown()) .build(); diff --git a/src/test/java/de/caritas/cob/consultingtypeservice/api/converter/TopicGroupConverterTest.java b/src/test/java/de/caritas/cob/consultingtypeservice/api/converter/TopicGroupConverterTest.java new file mode 100644 index 00000000..7efa03d2 --- /dev/null +++ b/src/test/java/de/caritas/cob/consultingtypeservice/api/converter/TopicGroupConverterTest.java @@ -0,0 +1,46 @@ +package de.caritas.cob.consultingtypeservice.api.converter; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.when; + +import com.google.common.collect.Lists; +import de.caritas.cob.consultingtypeservice.api.model.TopicGroupEntity; +import de.caritas.cob.consultingtypeservice.api.service.TranslationService; +import org.assertj.core.util.Sets; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class TopicGroupConverterTest { + + @InjectMocks TopicGroupConverter topicGroupConverter; + + @Mock TranslationService translationService; + + @Test + void should_ResolveNameForGivenLang_When_TopicGroupConverterIsCalled() { + // given + var topicGroups = + Lists.newArrayList( + TopicGroupEntity.builder() + .id(1L) + .name("{\"de\":\"name_de\",\"en\":\"name_en\"}") + .topicEntities(Sets.newHashSet()) + .build(), + TopicGroupEntity.builder() + .id(2L) + .name("{\"de\":\"second_name_de\",\"en\":\"second_name_en\"}") + .topicEntities(Sets.newHashSet()) + .build()); + when(translationService.getCurrentLanguageContext()).thenReturn("en"); + + // when + var result = topicGroupConverter.toTopicGroupsDTO(topicGroups); + // then + assertEquals("name_en", result.getData().getItems().get(0).getName()); + assertEquals("second_name_en", result.getData().getItems().get(1).getName()); + } +} diff --git a/src/test/java/de/caritas/cob/consultingtypeservice/api/util/MultilingualTopicTestDataBuilder.java b/src/test/java/de/caritas/cob/consultingtypeservice/api/util/MultilingualTopicTestDataBuilder.java index 9cb9bc2a..b6d96dd9 100644 --- a/src/test/java/de/caritas/cob/consultingtypeservice/api/util/MultilingualTopicTestDataBuilder.java +++ b/src/test/java/de/caritas/cob/consultingtypeservice/api/util/MultilingualTopicTestDataBuilder.java @@ -1,6 +1,6 @@ package de.caritas.cob.consultingtypeservice.api.util; -import de.caritas.cob.consultingtypeservice.api.model.TitlesDTO; +import de.caritas.cob.consultingtypeservice.api.model.TitlesMultilingualDTO; import de.caritas.cob.consultingtypeservice.api.model.TopicMultilingualDTO; import java.time.LocalDateTime; import java.time.ZoneOffset; @@ -47,7 +47,7 @@ public MultilingualTopicTestDataBuilder withName() { return this; } - public MultilingualTopicTestDataBuilder withTitles(TitlesDTO titles) { + public MultilingualTopicTestDataBuilder withTitles(TitlesMultilingualDTO titles) { topicMultilingualDTO.setTitles(titles); return this; } diff --git a/src/test/java/de/caritas/cob/consultingtypeservice/api/util/TranslationUtilsTest.java b/src/test/java/de/caritas/cob/consultingtypeservice/api/util/TranslationUtilsTest.java new file mode 100644 index 00000000..68bbba90 --- /dev/null +++ b/src/test/java/de/caritas/cob/consultingtypeservice/api/util/TranslationUtilsTest.java @@ -0,0 +1,51 @@ +package de.caritas.cob.consultingtypeservice.api.util; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import com.fasterxml.jackson.databind.RuntimeJsonMappingException; +import org.junit.jupiter.api.Test; + +class TranslationUtilsTest { + + @Test + void shouldResolveProperLanguageValue_When_LanguageKeyIsFound() { + // given + // when + String translation = + TranslationUtils.getTranslatedStringFromMap("{\"de\":\"German\",\"en\":\"English\"}", "en"); + // then + assertThat(translation).isEqualTo("English"); + } + + @Test + void shouldFallbackToGerman_When_LanguageNotFound() { + // given + // when + String translation = + TranslationUtils.getTranslatedStringFromMap("{\"de\":\"German\",\"en\":\"English\"}", "fr"); + // then + assertThat(translation).isEqualTo("German"); + } + + @Test + void shouldReturnEmptyString_When_GermanFallbackNotFound() { + // given + // when + String translation = + TranslationUtils.getTranslatedStringFromMap( + "{\"es\":\"Spanish\",\"en\":\"English\"}", "fr"); + // then + assertThat(translation).isEmpty(); + } + + @Test + void shouldThrowException_When_GivenStringNotInJsonFormat() { + // given + // when + // then + assertThrows( + RuntimeJsonMappingException.class, + () -> TranslationUtils.getTranslatedStringFromMap("aSimpleString", "fr")); + } +} diff --git a/src/test/resources/database/TopicDatabase.sql b/src/test/resources/database/TopicDatabase.sql index aa5fae6f..98539d27 100644 --- a/src/test/resources/database/TopicDatabase.sql +++ b/src/test/resources/database/TopicDatabase.sql @@ -40,19 +40,19 @@ INSERT INTO TOPIC (`id`, `tenant_id`, `name`, `description`, `status`, `create_d `titles_long`, `titles_welcome`, `titles_dropdown`,`slug`) VALUES (1, '1', '{"de" : "de an active topic", "en": "en an active topic"}', '{"de" : "de description", "en": "en description"}', 'ACTIVE', - '2022-06-02', 1, 'https://www.google.com', 'Welcome', TRUE, '1-short', - '1-long', '1-welcome', '1-dropdown','1-slug'); + '2022-06-02', 1, 'https://www.google.com', 'Welcome', TRUE, '{"de" : "1-short", "en": "1-short-en"}', + '{"de" : "1-long", "en": "1-long-en"}', '1-welcome', '1-dropdown','1-slug'); INSERT INTO TOPIC (`id`, `tenant_id`, `name`, `description`, `status`, `create_date`, `titles_short`, `titles_long`, `titles_welcome`, `titles_dropdown`, `slug`) VALUES (2, '1', '{"de" : "de not an active topic", "en": "en not an active topic"}', - '{"de" : "de description", "en": "en description"}', 'INACTIVE', '2022-06-02', '2-short', '2-long', + '{"de" : "de description", "en": "en description"}', 'INACTIVE', '2022-06-02', '{"de" : "2-short", "en": "2-short-en"}', '{"de" : "2-short", "en": "2-long-en"}', '2-welcome', '2-dropdown', '2-slug'); INSERT INTO TOPIC (`id`, `tenant_id`, `name`, `description`, `status`, `create_date`, `titles_short`, `titles_long`, `titles_welcome`, `titles_dropdown`, `slug`) VALUES (3, '2', '{"de" : "de another topic"}', '{"de" : "de description"}', 'ACTIVE', '2022-06-02', - '3-short', '3-long', '3-welcome', '3-dropdown', '3-slug'); + '{"de" : "3-short", "en": "3-short-en"}', '{"de" : "3-long", "en": "3-long-en"}', '3-welcome', '3-dropdown', '3-slug'); CREATE TABLE IF NOT EXISTS topic_group (