Skip to content

Commit

Permalink
Merge pull request #16 from virtualidentityag/DIAKONIE-274-internatio…
Browse files Browse the repository at this point in the history
…nalization-for-topics-and-topic-groups

feat: make topic titles short and long attributes i18n-aware, make to…
  • Loading branch information
tkuzynow authored Apr 18, 2024
2 parents 5e7d21f + 9319e6e commit 18ca797
Show file tree
Hide file tree
Showing 19 changed files with 300 additions and 72 deletions.
20 changes: 19 additions & 1 deletion api/topicservice.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -349,7 +367,7 @@ components:
welcomeMessage:
$ref: '#/components/schemas/WelcomeMessage'
titles:
$ref: '#/components/schemas/TitlesDTO'
$ref: '#/components/schemas/TitlesMultilingualDTO'

Translation:
type: object
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

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;
import java.time.LocalDateTime;
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;
Expand All @@ -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()
Expand All @@ -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());
Expand All @@ -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());
}
Expand All @@ -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());
Expand All @@ -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<TopicMultilingualDTO> toMultilingualDTOList(
final Collection<TopicEntity> topicEntities) {
return topicEntities.stream().map(this::toMultilingualDTO).collect(Collectors.toList());
Expand All @@ -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());
Expand All @@ -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<String, String> 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);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<TopicGroupEntity> topicGroups) {
return new TopicGroupsDTO().data(new TopicGroupsDTOData().items(itemsOf(topicGroups)));
}

private static List<TopicGroupsDTODataItemsInner> itemsOf(
Collection<TopicGroupEntity> topicGroups) {
private List<TopicGroupsDTODataItemsInner> itemsOf(Collection<TopicGroupEntity> 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<Integer> topicIdsOf(TopicGroupEntity topicGroup) {
return topicGroup.getTopicEntities().stream()
.map(topicEntity -> topicEntity.getId().intValue())
Expand Down
Original file line number Diff line number Diff line change
@@ -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<String, String> 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);
}
}
}
Original file line number Diff line number Diff line change
@@ -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);

Original file line number Diff line number Diff line change
@@ -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);

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
<changeSet author="dodalovicgran" id="topic_add_titles">
<sqlFile path="db/changelog/changeset/0010_change_topic_and_topic_groups_to_be_i18n_aware/0010_change_topic_and_topic_groups_to_be_i18n_aware.sql" stripComments="true" />
<rollback>
<sqlFile path="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" stripComments="true" />
</rollback>
</changeSet>
</databaseChangeLog>
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@
<include file="db/changelog/changeset/0007_topic_welcome_message/topic_welcome_message.xml"/>
<include file="db/changelog/changeset/0008_topic_send_next_step_message/topic_send_next_step_message.xml"/>
<include file="db/changelog/changeset/0009_topic_add_titles_and_extend_internal_identifier/0009_topic_add_titles_and_extend_internal_identifier.xml"/>
<include file="db/changelog/changeset/0010_change_topic_and_topic_groups_to_be_i18n_aware/0010_change_topic_and_topic_groups_to_be_i18n_aware.xml"/>
</databaseChangeLog>
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@
<include file="db/changelog/changeset/0007_topic_welcome_message/topic_welcome_message.xml"/>
<include file="db/changelog/changeset/0008_topic_send_next_step_message/topic_send_next_step_message.xml"/>
<include file="db/changelog/changeset/0009_topic_add_titles_and_extend_internal_identifier/0009_topic_add_titles_and_extend_internal_identifier.xml"/>
<include file="db/changelog/changeset/0010_change_topic_and_topic_groups_to_be_i18n_aware/0010_change_topic_and_topic_groups_to_be_i18n_aware.xml"/>
</databaseChangeLog>
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@
<include file="db/changelog/changeset/0007_topic_welcome_message/topic_welcome_message.xml"/>
<include file="db/changelog/changeset/0008_topic_send_next_step_message/topic_send_next_step_message.xml"/>
<include file="db/changelog/changeset/0009_topic_add_titles_and_extend_internal_identifier/0009_topic_add_titles_and_extend_internal_identifier.xml"/>
<include file="db/changelog/changeset/0010_change_topic_and_topic_groups_to_be_i18n_aware/0010_change_topic_and_topic_groups_to_be_i18n_aware.xml"/>
</databaseChangeLog>
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@
<include file="db/changelog/changeset/0007_topic_welcome_message/topic_welcome_message.xml"/>
<include file="db/changelog/changeset/0008_topic_send_next_step_message/topic_send_next_step_message.xml"/>
<include file="db/changelog/changeset/0009_topic_add_titles_and_extend_internal_identifier/0009_topic_add_titles_and_extend_internal_identifier.xml"/>
<include file="db/changelog/changeset/0010_change_topic_and_topic_groups_to_be_i18n_aware/0010_change_topic_and_topic_groups_to_be_i18n_aware.xml"/>
</databaseChangeLog>
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@
<include file="db/changelog/changeset/0007_topic_welcome_message/topic_welcome_message.xml"/>
<include file="db/changelog/changeset/0008_topic_send_next_step_message/topic_send_next_step_message.xml"/>
<include file="db/changelog/changeset/0009_topic_add_titles_and_extend_internal_identifier/0009_topic_add_titles_and_extend_internal_identifier.xml"/>
<include file="db/changelog/changeset/0010_change_topic_and_topic_groups_to_be_i18n_aware/0010_change_topic_and_topic_groups_to_be_i18n_aware.xml"/>
</databaseChangeLog>
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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());
Expand Down Expand Up @@ -333,4 +340,10 @@ private void givenOtherClaimsAreDefinedForToken(final AccessToken token) {
claimMap.put("userId", "some userid");
when(token.getOtherClaims()).thenReturn(claimMap);
}

private static Map<String, String> translateableMapWithGermanEntryFor(String value) {
final Map<String, String> description = new HashMap<>();
description.put("de", value);
return description;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Loading

0 comments on commit 18ca797

Please sign in to comment.