From 3dd6ed90092c1c30a1581168210d79056c423261 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Thu, 9 Nov 2023 12:45:36 +0100 Subject: [PATCH 01/29] fix: datetime type mapping for tenantService reference --- pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pom.xml b/pom.xml index 7a5830e6..66f90f58 100644 --- a/pom.xml +++ b/pom.xml @@ -491,6 +491,12 @@ ${project.groupId}.${project.artifactId}.tenantservice.generated.web.model + + OffsetDateTime=LocalDateTime + + + java.time.OffsetDateTime=java.time.LocalDateTime + From bde4973f8f335005ca26b144d369d32c55098645 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Thu, 9 Nov 2023 13:12:48 +0100 Subject: [PATCH 02/29] fix: include proper migrations --- src/main/resources/db/changelog/agencyservice-dev-master.xml | 1 + src/main/resources/db/changelog/agencyservice-local-master.xml | 1 + src/main/resources/db/changelog/agencyservice-prod-master.xml | 1 + src/main/resources/db/changelog/agencyservice-staging-master.xml | 1 + 4 files changed, 4 insertions(+) diff --git a/src/main/resources/db/changelog/agencyservice-dev-master.xml b/src/main/resources/db/changelog/agencyservice-dev-master.xml index 9108a650..159bc005 100644 --- a/src/main/resources/db/changelog/agencyservice-dev-master.xml +++ b/src/main/resources/db/changelog/agencyservice-dev-master.xml @@ -23,4 +23,5 @@ --> + diff --git a/src/main/resources/db/changelog/agencyservice-local-master.xml b/src/main/resources/db/changelog/agencyservice-local-master.xml index 787f4ecd..8e06fc5b 100644 --- a/src/main/resources/db/changelog/agencyservice-local-master.xml +++ b/src/main/resources/db/changelog/agencyservice-local-master.xml @@ -22,4 +22,5 @@ + diff --git a/src/main/resources/db/changelog/agencyservice-prod-master.xml b/src/main/resources/db/changelog/agencyservice-prod-master.xml index 6374e10f..e0758e35 100644 --- a/src/main/resources/db/changelog/agencyservice-prod-master.xml +++ b/src/main/resources/db/changelog/agencyservice-prod-master.xml @@ -19,4 +19,5 @@ + diff --git a/src/main/resources/db/changelog/agencyservice-staging-master.xml b/src/main/resources/db/changelog/agencyservice-staging-master.xml index c9c9268d..c84782e1 100644 --- a/src/main/resources/db/changelog/agencyservice-staging-master.xml +++ b/src/main/resources/db/changelog/agencyservice-staging-master.xml @@ -19,4 +19,5 @@ + From 6a762717c752331fff90275f2889d9a28163be14 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Thu, 9 Nov 2023 13:42:01 +0100 Subject: [PATCH 03/29] fix: fix migration script --- .../addDataProtectionAttributes-rollback.sql | 6 ++++++ .../addDataProtectionAttributes.sql | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes-rollback.sql b/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes-rollback.sql index e322ee1d..9c284b97 100644 --- a/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes-rollback.sql +++ b/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes-rollback.sql @@ -1,2 +1,8 @@ ALTER TABLE `agencyservice`.`agency` DROP COLUMN data_protection_officer_contact longtext; + +ALTER TABLE `agencyservice`.`agency` +DROP COLUMN data_protection_alternative_contact longtext; + +ALTER TABLE `agencyservice`.`agency` +DROP COLUMN data_protection_agency_contact longtext; \ No newline at end of file diff --git a/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes.sql b/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes.sql index f3ad82f9..a158cd8a 100644 --- a/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes.sql +++ b/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes.sql @@ -2,7 +2,7 @@ ALTER TABLE `agencyservice`.`agency` ADD COLUMN data_protection_responsible_entity varchar(100) NULL AFTER `counselling_relations`; ALTER TABLE `agencyservice`.`agency` -ADD COLUMN data_protection_responsible_contact longtext NULL AFTER `data_protection_responsible_entity`; +ADD COLUMN data_protection_alternative_contact longtext NULL AFTER `data_protection_responsible_entity`; ALTER TABLE `agencyservice`.`agency` ADD COLUMN data_protection_officer_contact longtext NULL AFTER `data_protection_responsible_contact`; From c5f22355f74c60c30371d87377d3f45ee2d3e599 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Thu, 9 Nov 2023 13:49:14 +0100 Subject: [PATCH 04/29] fix: fix rollback script --- .../addDataProtectionAttributes-rollback.sql | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes-rollback.sql b/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes-rollback.sql index 9c284b97..6ea803e2 100644 --- a/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes-rollback.sql +++ b/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes-rollback.sql @@ -1,8 +1,11 @@ ALTER TABLE `agencyservice`.`agency` -DROP COLUMN data_protection_officer_contact longtext; +DROP COLUMN data_protection_responsible_entity; ALTER TABLE `agencyservice`.`agency` -DROP COLUMN data_protection_alternative_contact longtext; +DROP COLUMN data_protection_officer_contact; ALTER TABLE `agencyservice`.`agency` -DROP COLUMN data_protection_agency_contact longtext; \ No newline at end of file +DROP COLUMN data_protection_alternative_contact; + +ALTER TABLE `agencyservice`.`agency` +DROP COLUMN data_protection_agency_contact; \ No newline at end of file From 50fa7f8fbf9050a322eb26522ed9175a57cbad43 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Thu, 9 Nov 2023 13:56:17 +0100 Subject: [PATCH 05/29] fix: fix SQL script --- .../addDataProtectionAttributes.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes.sql b/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes.sql index a158cd8a..7ec8a7c9 100644 --- a/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes.sql +++ b/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes.sql @@ -5,7 +5,7 @@ ALTER TABLE `agencyservice`.`agency` ADD COLUMN data_protection_alternative_contact longtext NULL AFTER `data_protection_responsible_entity`; ALTER TABLE `agencyservice`.`agency` -ADD COLUMN data_protection_officer_contact longtext NULL AFTER `data_protection_responsible_contact`; +ADD COLUMN data_protection_officer_contact longtext NULL AFTER `data_protection_alternative_contact`; ALTER TABLE `agencyservice`.`agency` -ADD COLUMN data_protection_agency_contact longtext NULL AFTER `data_protection_officer_contact`; +ADD COLUMN data_protection_agency_contact longtext NULL AFTER `data_protection_officer_contact`; \ No newline at end of file From 86456ed7e5322dcd876e46e4eaaf173ffc274acb Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Tue, 14 Nov 2023 10:04:15 +0100 Subject: [PATCH 06/29] add test to cover testcase of privacy without placeholders --- ...tralDataProtectionTemplateServiceTest.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/test/java/de/caritas/cob/agencyservice/api/service/CentralDataProtectionTemplateServiceTest.java b/src/test/java/de/caritas/cob/agencyservice/api/service/CentralDataProtectionTemplateServiceTest.java index bbb2fe21..fc4c5511 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/service/CentralDataProtectionTemplateServiceTest.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/service/CentralDataProtectionTemplateServiceTest.java @@ -70,6 +70,39 @@ void renderDataProtectionPrivacy_shouldProperlyRenderPrivacy_When_PlaceholdersAr "Privacy template with placeholders: Data protection officer contact name: Max Mustermann, Data protection responsible contact name: Max Mustermann,"); } + @Test + void renderDataProtectionPrivacy_shouldReturnPrivacyAsItIs_When_PlaceholdersAreNotIncludedInPrivacy() { + + // given + when(tenantService.getRestrictedTenantDataByTenantId(anyLong())).thenReturn( + new RestrictedTenantDTO() + .content( + new Content().dataProtectionContactTemplate(getDataProtectionContactTemplate()) + .privacy( + "Privacy template without placeholders"))); + DataProtectionContactDTO dataProtectionContactDTO = new DataProtectionContactDTO() + .nameAndLegalForm("Max Mustermann"); + + Agency agency = Agency.builder() + .id(1000L) + .tenantId(1L) + .consultingTypeId(1) + .name("agencyName") + .dataProtectionResponsibleEntity(DataProtectionResponsibleEntity.DATA_PROTECTION_OFFICER) + .dataProtectionOfficerContactData(JsonConverter.convertToJson(dataProtectionContactDTO)) + .dataProtectionAgencyResponsibleContactData(JsonConverter.convertToJson(dataProtectionContactDTO)) + .build(); + + // when + var renderedPrivacy = centralDataProtectionTemplateService.renderPrivacyTemplateWithRenderedPlaceholderValues( + agency); + + // then + assertThat( + renderedPrivacy).isEqualTo( + "Privacy template without placeholders"); + } + @Test void renderDataProtectionTemplatePlaceholders_shouldProperlyRenderPlaceholders_If_SomeVariableDataIsMissing() { From e319cc6ff02cfecfc0b675972e96f687b615004b Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Tue, 14 Nov 2023 23:22:27 +0100 Subject: [PATCH 07/29] fix: priviliges model, add separate authority to search agencies --- .../api/authorization/Authority.java | 37 ++++++++++++++----- .../RoleAuthorizationAuthorityMapper.java | 3 +- .../agencyservice/config/SecurityConfig.java | 14 +++---- .../api/authorization/AuthorityTest.java | 16 ++++---- .../RoleAuthorizationAuthorityMapperTest.java | 36 +++++++++++++----- 5 files changed, 70 insertions(+), 36 deletions(-) diff --git a/src/main/java/de/caritas/cob/agencyservice/api/authorization/Authority.java b/src/main/java/de/caritas/cob/agencyservice/api/authorization/Authority.java index 4eb6b9bf..fb11c718 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/authorization/Authority.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/authorization/Authority.java @@ -1,24 +1,35 @@ package de.caritas.cob.agencyservice.api.authorization; +import com.google.common.collect.Lists; +import java.util.List; import java.util.stream.Stream; +import lombok.Getter; /** * * Definition of all authorities and of the role-authority-mapping. * */ +@Getter public enum Authority { - AGENCY_ADMIN("agency-admin", "AUTHORIZATION_AGENCY_ADMIN"), - TENANT_ADMIN("tenant-admin", "AUTHORIZATION_TENANT_ADMIN"), - RESTRICTED_AGENCY_ADMIN("restricted-agency-admin", "AUTHORIZATION_RESTRICTED_AGENCY_ADMIN"); + AGENCY_ADMIN("agency-admin", AuthorityValue.AGENCY_ADMIN, AuthorityValue.SEARCH_AGENCIES), + TENANT_ADMIN("tenant-admin", AuthorityValue.TENANT_ADMIN), + RESTRICTED_AGENCY_ADMIN("restricted-agency-admin", AuthorityValue.RESTRICTED_AGENCY_ADMIN, AuthorityValue.SEARCH_AGENCIES), + + RESTRICTED_CONSULTANT_ADMIN("restricted-consultant-admin", AuthorityValue.SEARCH_AGENCIES); private final String roleName; - private final String authorityName; + private final List authorities; Authority(final String roleName, final String authorityName) { this.roleName = roleName; - this.authorityName = authorityName; + this.authorities = Lists.newArrayList(authorityName); + } + + Authority(final String roleName, final String... authorities) { + this.roleName = roleName; + this.authorities = Lists.newArrayList(authorities); } /** @@ -34,12 +45,18 @@ public static Authority fromRoleName(String roleName) { .orElse(null); } - public String getAuthority() { - return this.authorityName; - } - public String getRoleName() { - return this.roleName; + public static class AuthorityValue { + + private AuthorityValue() {} + + public static final String PREFIX = "AUTHORIZATION_"; + public static final String AGENCY_ADMIN = PREFIX + "AGENCY_ADMIN"; + public static final String SEARCH_AGENCIES = PREFIX + "SEARCH_AGENCIES"; + public static final String TENANT_ADMIN = PREFIX + "TENANT_ADMIN"; + public static final String RESTRICTED_AGENCY_ADMIN = PREFIX + "RESTRICTED_AGENCY_ADMIN"; + } + } diff --git a/src/main/java/de/caritas/cob/agencyservice/api/authorization/RoleAuthorizationAuthorityMapper.java b/src/main/java/de/caritas/cob/agencyservice/api/authorization/RoleAuthorizationAuthorityMapper.java index fc99d604..5df9c9b4 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/authorization/RoleAuthorizationAuthorityMapper.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/authorization/RoleAuthorizationAuthorityMapper.java @@ -30,7 +30,8 @@ public Set mapAuthorities(Set roleNames) { return roleNames.stream() .map(Authority::fromRoleName) .filter(Objects::nonNull) - .map(Authority::getAuthority) + .map(Authority::getAuthorities) + .flatMap(Collection::parallelStream) .map(SimpleGrantedAuthority::new) .collect(Collectors.toSet()); } diff --git a/src/main/java/de/caritas/cob/agencyservice/config/SecurityConfig.java b/src/main/java/de/caritas/cob/agencyservice/config/SecurityConfig.java index c5feba44..c5b0e17e 100644 --- a/src/main/java/de/caritas/cob/agencyservice/config/SecurityConfig.java +++ b/src/main/java/de/caritas/cob/agencyservice/config/SecurityConfig.java @@ -1,9 +1,6 @@ package de.caritas.cob.agencyservice.config; -import static de.caritas.cob.agencyservice.api.authorization.Authority.AGENCY_ADMIN; -import static de.caritas.cob.agencyservice.api.authorization.Authority.RESTRICTED_AGENCY_ADMIN; -import static de.caritas.cob.agencyservice.api.authorization.Authority.TENANT_ADMIN; - +import de.caritas.cob.agencyservice.api.authorization.Authority.AuthorityValue; import de.caritas.cob.agencyservice.config.security.AuthorisationService; import de.caritas.cob.agencyservice.config.security.JwtAuthConverter; import de.caritas.cob.agencyservice.config.security.JwtAuthConverterProperties; @@ -16,6 +13,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.core.env.Environment; +import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; @@ -84,11 +82,13 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .requestMatchers("/agencies/**").permitAll() .requestMatchers(WHITE_LIST).permitAll() .requestMatchers("/agencies").permitAll() + .requestMatchers(HttpMethod.GET, "/agencyadmin/agencies") + .hasAuthority(AuthorityValue.SEARCH_AGENCIES) .requestMatchers("/agencyadmin/agencies/tenant/*") - .access("hasAuthority('" + AGENCY_ADMIN.getAuthority() - + "') and hasAuthority('" + TENANT_ADMIN.getAuthority() + "')") + .access("hasAuthority('" + AuthorityValue.AGENCY_ADMIN + + "') and hasAuthority('" + AuthorityValue.TENANT_ADMIN + "')") .requestMatchers("/agencyadmin", "/agencyadmin/", "/agencyadmin/**") - .hasAnyAuthority(AGENCY_ADMIN.getAuthority(), RESTRICTED_AGENCY_ADMIN.getAuthority()) + .hasAnyAuthority(AuthorityValue.AGENCY_ADMIN, AuthorityValue.RESTRICTED_AGENCY_ADMIN) .anyRequest().denyAll(); diff --git a/src/test/java/de/caritas/cob/agencyservice/api/authorization/AuthorityTest.java b/src/test/java/de/caritas/cob/agencyservice/api/authorization/AuthorityTest.java index 0a31a827..46fa0154 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/authorization/AuthorityTest.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/authorization/AuthorityTest.java @@ -2,40 +2,40 @@ import static de.caritas.cob.agencyservice.api.authorization.Authority.AGENCY_ADMIN; import static de.caritas.cob.agencyservice.api.authorization.Authority.fromRoleName; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.nullValue; +import static org.assertj.core.api.Assertions.assertThat; +import de.caritas.cob.agencyservice.api.authorization.Authority.AuthorityValue; +import java.util.List; import org.junit.Test; public class AuthorityTest { @Test public void getAuthority_Should_returnExpectedAuthority_When_authorityIsAgencyAdmin() { - String authority = AGENCY_ADMIN.getAuthority(); + List authorities = AGENCY_ADMIN.getAuthorities(); - assertThat(authority, is("AUTHORIZATION_AGENCY_ADMIN")); + assertThat(authorities).containsOnly(AuthorityValue.AGENCY_ADMIN, AuthorityValue.SEARCH_AGENCIES); } @Test public void fromRoleName_Should_returnNull_When_roleNameIsNull() { Authority authority = fromRoleName(null); - assertThat(authority, nullValue()); + assertThat(authority).isNull(); } @Test public void fromRoleName_Should_returnNull_When_roleNameDoesNotExist() { Authority authority = fromRoleName("not existing"); - assertThat(authority, nullValue()); + assertThat(authority).isNull(); } @Test public void fromRoleName_Should_returnAgencyAdmin_When_roleNameIsAgencyAdmin() { Authority authority = fromRoleName("agency-admin"); - assertThat(authority, is(AGENCY_ADMIN)); + assertThat(authority.getAuthorities()).containsOnly(AuthorityValue.AGENCY_ADMIN, AuthorityValue.SEARCH_AGENCIES); } } diff --git a/src/test/java/de/caritas/cob/agencyservice/api/authorization/RoleAuthorizationAuthorityMapperTest.java b/src/test/java/de/caritas/cob/agencyservice/api/authorization/RoleAuthorizationAuthorityMapperTest.java index 1afd2238..e7af266b 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/authorization/RoleAuthorizationAuthorityMapperTest.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/authorization/RoleAuthorizationAuthorityMapperTest.java @@ -2,10 +2,8 @@ import static de.caritas.cob.agencyservice.api.authorization.Authority.AGENCY_ADMIN; import static java.util.Collections.emptyList; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.is; - +import static org.assertj.core.api.Assertions.assertThat; +import de.caritas.cob.agencyservice.api.authorization.Authority.AuthorityValue; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; @@ -28,8 +26,10 @@ public void mapAuthorities_Should_returnGrantedAgencyAdminAuthority_When_authori Collection mappedAuthorities = this.roleAuthorizationAuthorityMapper .mapAuthorities(grantedAuthorities); - assertThat(mappedAuthorities, hasSize(1)); - assertThat(mappedAuthorities.iterator().next().getAuthority(), is(AGENCY_ADMIN.getAuthority())); + assertThat(mappedAuthorities).hasSize(2); + List authorities = mappedAuthorities.stream() + .map(grantedAuthority -> grantedAuthority.getAuthority()).toList(); + assertThat(authorities).containsAll(AGENCY_ADMIN.getAuthorities()); } @Test @@ -41,8 +41,24 @@ public void mapAuthorities_Should_returnGrantedAgencyAdminAuthority_When_authori Collection mappedAuthorities = this.roleAuthorizationAuthorityMapper .mapAuthorities(grantedAuthorities); - assertThat(mappedAuthorities, hasSize(1)); - assertThat(mappedAuthorities.iterator().next().getAuthority(), is(AGENCY_ADMIN.getAuthority())); + assertThat(mappedAuthorities).hasSize(2); + List authorities = mappedAuthorities.stream() + .map(grantedAuthority -> grantedAuthority.getAuthority()).toList(); + assertThat(authorities).containsAll(AGENCY_ADMIN.getAuthorities()); + + } + + @Test + public void mapAuthorities_Should_returnGrantedAgencySearchAuthority_When_authoritiesRestrictedConsultantAdmin() { + List grantedAuthorities = Stream.of("a", "v", "restricted-consultant-admin", "c") + .map(SimpleGrantedAuthority::new) + .collect(Collectors.toList()); + + Collection mappedAuthorities = this.roleAuthorizationAuthorityMapper + .mapAuthorities(grantedAuthorities); + + assertThat(mappedAuthorities).hasSize(1); + assertThat(mappedAuthorities.iterator().next().getAuthority()).isEqualTo(AuthorityValue.SEARCH_AGENCIES); } @Test @@ -50,7 +66,7 @@ public void mapAuthorities_Should_returnEmptyCollection_When_authorityIsEmpty() Collection mappedAuthorities = this.roleAuthorizationAuthorityMapper .mapAuthorities(emptyList()); - assertThat(mappedAuthorities, hasSize(0)); + assertThat(mappedAuthorities).isEmpty(); } @Test @@ -62,7 +78,7 @@ public void mapAuthorities_Should_returnEmptyCollection_When_authoritiesAreNotPr Collection mappedAuthorities = this.roleAuthorizationAuthorityMapper .mapAuthorities(grantedAuthorities); - assertThat(mappedAuthorities, hasSize(0)); + assertThat(mappedAuthorities).isEmpty(); } } From 71a4c4f4b6db522374cea2a4dcc0ef81f9d9110f Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Wed, 29 Nov 2023 11:15:47 +0100 Subject: [PATCH 08/29] fix: enum type --- .../cob/agencyservice/api/repository/agency/Agency.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/de/caritas/cob/agencyservice/api/repository/agency/Agency.java b/src/main/java/de/caritas/cob/agencyservice/api/repository/agency/Agency.java index f8b67fe2..a2723d72 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/repository/agency/Agency.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/repository/agency/Agency.java @@ -3,6 +3,7 @@ import de.caritas.cob.agencyservice.api.repository.TenantAware; import de.caritas.cob.agencyservice.api.repository.agencypostcoderange.AgencyPostcodeRange; import de.caritas.cob.agencyservice.api.repository.agencytopic.AgencyTopic; +import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; import java.time.LocalDateTime; import java.util.List; @@ -120,7 +121,7 @@ private Integer getPostCodeInteger() { private LocalDateTime updateDate; @Column(name = "data_protection_responsible_entity", nullable = false) - @Enumerated + @Enumerated(EnumType.STRING) private DataProtectionResponsibleEntity dataProtectionResponsibleEntity; From 7e534681216a9954498941bb7abe2c56c3b7f167 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Wed, 29 Nov 2023 11:24:47 +0100 Subject: [PATCH 09/29] fix: null handling for responsible entity --- .../CentralDataProtectionTemplateService.java | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/main/java/de/caritas/cob/agencyservice/api/service/CentralDataProtectionTemplateService.java b/src/main/java/de/caritas/cob/agencyservice/api/service/CentralDataProtectionTemplateService.java index 364cd465..abccb691 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/service/CentralDataProtectionTemplateService.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/service/CentralDataProtectionTemplateService.java @@ -29,15 +29,18 @@ public class CentralDataProtectionTemplateService { public String renderPrivacyTemplateWithRenderedPlaceholderValues(Agency agency) { RestrictedTenantDTO restrictedTenantDataByTenantId = tenantService.getRestrictedTenantDataByTenantId( agency.getTenantId()); - if (restrictedTenantDataByTenantId != null && restrictedTenantDataByTenantId.getContent() != null) { - return renderPrivacyTemplateWithRenderedPlaceholderValues(agency, restrictedTenantDataByTenantId); + if (restrictedTenantDataByTenantId != null + && restrictedTenantDataByTenantId.getContent() != null) { + return renderPrivacyTemplateWithRenderedPlaceholderValues(agency, + restrictedTenantDataByTenantId); } log.debug("No privacy content set for tenant with id: {}", agency.getTenantId()); return null; } @Nullable - private String renderPrivacyTemplateWithRenderedPlaceholderValues(Agency agency, RestrictedTenantDTO restrictedTenantDataByTenantId) { + private String renderPrivacyTemplateWithRenderedPlaceholderValues(Agency agency, + RestrictedTenantDTO restrictedTenantDataByTenantId) { var renderedPlaceholdersMap = renderDataProtectionPlaceholdersFromTemplates(agency); Map dataModel = renderedPlaceholdersMap.entrySet().stream() .collect(Collectors.toMap(entry -> entry.getKey().getPlaceholderVariable(), @@ -76,7 +79,8 @@ protected Map renderDataProtectionPlaceho private String renderDataProtectionResponsibleFromTemplate(Agency agency, DataProtectionContactTemplateDTO dataProtectionContactTemplateDTO) { if (isDataProtectionResponsibleTemplateAvailable(dataProtectionContactTemplateDTO)) { - return renderDataProtectionResponsibleFromTemplateIfAvailable(agency, dataProtectionContactTemplateDTO); + return renderDataProtectionResponsibleFromTemplateIfAvailable(agency, + dataProtectionContactTemplateDTO); } else { log.warn("No data protection responsible template set for tenant with id: {}", agency.getTenantId()); @@ -96,7 +100,8 @@ private String renderDataProtectionResponsibleFromTemplateIfAvailable(Agency age private String renderDataProtectionOfficerContactFromTemplate(Agency agency, DataProtectionContactTemplateDTO dataProtectionContactTemplateDTO) { if (isDataProtectionOfficerTemplateAvailable(dataProtectionContactTemplateDTO)) { - return renderDataProtectionOfficerContactFromTemplateIfAvailable(agency, dataProtectionContactTemplateDTO); + return renderDataProtectionOfficerContactFromTemplateIfAvailable(agency, + dataProtectionContactTemplateDTO); } else { log.warn("No data protection officer template set for tenant with id: {}", agency.getTenantId()); @@ -109,6 +114,14 @@ private String renderDataProtectionOfficerContactFromTemplateIfAvailable(Agency DataProtectionContactTemplateDTO dataProtectionContactTemplateDTO) { final DataProtectionOfficerDTO dataProtectionOfficerDTO = dataProtectionContactTemplateDTO.getAgencyContext() .getDataProtectionOfficer(); + + if (agency.getDataProtectionResponsibleEntity() == null) { + log.warn("No data protection responsible entity set for agency with id: {}", + agency.getId()); + log.warn("Returning null for data protection officer contact template"); + return null; + } + switch (agency.getDataProtectionResponsibleEntity()) { case DATA_PROTECTION_OFFICER -> { var contactDataDTO = JsonConverter.convertFromJsonNullSafe( @@ -129,11 +142,8 @@ private String renderDataProtectionOfficerContactFromTemplateIfAvailable(Agency return renderDataProtectionContactTemplate( dataProtectionOfficerDTO.getAgencyResponsibleContact(), agencyContact); } - default -> { - log.error("No data protection responsible entity set for agency with id: {}", - agency.getId()); - return null; - } + default -> throw new IllegalArgumentException("Unknown data protection responsible entity: " + + agency.getDataProtectionResponsibleEntity()); } } @@ -149,7 +159,8 @@ private boolean isDataProtectionOfficerTemplateAvailable( && dataProtectionContactTemplateDTO.getAgencyContext().getDataProtectionOfficer() != null; } - private boolean isDataProtectionAgencyContextAvailable(DataProtectionContactTemplateDTO dataProtectionContactTemplateDTO) { + private boolean isDataProtectionAgencyContextAvailable( + DataProtectionContactTemplateDTO dataProtectionContactTemplateDTO) { return dataProtectionContactTemplateDTO != null && dataProtectionContactTemplateDTO.getAgencyContext() != null; } From 1d63784348c0fd591a658630482641e4bffcff8a Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Thu, 30 Nov 2023 12:43:36 +0100 Subject: [PATCH 10/29] fix: null handling for rendered template --- .../CentralDataProtectionTemplateService.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/main/java/de/caritas/cob/agencyservice/api/service/CentralDataProtectionTemplateService.java b/src/main/java/de/caritas/cob/agencyservice/api/service/CentralDataProtectionTemplateService.java index abccb691..f050c374 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/service/CentralDataProtectionTemplateService.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/service/CentralDataProtectionTemplateService.java @@ -65,12 +65,17 @@ protected Map renderDataProtectionPlaceho && restrictedTenantDataByTenantId.getContent().getDataProtectionContactTemplate() != null) { var renderedDataProtectionOfficerContact = renderDataProtectionOfficerContactFromTemplate( agency, restrictedTenantDataByTenantId.getContent().getDataProtectionContactTemplate()); - result.put(DataProtectionPlaceHolderType.DATA_PROTECTION_OFFICER, - renderedDataProtectionOfficerContact); + + if (renderedDataProtectionOfficerContact != null) { + result.put(DataProtectionPlaceHolderType.DATA_PROTECTION_OFFICER, + renderedDataProtectionOfficerContact); + } var renderedDataProtectionResponsible = renderDataProtectionResponsibleFromTemplate( agency, restrictedTenantDataByTenantId.getContent().getDataProtectionContactTemplate()); - result.put(DataProtectionPlaceHolderType.DATA_PROTECTION_RESPONSIBLE, - renderedDataProtectionResponsible); + if (renderedDataProtectionResponsible != null) { + result.put(DataProtectionPlaceHolderType.DATA_PROTECTION_RESPONSIBLE, + renderedDataProtectionResponsible); + } } return result; } From b20dd52614f72c9db1a9b348ee8ec5bdf0d3b1fc Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Thu, 30 Nov 2023 17:36:14 +0100 Subject: [PATCH 11/29] fix: null handling for rendered template --- .../CentralDataProtectionTemplateService.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/java/de/caritas/cob/agencyservice/api/service/CentralDataProtectionTemplateService.java b/src/main/java/de/caritas/cob/agencyservice/api/service/CentralDataProtectionTemplateService.java index f050c374..c688d067 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/service/CentralDataProtectionTemplateService.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/service/CentralDataProtectionTemplateService.java @@ -14,6 +14,7 @@ import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import de.caritas.cob.agencyservice.tenantservice.generated.web.model.RestrictedTenantDTO; @@ -66,16 +67,16 @@ protected Map renderDataProtectionPlaceho var renderedDataProtectionOfficerContact = renderDataProtectionOfficerContactFromTemplate( agency, restrictedTenantDataByTenantId.getContent().getDataProtectionContactTemplate()); - if (renderedDataProtectionOfficerContact != null) { - result.put(DataProtectionPlaceHolderType.DATA_PROTECTION_OFFICER, - renderedDataProtectionOfficerContact); - } + + result.put(DataProtectionPlaceHolderType.DATA_PROTECTION_OFFICER, + renderedDataProtectionOfficerContact != null ? renderedDataProtectionOfficerContact : StringUtils.EMPTY); + var renderedDataProtectionResponsible = renderDataProtectionResponsibleFromTemplate( agency, restrictedTenantDataByTenantId.getContent().getDataProtectionContactTemplate()); - if (renderedDataProtectionResponsible != null) { - result.put(DataProtectionPlaceHolderType.DATA_PROTECTION_RESPONSIBLE, - renderedDataProtectionResponsible); - } + + result.put(DataProtectionPlaceHolderType.DATA_PROTECTION_RESPONSIBLE, + renderedDataProtectionResponsible != null ? renderedDataProtectionResponsible : StringUtils.EMPTY); + } return result; } From 7d46d8a02ba178033482b17799b098865ffd5bff Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Thu, 21 Dec 2023 15:18:54 +0100 Subject: [PATCH 12/29] feat: add possibility to persist data protection information --- api/agencyadminservice.yaml | 3 + .../api/admin/service/AgencyAdminService.java | 9 +- .../agency/DataProtectionConverter.java | 50 ++++++++ .../agencyservice/api/util/JsonConverter.java | 3 + .../agency/DataProtectionConverterTest.java | 112 ++++++++++++++++++ 5 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 src/main/java/de/caritas/cob/agencyservice/api/admin/service/agency/DataProtectionConverter.java create mode 100644 src/test/java/de/caritas/cob/agencyservice/api/admin/service/agency/DataProtectionConverterTest.java diff --git a/api/agencyadminservice.yaml b/api/agencyadminservice.yaml index 45abe22d..237dbf1c 100644 --- a/api/agencyadminservice.yaml +++ b/api/agencyadminservice.yaml @@ -690,6 +690,9 @@ components: items: type: string enum: [ RELATIVE_COUNSELLING, SELF_COUNSELLING, PARENTAL_COUNSELLING ] + dataProtection: + type: object + $ref: '#/components/schemas/DataProtectionDTO' DemographicsDTO: type: object diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminService.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminService.java index 598ebba9..d793df01 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminService.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminService.java @@ -8,6 +8,7 @@ import com.google.common.base.Joiner; import de.caritas.cob.agencyservice.api.admin.service.agency.AgencyAdminFullResponseDTOBuilder; import de.caritas.cob.agencyservice.api.admin.service.agency.AgencyTopicEnrichmentService; +import de.caritas.cob.agencyservice.api.admin.service.agency.DataProtectionConverter; import de.caritas.cob.agencyservice.api.admin.service.agency.DemographicsConverter; import de.caritas.cob.agencyservice.api.admin.validation.DeleteAgencyValidator; import de.caritas.cob.agencyservice.api.exception.httpresponses.ConflictException; @@ -26,7 +27,6 @@ import java.time.ZoneOffset; import java.util.Arrays; import java.util.List; -import java.util.stream.Collectors; import lombok.NonNull; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; @@ -55,6 +55,9 @@ public class AgencyAdminService { @Autowired(required = false) private DemographicsConverter demographicsConverter; + @Autowired(required = false) + private DataProtectionConverter dataProtectionConverter; + @Value("${feature.topics.enabled}") private boolean featureTopicsEnabled; @@ -207,6 +210,8 @@ private Agency mergeAgencies(Agency agency, UpdateAgencyDTO updateAgencyDTO) { .counsellingRelations(agency.getCounsellingRelations()) .deleteDate(agency.getDeleteDate()); + dataProtectionConverter.convertToEntity(updateAgencyDTO.getDataProtection(), agencyBuilder); + if (nonNull(updateAgencyDTO.getConsultingType())) { agencyBuilder.consultingTypeId(updateAgencyDTO.getConsultingType()); } else { @@ -235,6 +240,8 @@ private Agency mergeAgencies(Agency agency, UpdateAgencyDTO updateAgencyDTO) { } + + /** * Changes the type of the agency. * diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/service/agency/DataProtectionConverter.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/service/agency/DataProtectionConverter.java new file mode 100644 index 00000000..3f564bec --- /dev/null +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/service/agency/DataProtectionConverter.java @@ -0,0 +1,50 @@ +package de.caritas.cob.agencyservice.api.admin.service.agency; + +import de.caritas.cob.agencyservice.api.model.DataProtectionDTO; +import de.caritas.cob.agencyservice.api.repository.agency.Agency.AgencyBuilder; +import de.caritas.cob.agencyservice.api.repository.agency.DataProtectionResponsibleEntity; +import de.caritas.cob.agencyservice.api.util.JsonConverter; +import org.springframework.stereotype.Component; + +@Component +public class DataProtectionConverter { + + public void convertToEntity(DataProtectionDTO dataProtectionDTO, AgencyBuilder agencyBuilder) { + if (dataProtectionDTO != null) { + agencyBuilder.dataProtectionResponsibleEntity(convertEnums(dataProtectionDTO)); + agencyBuilder.dataProtectionOfficerContactData( + JsonConverter.convertToJson(dataProtectionDTO.getDataProtectionOfficerContact())); + agencyBuilder.dataProtectionAgencyResponsibleContactData(JsonConverter.convertToJson( + dataProtectionDTO.getAgencyDataProtectionResponsibleContact())); + agencyBuilder.dataProtectionAlternativeContactData(JsonConverter.convertToJson( + dataProtectionDTO.getAlternativeDataProtectionRepresentativeContact())); + } else { + nullifyDataProtectionAttributes(agencyBuilder); + } + } + + private static void nullifyDataProtectionAttributes(AgencyBuilder agencyBuilder) { + agencyBuilder.dataProtectionResponsibleEntity(null); + agencyBuilder.dataProtectionOfficerContactData(null); + agencyBuilder.dataProtectionAgencyResponsibleContactData(null); + agencyBuilder.dataProtectionAlternativeContactData(null); + } + + private static DataProtectionResponsibleEntity convertEnums( + DataProtectionDTO dataProtectionDTO) { + var dataProtectionEntity = dataProtectionDTO.getDataProtectionResponsibleEntity(); + if (dataProtectionEntity == null) { + return null; + } + switch (dataProtectionEntity) { + case AGENCY_RESPONSIBLE: + return DataProtectionResponsibleEntity.AGENCY_RESPONSIBLE; + case DATA_PROTECTION_OFFICER: + return DataProtectionResponsibleEntity.DATA_PROTECTION_OFFICER; + case ALTERNATIVE_REPRESENTATIVE: + return DataProtectionResponsibleEntity.ALTERNATIVE_REPRESENTATIVE; + } + return null; + } + +} diff --git a/src/main/java/de/caritas/cob/agencyservice/api/util/JsonConverter.java b/src/main/java/de/caritas/cob/agencyservice/api/util/JsonConverter.java index a44eab8b..5d1c9686 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/util/JsonConverter.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/util/JsonConverter.java @@ -14,6 +14,9 @@ private JsonConverter() { } public static String convertToJson(Object object) { + if (object == null) { + return null; + } return serializeToJsonString(object); } diff --git a/src/test/java/de/caritas/cob/agencyservice/api/admin/service/agency/DataProtectionConverterTest.java b/src/test/java/de/caritas/cob/agencyservice/api/admin/service/agency/DataProtectionConverterTest.java new file mode 100644 index 00000000..aa91c3e0 --- /dev/null +++ b/src/test/java/de/caritas/cob/agencyservice/api/admin/service/agency/DataProtectionConverterTest.java @@ -0,0 +1,112 @@ +package de.caritas.cob.agencyservice.api.admin.service.agency; + +import de.caritas.cob.agencyservice.api.model.DataProtectionContactDTO; +import de.caritas.cob.agencyservice.api.model.DataProtectionDTO; +import de.caritas.cob.agencyservice.api.model.DataProtectionDTO.DataProtectionResponsibleEntityEnum; +import de.caritas.cob.agencyservice.api.repository.agency.Agency; +import de.caritas.cob.agencyservice.api.repository.agency.Agency.AgencyBuilder; +import de.caritas.cob.agencyservice.api.repository.agency.DataProtectionResponsibleEntity; +import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; + +class DataProtectionConverterTest { + + @Test + void convertToEntity_Should_Convert_When_AllParamsAreNull() { + // given + DataProtectionDTO dataProtectionDTO = new DataProtectionDTO(); + DataProtectionConverter dataProtectionConverter = new DataProtectionConverter(); + AgencyBuilder builder = Agency.builder().name("test").consultingTypeId(1); + + // when + dataProtectionConverter.convertToEntity(dataProtectionDTO, builder); + Agency agency = builder.build(); + + // then + assertThat(agency.getDataProtectionResponsibleEntity()).isNull(); + assertThat(agency.getDataProtectionAlternativeContactData()).isNull(); + assertThat(agency.getDataProtectionOfficerContactData()).isNull(); + assertThat(agency.getDataProtectionAgencyResponsibleContactData()).isNull(); + } + + @Test + void convertToEntity_Should_Convert_When_DataProtectionDTOIsNull() { + // given + DataProtectionConverter dataProtectionConverter = new DataProtectionConverter(); + AgencyBuilder builder = Agency.builder().name("test").consultingTypeId(1); + + // when + dataProtectionConverter.convertToEntity(null, builder); + Agency agency = builder.build(); + + // then + assertThat(agency.getDataProtectionResponsibleEntity()).isNull(); + assertThat(agency.getDataProtectionAlternativeContactData()).isNull(); + assertThat(agency.getDataProtectionOfficerContactData()).isNull(); + assertThat(agency.getDataProtectionAgencyResponsibleContactData()).isNull(); + } + + @Test + void convertToEntity_Should_Convert_When_AgencyResponsible_IsNotNull() { + // given + DataProtectionConverter dataProtectionConverter = new DataProtectionConverter(); + AgencyBuilder builder = Agency.builder().name("test").consultingTypeId(1); + var dataProtectionDTO = new DataProtectionDTO().dataProtectionResponsibleEntity(DataProtectionDTO.DataProtectionResponsibleEntityEnum.AGENCY_RESPONSIBLE) + .agencyDataProtectionResponsibleContact(new DataProtectionContactDTO().nameAndLegalForm("agency data responsible")); + + // when + dataProtectionConverter.convertToEntity(dataProtectionDTO, builder); + Agency agency = builder.build(); + + // then + assertThat(agency.getDataProtectionResponsibleEntity()).isEqualTo( + DataProtectionResponsibleEntity.AGENCY_RESPONSIBLE); + assertThat(agency.getDataProtectionAlternativeContactData()).isNull(); + assertThat(agency.getDataProtectionOfficerContactData()).isNull(); + assertThat(agency.getDataProtectionAgencyResponsibleContactData()).isNotNull(); + } + + @Test + void convertToEntity_Should_Convert_When_DataProtectionOfficer_IsNotNull() { + // given + DataProtectionConverter dataProtectionConverter = new DataProtectionConverter(); + AgencyBuilder builder = Agency.builder().name("test").consultingTypeId(1); + var dataProtectionDTO = new DataProtectionDTO().dataProtectionResponsibleEntity( + DataProtectionResponsibleEntityEnum.DATA_PROTECTION_OFFICER) + .dataProtectionOfficerContact(new DataProtectionContactDTO().nameAndLegalForm("data protection officer data")); + + // when + dataProtectionConverter.convertToEntity(dataProtectionDTO, builder); + Agency agency = builder.build(); + + // then + assertThat(agency.getDataProtectionResponsibleEntity()).isEqualTo( + DataProtectionResponsibleEntity.DATA_PROTECTION_OFFICER); + assertThat(agency.getDataProtectionAlternativeContactData()).isNull(); + assertThat(agency.getDataProtectionOfficerContactData()).isNotNull(); + assertThat(agency.getDataProtectionAgencyResponsibleContactData()).isNull(); + } + + @Test + void convertToEntity_Should_Convert_When_AlternativeRepresentative_IsNotNull() { + // given + DataProtectionConverter dataProtectionConverter = new DataProtectionConverter(); + AgencyBuilder builder = Agency.builder().name("test").consultingTypeId(1); + var dataProtectionDTO = new DataProtectionDTO().dataProtectionResponsibleEntity( + DataProtectionResponsibleEntityEnum.ALTERNATIVE_REPRESENTATIVE) + .alternativeDataProtectionRepresentativeContact(new DataProtectionContactDTO().nameAndLegalForm("alternative representative data")); + + // when + dataProtectionConverter.convertToEntity(dataProtectionDTO, builder); + Agency agency = builder.build(); + + // then + assertThat(agency.getDataProtectionResponsibleEntity()).isEqualTo( + DataProtectionResponsibleEntity.ALTERNATIVE_REPRESENTATIVE); + assertThat(agency.getDataProtectionAlternativeContactData()).isNotNull(); + assertThat(agency.getDataProtectionOfficerContactData()).isNull(); + assertThat(agency.getDataProtectionAgencyResponsibleContactData()).isNull(); + } + + +} From ba591752269b0f52cb4e7617d1a347dab03f45c7 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Thu, 21 Dec 2023 15:21:03 +0100 Subject: [PATCH 13/29] fix: checkstyle --- .../api/admin/service/agency/DataProtectionConverter.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/service/agency/DataProtectionConverter.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/service/agency/DataProtectionConverter.java index 3f564bec..fe5d7b29 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/admin/service/agency/DataProtectionConverter.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/service/agency/DataProtectionConverter.java @@ -43,8 +43,10 @@ private static DataProtectionResponsibleEntity convertEnums( return DataProtectionResponsibleEntity.DATA_PROTECTION_OFFICER; case ALTERNATIVE_REPRESENTATIVE: return DataProtectionResponsibleEntity.ALTERNATIVE_REPRESENTATIVE; + default: + throw new IllegalArgumentException( + "DataProtectionResponsibleEntity not supported: " + dataProtectionEntity); } - return null; } } From a7f2b14e8440bf1f16fb0c9679c3a98e310bf44c Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Thu, 21 Dec 2023 15:27:58 +0100 Subject: [PATCH 14/29] fix: tests --- .../agencyservice/api/admin/service/AgencyAdminService.java | 6 ++++-- .../api/admin/service/AgencyAdminServiceTest.java | 4 ++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminService.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminService.java index d793df01..07b9438c 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminService.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminService.java @@ -55,7 +55,7 @@ public class AgencyAdminService { @Autowired(required = false) private DemographicsConverter demographicsConverter; - @Autowired(required = false) + @Autowired private DataProtectionConverter dataProtectionConverter; @Value("${feature.topics.enabled}") @@ -210,7 +210,9 @@ private Agency mergeAgencies(Agency agency, UpdateAgencyDTO updateAgencyDTO) { .counsellingRelations(agency.getCounsellingRelations()) .deleteDate(agency.getDeleteDate()); - dataProtectionConverter.convertToEntity(updateAgencyDTO.getDataProtection(), agencyBuilder); + if (dataProtectionConverter != null) { + dataProtectionConverter.convertToEntity(updateAgencyDTO.getDataProtection(), agencyBuilder); + } if (nonNull(updateAgencyDTO.getConsultingType())) { agencyBuilder.consultingTypeId(updateAgencyDTO.getConsultingType()); diff --git a/src/test/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminServiceTest.java b/src/test/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminServiceTest.java index bf18540d..982f483d 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminServiceTest.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminServiceTest.java @@ -18,6 +18,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.Lists; import de.caritas.cob.agencyservice.api.admin.service.agency.AgencyTopicEnrichmentService; +import de.caritas.cob.agencyservice.api.admin.service.agency.DataProtectionConverter; import de.caritas.cob.agencyservice.api.admin.service.agency.DemographicsConverter; import de.caritas.cob.agencyservice.api.admin.validation.DeleteAgencyValidator; import de.caritas.cob.agencyservice.api.exception.httpresponses.ConflictException; @@ -74,6 +75,9 @@ class AgencyAdminServiceTest { @Mock DemographicsConverter demographicsConverter; + @Mock + DataProtectionConverter dataProtectionConverter; + @Mock AppointmentService appointmentService; From f58920a9578532576287ffaee22a7f0bf625d9c2 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Fri, 22 Dec 2023 13:15:32 +0100 Subject: [PATCH 15/29] fix: converter --- .../agency/DataProtectionDTOBuilder.java | 69 ++++++++----------- .../controller/AgencyAdminControllerIT.java | 53 ++++++++++++++ 2 files changed, 81 insertions(+), 41 deletions(-) diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/service/agency/DataProtectionDTOBuilder.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/service/agency/DataProtectionDTOBuilder.java index ad911450..88683bea 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/admin/service/agency/DataProtectionDTOBuilder.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/service/agency/DataProtectionDTOBuilder.java @@ -4,7 +4,9 @@ import de.caritas.cob.agencyservice.api.model.DataProtectionDTO; import de.caritas.cob.agencyservice.api.model.DataProtectionDTO.DataProtectionResponsibleEntityEnum; import de.caritas.cob.agencyservice.api.repository.agency.Agency; +import de.caritas.cob.agencyservice.api.repository.agency.DataProtectionResponsibleEntity; import de.caritas.cob.agencyservice.api.util.JsonConverter; +import java.util.function.Supplier; import lombok.NonNull; import lombok.RequiredArgsConstructor; @@ -13,60 +15,45 @@ public class DataProtectionDTOBuilder { private final @NonNull Agency agency; - public DataProtectionDTO fromAgency() { if (agency.getDataProtectionResponsibleEntity() == null) { return null; } - switch (this.agency.getDataProtectionResponsibleEntity()) { - case AGENCY_RESPONSIBLE: - return getAgencyResponsibleDataProtectionDTO(); - case ALTERNATIVE_REPRESENTATIVE: - return getAlternativeRepresentative(); - case DATA_PROTECTION_OFFICER: - return getDataProtectionOfficerDTO(); - default: - return null; - } + return new DataProtectionDTO() + .dataProtectionResponsibleEntity(convertEnums(agency.getDataProtectionResponsibleEntity())) + .agencyDataProtectionResponsibleContact( + convertNullSafe(agency::getDataProtectionAgencyResponsibleContactData)) + .alternativeDataProtectionRepresentativeContact( + convertNullSafe(agency::getDataProtectionAlternativeContactData)) + .dataProtectionOfficerContact( + convertNullSafe(agency::getDataProtectionOfficerContactData)); } - private DataProtectionDTO getDataProtectionOfficerDTO() { - String dataProtectionOfficerContactData = this.agency.getDataProtectionOfficerContactData(); - if (dataProtectionOfficerContactData == null) { + private DataProtectionContactDTO convertNullSafe(Supplier dataProtectionDataSupplier) { + if (dataProtectionDataSupplier.get() == null) { return null; + } else { + return JsonConverter.convertFromJson(dataProtectionDataSupplier.get()); } - DataProtectionContactDTO dataProtectionContactDTO = JsonConverter.convertFromJson( - dataProtectionOfficerContactData); - return new DataProtectionDTO() - .dataProtectionResponsibleEntity( - DataProtectionResponsibleEntityEnum.DATA_PROTECTION_OFFICER) - .dataProtectionOfficerContact(dataProtectionContactDTO); } - private DataProtectionDTO getAlternativeRepresentative() { - String dataProtectionAlternativeContactData = this.agency.getDataProtectionAlternativeContactData(); - if (dataProtectionAlternativeContactData == null) { - return null; - } - DataProtectionContactDTO dataProtectionContactDTO = JsonConverter.convertFromJson( - dataProtectionAlternativeContactData); - return new DataProtectionDTO() - .dataProtectionResponsibleEntity( - DataProtectionResponsibleEntityEnum.ALTERNATIVE_REPRESENTATIVE) - .alternativeDataProtectionRepresentativeContact(dataProtectionContactDTO); - } + private static DataProtectionResponsibleEntityEnum convertEnums( + DataProtectionResponsibleEntity dataProtectionEntity) { - private DataProtectionDTO getAgencyResponsibleDataProtectionDTO() { - String dataProtectionAgencyResponsibleContactData = this.agency.getDataProtectionAgencyResponsibleContactData(); - if (dataProtectionAgencyResponsibleContactData == null) { - return null; + switch (dataProtectionEntity) { + case AGENCY_RESPONSIBLE: + return DataProtectionDTO.DataProtectionResponsibleEntityEnum.AGENCY_RESPONSIBLE; + case DATA_PROTECTION_OFFICER: + return DataProtectionDTO.DataProtectionResponsibleEntityEnum.DATA_PROTECTION_OFFICER; + case ALTERNATIVE_REPRESENTATIVE: + return DataProtectionDTO.DataProtectionResponsibleEntityEnum.ALTERNATIVE_REPRESENTATIVE; + default: + throw new IllegalArgumentException( + "DataProtectionResponsibleEntity not supported: " + dataProtectionEntity); } - DataProtectionContactDTO dataProtectionContactDTO = JsonConverter.convertFromJson( - dataProtectionAgencyResponsibleContactData); - return new DataProtectionDTO() - .dataProtectionResponsibleEntity(DataProtectionResponsibleEntityEnum.AGENCY_RESPONSIBLE) - .agencyDataProtectionResponsibleContact(dataProtectionContactDTO); } + + } diff --git a/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerIT.java b/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerIT.java index 4b1fb43a..f5005e2b 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerIT.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerIT.java @@ -14,6 +14,8 @@ import com.google.common.collect.Lists; import de.caritas.cob.agencyservice.api.admin.service.UserAdminService; +import de.caritas.cob.agencyservice.api.model.DataProtectionContactDTO; +import de.caritas.cob.agencyservice.api.model.DataProtectionDTO; import de.caritas.cob.agencyservice.api.util.AuthenticatedUser; import de.caritas.cob.agencyservice.api.manager.consultingtype.ConsultingTypeManager; import de.caritas.cob.agencyservice.api.model.AgencyDTO; @@ -34,6 +36,7 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.context.WebApplicationContext; @@ -242,6 +245,56 @@ void updateAgency_Should_returnStatusOk_When_calledWithEmptyDescription() throws assertNull(savedAgency.getDescription()); } + @Test + @WithMockUser(authorities = "AUTHORIZATION_AGENCY_ADMIN") + void updateAgency_Should_persistDataProtectionAttributes_When_payloadContainsDataProtection() throws Exception { + var response = new ExtendedConsultingTypeResponseDTO(); + when(consultingTypeManager.getConsultingTypeSettings(anyInt())).thenReturn(response); + + var agencyDTO = new UpdateAgencyDTO() + .name("Test update name") + .description(null) + .offline(true) + .external(false) + .dataProtection(new DataProtectionDTO() + .dataProtectionResponsibleEntity(DataProtectionDTO.DataProtectionResponsibleEntityEnum.AGENCY_RESPONSIBLE) + .agencyDataProtectionResponsibleContact(new DataProtectionContactDTO().nameAndLegalForm("agency responsible contact") + .city("Freiburg").postcode("99999").phoneNumber("123-123-123").email("agency@onlineberatung.net") + ) + .dataProtectionOfficerContact(new DataProtectionContactDTO().nameAndLegalForm("data protection contact").city("Munich") + .postcode("00001").phoneNumber("321-321-321").email("dataprotection@onlineberatung.net") + )); + + mockMvc.perform(put(PathConstants.UPDATE_DELETE_AGENCY_PATH) + .contentType(APPLICATION_JSON) + .content(JsonConverter.convertToJson(agencyDTO))) + .andExpect(status().isOk()) + .andExpect(jsonPath("_embedded.id").value(1)) + .andExpect(jsonPath("_embedded.name").value("Test update name")) + .andExpect(jsonPath("_embedded.description").isEmpty()) + .andExpect(jsonPath("_embedded.teamAgency").value("false")) + .andExpect(jsonPath("_embedded.external").value("false")) + .andExpect(jsonPath("_embedded.offline").exists()) + .andExpect(jsonPath("_embedded.topics").exists()) + .andExpect(jsonPath("_embedded.createDate").exists()) + .andExpect(jsonPath("_embedded.updateDate").exists()) + .andExpect(jsonPath("_embedded.deleteDate").exists()) + .andExpect(jsonPath("_embedded.dataProtection.dataProtectionResponsibleEntity").value("AGENCY_RESPONSIBLE")) + .andExpect(jsonPath("_embedded.dataProtection.agencyDataProtectionResponsibleContact.nameAndLegalForm").value("agency responsible contact")) + .andExpect(jsonPath("_embedded.dataProtection.agencyDataProtectionResponsibleContact.city").value("Freiburg")) + .andExpect(jsonPath("_embedded.dataProtection.agencyDataProtectionResponsibleContact.postcode").value("99999")) + .andExpect(jsonPath("_embedded.dataProtection.agencyDataProtectionResponsibleContact.phoneNumber").value("123-123-123")) + .andExpect(jsonPath("_embedded.dataProtection.agencyDataProtectionResponsibleContact.email").value("agency@onlineberatung.net")) + .andExpect(jsonPath("_embedded.dataProtection.dataProtectionOfficerContact.nameAndLegalForm").value("data protection contact")) + .andExpect(jsonPath("_embedded.dataProtection.dataProtectionOfficerContact.city").value("Munich")) + .andExpect(jsonPath("_embedded.dataProtection.dataProtectionOfficerContact.postcode").value("00001")) + .andExpect(jsonPath("_embedded.dataProtection.dataProtectionOfficerContact.phoneNumber").value("321-321-321")) + .andExpect(jsonPath("_embedded.dataProtection.dataProtectionOfficerContact.email").value("dataprotection@onlineberatung.net")); + + var savedAgency = agencyRepository.findById(1L).orElseThrow(); + assertNull(savedAgency.getDescription()); + } + @Test @WithMockUser(authorities = {"AUTHORIZATION_RESTRICTED_AGENCY_ADMIN"}) void updateAgency_Should_returnStatusOk_When_calledWithRestrictedAgencyAdminThatHasPermissionForGivenAgency() From b777e1f21af9a4ff7a2c4e6b8369301794745b1e Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Fri, 22 Dec 2023 13:23:00 +0100 Subject: [PATCH 16/29] fix: tests --- .../api/admin/service/AgencyAdminServiceTest.java | 15 +++++++++++++-- .../AgencyAdminFullResponseDTOBuilderTest.java | 1 + 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/test/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminServiceTest.java b/src/test/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminServiceTest.java index 982f483d..edf30c75 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminServiceTest.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminServiceTest.java @@ -111,7 +111,7 @@ void createAgency_Should_CreateAgencyAndAddDefaultCounsellingRelations() { var agency = this.easyRandom.nextObject(Agency.class); agency.setCounsellingRelations(null); agency.setDataProtectionOfficerContactData(null); - agency.setDataProtectionResponsibleEntity(null); + clearDataProtection(agency); var agencyDTO = this.easyRandom.nextObject(AgencyDTO.class); agencyDTO.setCounsellingRelations(null); agencyDTO.setConsultingType(1); @@ -125,6 +125,7 @@ void createAgency_Should_CreateAgencyAndAddDefaultCounsellingRelations() { @Test void updateAgency_Should_SaveAgencyMandatoryChanges_WhenAgencyIsFound() { var agency = this.easyRandom.nextObject(Agency.class); + clearDataProtection(agency); DataProtectionContactDTO dataProtectionContactDTO = this.easyRandom.nextObject(DataProtectionContactDTO.class); agency.setDataProtectionOfficerContactData(JsonConverter.convertToJson(dataProtectionContactDTO)); agency.setDataProtectionAlternativeContactData(null); @@ -143,12 +144,21 @@ void updateAgency_Should_SaveAgencyMandatoryChanges_WhenAgencyIsFound() { assertEquals(agency.getConsultingTypeId(), passedConsultingTypeId); } + private void clearDataProtection(Agency agency) { + agency.setDataProtectionResponsibleEntity(null); + agency.setDataProtectionAgencyResponsibleContactData(null); + agency.setDataProtectionAlternativeContactData(null); + agency.setDataProtectionOfficerContactData(null); + } + @Test void updateAgency_Should_SaveOptionalAgencyChanges_WhenAgencyIsFound() { var agency = easyRandom.nextObject(Agency.class); agency.setCounsellingRelations(AgencyAdminResponseDTO.CounsellingRelationsEnum.PARENTAL_COUNSELLING.getValue()); agency.setDataProtectionResponsibleEntity(DataProtectionResponsibleEntity.ALTERNATIVE_REPRESENTATIVE); agency.setDataProtectionAlternativeContactData(JsonConverter.convertToJson(new DataProtectionContactDTO())); + agency.setDataProtectionOfficerContactData(null); + agency.setDataProtectionAgencyResponsibleContactData(null); when(agencyRepository.findById(AGENCY_ID)).thenReturn(Optional.of(agency)); when(agencyRepository.save(any())).thenReturn(agency); @@ -168,7 +178,7 @@ void updateAgency_Should_SaveAgencyChanges_WhenAgencyIsFoundAndTopicFeatureEnabl // given ReflectionTestUtils.setField(agencyAdminService, "featureTopicsEnabled", true); var agency = this.easyRandom.nextObject(Agency.class); - agency.setDataProtectionResponsibleEntity(null); + clearDataProtection(agency); agency.setCounsellingRelations(null); when(agencyRepository.findById(AGENCY_ID)).thenReturn(Optional.of(agency)); when(agencyRepository.save(any())).thenReturn(agency); @@ -189,6 +199,7 @@ void updateAgency_Should_SaveAgencyChanges_WhenAgencyIsFoundAndDemographicsFeatu // given ReflectionTestUtils.setField(agencyAdminService, "featureDemographicsEnabled", true); var agency = this.easyRandom.nextObject(Agency.class); + clearDataProtection(agency); agency.setDataProtectionAgencyResponsibleContactData(null); agency.setDataProtectionResponsibleEntity(DataProtectionResponsibleEntity.AGENCY_RESPONSIBLE); agency.setCounsellingRelations(AgencyAdminResponseDTO.CounsellingRelationsEnum.PARENTAL_COUNSELLING.getValue()); diff --git a/src/test/java/de/caritas/cob/agencyservice/api/admin/service/agency/AgencyAdminFullResponseDTOBuilderTest.java b/src/test/java/de/caritas/cob/agencyservice/api/admin/service/agency/AgencyAdminFullResponseDTOBuilderTest.java index 539eef6d..7780435c 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/admin/service/agency/AgencyAdminFullResponseDTOBuilderTest.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/admin/service/agency/AgencyAdminFullResponseDTOBuilderTest.java @@ -32,6 +32,7 @@ public void init() { this.agency.setDataProtectionResponsibleEntity(DataProtectionResponsibleEntity.AGENCY_RESPONSIBLE); this.agency.setDataProtectionAgencyResponsibleContactData(JsonConverter.convertToJson(new DataProtectionContactDTO())); this.agency.setDataProtectionOfficerContactData(JsonConverter.convertToJson(new DataProtectionContactDTO())); + this.agency.setDataProtectionAlternativeContactData(JsonConverter.convertToJson(new DataProtectionContactDTO())); this.agency.setTenantId(TENANT_ID); this.agencyAdminFullResponseDTOBuilder = new AgencyAdminFullResponseDTOBuilder(agency); this.agency.setCounsellingRelations(AgencyDTO.CounsellingRelationsEnum.PARENTAL_COUNSELLING.getValue() + "," + AgencyDTO.CounsellingRelationsEnum.RELATIVE_COUNSELLING.getValue()); From 6bad3fd35597350431b7a74ef72be036db8bae21 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Wed, 27 Dec 2023 18:16:01 +0100 Subject: [PATCH 17/29] fix: tests --- .../api/admin/validation/AgencyValidator.java | 8 + ...AgencyDataProtectionValidationService.java | 66 ++++++ .../AgencyDataProtectionValidator.java | 42 ++++ .../AgencyOfflineStatusValidator.java | 3 +- .../validators/model/ValidateAgencyDTO.java | 4 + .../HttpStatusExceptionReason.java | 5 +- .../agency/DataProtectionPlaceHolderType.java | 28 +++ ...cyDataProtectionValidationServiceTest.java | 224 ++++++++++++++++++ .../AgencyDataProtectionValidatorTest.java | 101 ++++++++ .../controller/AgencyAdminControllerIT.java | 9 + ...encyAdminControllerWithDemographicsIT.java | 8 + .../AgencyAdminControllerWithTopicsIT.java | 7 + 12 files changed, 503 insertions(+), 2 deletions(-) create mode 100644 src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidationService.java create mode 100644 src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidator.java create mode 100644 src/main/java/de/caritas/cob/agencyservice/api/repository/agency/DataProtectionPlaceHolderType.java create mode 100644 src/test/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidationServiceTest.java create mode 100644 src/test/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidatorTest.java diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/AgencyValidator.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/AgencyValidator.java index 35044052..08c869bb 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/AgencyValidator.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/AgencyValidator.java @@ -4,8 +4,10 @@ import de.caritas.cob.agencyservice.api.admin.validation.validators.annotation.CreateAgencyValidator; import de.caritas.cob.agencyservice.api.admin.validation.validators.annotation.UpdateAgencyValidator; import de.caritas.cob.agencyservice.api.admin.validation.validators.model.ValidateAgencyDTO; +import de.caritas.cob.agencyservice.api.exception.httpresponses.BadRequestException; import de.caritas.cob.agencyservice.api.model.AgencyDTO; import de.caritas.cob.agencyservice.api.model.UpdateAgencyDTO; +import de.caritas.cob.agencyservice.api.repository.agency.AgencyRepository; import lombok.NonNull; import lombok.RequiredArgsConstructor; import org.springframework.context.ApplicationContext; @@ -20,6 +22,8 @@ public class AgencyValidator { private final @NonNull ApplicationContext applicationContext; + private final @NonNull AgencyRepository agencyRepository; + /** * Validates an {@link AgencyDTO}. * @@ -53,15 +57,19 @@ private ValidateAgencyDTO fromAgencyDto(AgencyDTO agencyDto) { .postcode(agencyDto.getPostcode()) .consultingType(agencyDto.getConsultingType()) .demographicsDTO(agencyDto.getDemographics()) + .tenantId(agencyDto.getTenantId()) .build(); } private ValidateAgencyDTO fromUpdateAgencyDto(Long agencyId, UpdateAgencyDTO updateAgencyDTO) { + var existingAgency = agencyRepository.findById(agencyId).orElseThrow(() -> new BadRequestException("Agency with id " + agencyId + "not found!")); return ValidateAgencyDTO.builder() .id(agencyId) .postcode(updateAgencyDTO.getPostcode()) .offline(updateAgencyDTO.getOffline()) + .tenantId(existingAgency.getTenantId()) .demographicsDTO(updateAgencyDTO.getDemographics()) + .dataProtectionDTO(updateAgencyDTO.getDataProtection()) .build(); } } diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidationService.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidationService.java new file mode 100644 index 00000000..d2861af9 --- /dev/null +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidationService.java @@ -0,0 +1,66 @@ +package de.caritas.cob.agencyservice.api.admin.validation.validators; + +import static de.caritas.cob.agencyservice.api.model.DataProtectionDTO.DataProtectionResponsibleEntityEnum.AGENCY_RESPONSIBLE; +import static de.caritas.cob.agencyservice.api.model.DataProtectionDTO.DataProtectionResponsibleEntityEnum.ALTERNATIVE_REPRESENTATIVE; +import static de.caritas.cob.agencyservice.api.model.DataProtectionDTO.DataProtectionResponsibleEntityEnum.DATA_PROTECTION_OFFICER; +import static org.apache.commons.lang3.StringUtils.isBlank; + +import de.caritas.cob.agencyservice.api.admin.validation.validators.model.ValidateAgencyDTO; +import de.caritas.cob.agencyservice.api.exception.httpresponses.HttpStatusExceptionReason; +import de.caritas.cob.agencyservice.api.exception.httpresponses.InvalidOfflineStatusException; +import de.caritas.cob.agencyservice.api.model.DataProtectionContactDTO; +import de.caritas.cob.agencyservice.api.repository.agency.DataProtectionPlaceHolderType; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Component +@Slf4j +public class AgencyDataProtectionValidationService { + + public void validate(ValidateAgencyDTO validateAgencyDto, + de.caritas.cob.agencyservice.tenantservice.generated.web.model.RestrictedTenantDTO tenant) { + if (DataProtectionPlaceHolderType.DATA_PROTECTION_OFFICER.existsInText(tenant.getContent().getPrivacy())) { + log.info("Validating data protection officer for agency with id {}.", validateAgencyDto.getId()); + validateIfDataProtectionOfficer(validateAgencyDto); + validateIfAgencyResponsible(validateAgencyDto); + validateIfAlternativeRepresentative(validateAgencyDto); + } + + if (DataProtectionPlaceHolderType.DATA_PROTECTION_RESPONSIBLE.existsInText(tenant.getContent().getPrivacy())) { + log.info("Validating agency responsible for agency with id {}.", validateAgencyDto.getId()); + validateIfAgencyResponsible(validateAgencyDto); + } + } + + private void validateIfDataProtectionOfficer(ValidateAgencyDTO validateAgencyDto) { + if (DATA_PROTECTION_OFFICER.equals(validateAgencyDto.getDataProtectionDTO().getDataProtectionResponsibleEntity()) + && areFieldsEmpty(validateAgencyDto.getDataProtectionDTO().getDataProtectionOfficerContact())) { + log.warn("Could not bring agency with id {} status to ONLINE. Required fields for data protection officer is empty and privacy text requires placeholder.", validateAgencyDto.getId()); + throw new InvalidOfflineStatusException(HttpStatusExceptionReason.DATA_PROTECTION_OFFICER_IS_EMPTY); + } + } + + private void validateIfAgencyResponsible(ValidateAgencyDTO validateAgencyDto) { + if (AGENCY_RESPONSIBLE.equals(validateAgencyDto.getDataProtectionDTO().getDataProtectionResponsibleEntity()) + && areFieldsEmpty(validateAgencyDto.getDataProtectionDTO().getAgencyDataProtectionResponsibleContact())) { + log.warn("Could not bring agency with id {} status to ONLINE. Required fields for agency responsible is empty and privacy text requires data protection placeholder.", validateAgencyDto.getId()); + throw new InvalidOfflineStatusException(HttpStatusExceptionReason.DATA_PROTECTION_RESPONSIBLE_IS_EMPTY); + } + } + + private void validateIfAlternativeRepresentative(ValidateAgencyDTO validateAgencyDto) { + if (ALTERNATIVE_REPRESENTATIVE.equals(validateAgencyDto.getDataProtectionDTO().getDataProtectionResponsibleEntity()) + && areFieldsEmpty(validateAgencyDto.getDataProtectionDTO().getAlternativeDataProtectionRepresentativeContact())) { + log.warn("Could not bring agency with id {} status to ONLINE. Required fields for alternative responsible is empty and privacy text requires data protection placeholder.", validateAgencyDto.getId()); + throw new InvalidOfflineStatusException(HttpStatusExceptionReason.DATA_PROTECTION_ALTERNATIVE_RESPONSIBLE_IS_EMPTY); + } + } + + private boolean areFieldsEmpty(DataProtectionContactDTO dataProtectionOfficerContact) { + return dataProtectionOfficerContact == null + || isBlank(dataProtectionOfficerContact.getNameAndLegalForm()) + || isBlank(dataProtectionOfficerContact.getCity()) + || isBlank(dataProtectionOfficerContact.getPostcode()) + || isBlank(dataProtectionOfficerContact.getEmail()); + } +} diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidator.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidator.java new file mode 100644 index 00000000..a7d9ec06 --- /dev/null +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidator.java @@ -0,0 +1,42 @@ +package de.caritas.cob.agencyservice.api.admin.validation.validators; + +import de.caritas.cob.agencyservice.api.admin.validation.validators.annotation.UpdateAgencyValidator; +import de.caritas.cob.agencyservice.api.admin.validation.validators.model.ValidateAgencyDTO; +import de.caritas.cob.agencyservice.api.service.ApplicationSettingsService; +import de.caritas.cob.agencyservice.api.service.TenantService; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +@UpdateAgencyValidator +@Slf4j +public class AgencyDataProtectionValidator implements ConcreteAgencyValidator { + + private final @NonNull TenantService tenantService; + + private final @NonNull ApplicationSettingsService applicationSettingsService; + + private final @NonNull AgencyDataProtectionValidationService agencyDataProtectionValidationService; + + @Value("${feature.multitenancy.with.single.domain.enabled}") + private boolean multitenancyWithSingleDomain; + + @Override + public void validate(ValidateAgencyDTO validateAgencyDto) { + + var tenant = tenantService.getRestrictedTenantDataByTenantId(validateAgencyDto.getTenantId()); + agencyDataProtectionValidationService.validate(validateAgencyDto, tenant); + + if (multitenancyWithSingleDomain) { + var mainTenantSubdomainForSingleDomainMultitenancy = applicationSettingsService.getApplicationSettings() + .getMainTenantSubdomainForSingleDomainMultitenancy(); + de.caritas.cob.agencyservice.tenantservice.generated.web.model.RestrictedTenantDTO mainTenant = tenantService.getRestrictedTenantDataBySubdomain( + mainTenantSubdomainForSingleDomainMultitenancy.getValue()); + agencyDataProtectionValidationService.validate(validateAgencyDto, mainTenant); + } + } +} diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyOfflineStatusValidator.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyOfflineStatusValidator.java index 9f044d52..36595aec 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyOfflineStatusValidator.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyOfflineStatusValidator.java @@ -16,6 +16,7 @@ import de.caritas.cob.agencyservice.consultingtypeservice.generated.web.model.ExtendedConsultingTypeResponseDTO; import lombok.NonNull; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; /* @@ -24,6 +25,7 @@ @Component @RequiredArgsConstructor @UpdateAgencyValidator +@Slf4j public class AgencyOfflineStatusValidator implements ConcreteAgencyValidator { private final @NonNull AgencyRepository agencyRepository; @@ -48,7 +50,6 @@ public void validate(ValidateAgencyDTO validateAgencyDto) { if (hasNoConsultant(validateAgencyDto)) { throw new InvalidOfflineStatusException(AGENCY_CONTAINS_NO_CONSULTANTS); } - } } diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/model/ValidateAgencyDTO.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/model/ValidateAgencyDTO.java index 81a66182..af30d670 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/model/ValidateAgencyDTO.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/model/ValidateAgencyDTO.java @@ -1,5 +1,6 @@ package de.caritas.cob.agencyservice.api.admin.validation.validators.model; +import de.caritas.cob.agencyservice.api.model.DataProtectionDTO; import de.caritas.cob.agencyservice.api.model.DemographicsDTO; import lombok.Builder; import lombok.Getter; @@ -18,6 +19,9 @@ public class ValidateAgencyDTO { private String postcode; private Integer consultingType; private Boolean offline; + private Long tenantId; private DemographicsDTO demographicsDTO; + private DataProtectionDTO dataProtectionDTO; + } diff --git a/src/main/java/de/caritas/cob/agencyservice/api/exception/httpresponses/HttpStatusExceptionReason.java b/src/main/java/de/caritas/cob/agencyservice/api/exception/httpresponses/HttpStatusExceptionReason.java index 5aaa9d77..935b6b97 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/exception/httpresponses/HttpStatusExceptionReason.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/exception/httpresponses/HttpStatusExceptionReason.java @@ -11,5 +11,8 @@ public enum HttpStatusExceptionReason { AGENCY_CONTAINS_NO_CONSULTANTS, AGENCY_IS_ALREADY_TEAM_AGENCY, AGENCY_IS_ALREADY_DEFAULT_AGENCY, - AGENCY_ACCESS_DENIED + DATA_PROTECTION_OFFICER_IS_EMPTY, + DATA_PROTECTION_RESPONSIBLE_IS_EMPTY, + + DATA_PROTECTION_ALTERNATIVE_RESPONSIBLE_IS_EMPTY, AGENCY_ACCESS_DENIED } diff --git a/src/main/java/de/caritas/cob/agencyservice/api/repository/agency/DataProtectionPlaceHolderType.java b/src/main/java/de/caritas/cob/agencyservice/api/repository/agency/DataProtectionPlaceHolderType.java new file mode 100644 index 00000000..1b313ba7 --- /dev/null +++ b/src/main/java/de/caritas/cob/agencyservice/api/repository/agency/DataProtectionPlaceHolderType.java @@ -0,0 +1,28 @@ +package de.caritas.cob.agencyservice.api.repository.agency; + +import lombok.Getter; + +@Getter +public enum DataProtectionPlaceHolderType { + DATA_PROTECTION_RESPONSIBLE("responsible"), + DATA_PROTECTION_OFFICER("dataProtectionOfficer"); + + private final String placeholderVariable; + + DataProtectionPlaceHolderType(String placeholderVariable) { + this.placeholderVariable = placeholderVariable; + } + + public static boolean anyExistsInText(String privacy) { + return DATA_PROTECTION_RESPONSIBLE.existsInText(privacy) + || DATA_PROTECTION_OFFICER.existsInText(privacy); + } + + public boolean existsInText(String text) { + return text.contains(getPlaceholder()); + } + + public String getPlaceholder() { + return "${" + placeholderVariable + "}"; + } +} diff --git a/src/test/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidationServiceTest.java b/src/test/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidationServiceTest.java new file mode 100644 index 00000000..b694fd0e --- /dev/null +++ b/src/test/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidationServiceTest.java @@ -0,0 +1,224 @@ +package de.caritas.cob.agencyservice.api.admin.validation.validators; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; + +import de.caritas.cob.agencyservice.api.admin.validation.validators.model.ValidateAgencyDTO; +import de.caritas.cob.agencyservice.api.exception.httpresponses.HttpStatusExceptionReason; +import de.caritas.cob.agencyservice.api.exception.httpresponses.InvalidOfflineStatusException; +import de.caritas.cob.agencyservice.api.model.DataProtectionContactDTO; +import de.caritas.cob.agencyservice.api.model.DataProtectionDTO; +import de.caritas.cob.agencyservice.api.model.DataProtectionDTO.DataProtectionResponsibleEntityEnum; +import de.caritas.cob.agencyservice.api.repository.agency.DataProtectionPlaceHolderType; +import de.caritas.cob.agencyservice.tenantservice.generated.web.model.Content; +import de.caritas.cob.agencyservice.tenantservice.generated.web.model.RestrictedTenantDTO; +import org.assertj.core.api.Fail; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class AgencyDataProtectionValidationServiceTest { + + @InjectMocks + AgencyDataProtectionValidationService agencyDataProtectionValidator; + + @Test + void validate_Should_NotValidate_When_DataProtectionOfficerIsNotSet() { + // given + ValidateAgencyDTO agencyToValidate = ValidateAgencyDTO.builder() + .dataProtectionDTO(new DataProtectionDTO().dataProtectionResponsibleEntity( + DataProtectionResponsibleEntityEnum.DATA_PROTECTION_OFFICER)).build(); + + // when + try { + agencyDataProtectionValidator.validate( + agencyToValidate, tenantWithPrivacy("${dataProtectionOfficer}")); + } catch (InvalidOfflineStatusException e) { + // then + assertThat(e.getHttpStatusExceptionReason()).isEqualTo(HttpStatusExceptionReason.DATA_PROTECTION_OFFICER_IS_EMPTY); + } + } + + private de.caritas.cob.agencyservice.tenantservice.generated.web.model.RestrictedTenantDTO tenantWithPrivacy( + String privacy) { + return new RestrictedTenantDTO().content(new Content().privacy(privacy)); + } + + @Test + void validate_Should_Validate_When_DataProtectionOfficerIsSet() { + // given + ValidateAgencyDTO agencyToValidate = ValidateAgencyDTO.builder() + .dataProtectionDTO(new DataProtectionDTO().dataProtectionResponsibleEntity(DataProtectionResponsibleEntityEnum.DATA_PROTECTION_OFFICER) + .dataProtectionOfficerContact(new DataProtectionContactDTO().nameAndLegalForm("name").email("email").city("city").postcode("postcode"))).build(); + // when + try { + agencyDataProtectionValidator.validate( + agencyToValidate, tenantWithPrivacy("${dataProtectionOfficer}")); + } catch (Exception e) { + // then + Fail.fail("Should not throw exception"); + } + } + + @Test + void validate_Should_Validate_When_DataProtectionOfficerIsNotSet_And_PrivacyWithoutPlaceholder() { + // given + ValidateAgencyDTO agencyToValidate = ValidateAgencyDTO.builder() + .dataProtectionDTO(new DataProtectionDTO().dataProtectionResponsibleEntity(DataProtectionResponsibleEntityEnum.DATA_PROTECTION_OFFICER)).build(); + // when + try { + agencyDataProtectionValidator.validate( + agencyToValidate, tenantWithPrivacy("privacy without placeholder")); + } catch (Exception e) { + // then + Fail.fail("Should not throw exception"); + } + } + + + + @Test + void validate_Should_Validate_When_DataResponsibleIsNotSet_And_PrivacyWithoutPlaceholder() { + // given + ValidateAgencyDTO agencyToValidate = ValidateAgencyDTO.builder() + .dataProtectionDTO(new DataProtectionDTO().dataProtectionResponsibleEntity( + DataProtectionResponsibleEntityEnum.AGENCY_RESPONSIBLE) + ).build(); + // when + try { + agencyDataProtectionValidator.validate( + agencyToValidate, tenantWithPrivacy("privacy without placeholder")); + } catch (Exception e) { + // then + Fail.fail("Should not throw exception"); + } + } + + @Test + void validate_Should_Validate_When_DataResponsibleIsSet_And_ResponsiblePlaceholderExistsInPrivacy() { + // given + ValidateAgencyDTO agencyToValidate = ValidateAgencyDTO.builder() + .dataProtectionDTO(new DataProtectionDTO().dataProtectionResponsibleEntity( + DataProtectionResponsibleEntityEnum.AGENCY_RESPONSIBLE).agencyDataProtectionResponsibleContact(new DataProtectionContactDTO().nameAndLegalForm("name").email("email").city("city").postcode("postcode")) + ).build(); + // when + try { + agencyDataProtectionValidator.validate( + agencyToValidate, tenantWithPrivacy(DataProtectionPlaceHolderType.DATA_PROTECTION_RESPONSIBLE.getPlaceholder())); + } catch (Exception e) { + // then + Fail.fail("Should not throw exception"); + } + } + + + @Test + void validate_Should_NotValidate_When_DataResponsibleIsNotSet_And_DataResponsiblePlaceholder() { + // given + ValidateAgencyDTO agencyToValidate = ValidateAgencyDTO.builder() + .dataProtectionDTO(new DataProtectionDTO().dataProtectionResponsibleEntity( + DataProtectionResponsibleEntityEnum.AGENCY_RESPONSIBLE) + ).build(); + // when + try { + agencyDataProtectionValidator.validate( + agencyToValidate, tenantWithPrivacy(DataProtectionPlaceHolderType.DATA_PROTECTION_RESPONSIBLE.getPlaceholder())); + } catch (InvalidOfflineStatusException e) { + // then + assertThat(e.getHttpStatusExceptionReason()).isEqualTo(HttpStatusExceptionReason.DATA_PROTECTION_RESPONSIBLE_IS_EMPTY); + } + } + + + + + @Test + void validate_Should_Validate_When_DataResponsibleIsSet_And_DataProtectionOfficerPlaceholder() { + // given + ValidateAgencyDTO agencyToValidate = ValidateAgencyDTO.builder() + .dataProtectionDTO(new DataProtectionDTO().dataProtectionResponsibleEntity( + DataProtectionResponsibleEntityEnum.AGENCY_RESPONSIBLE) + .agencyDataProtectionResponsibleContact(new DataProtectionContactDTO().nameAndLegalForm("name").email("email").city("city").postcode("postcode")) + ).build(); + + // when + try { + agencyDataProtectionValidator.validate( + agencyToValidate, tenantWithPrivacy(DataProtectionPlaceHolderType.DATA_PROTECTION_OFFICER.getPlaceholder())); + } catch (Exception e) { + // then + Fail.fail("Should not throw exception"); + } + } + + @Test + void validate_Should_NotValidate_When_DataResponsibleIsNotSet_And_DataProtectionOfficerPlaceholder() { + // given + ValidateAgencyDTO agencyToValidate = ValidateAgencyDTO.builder() + .dataProtectionDTO(new DataProtectionDTO().dataProtectionResponsibleEntity( + DataProtectionResponsibleEntityEnum.AGENCY_RESPONSIBLE)).build(); + // when + try { + agencyDataProtectionValidator.validate( + agencyToValidate, tenantWithPrivacy(DataProtectionPlaceHolderType.DATA_PROTECTION_OFFICER.getPlaceholder())); + } catch (InvalidOfflineStatusException e) { + // then + assertThat(e.getHttpStatusExceptionReason()).isEqualTo(HttpStatusExceptionReason.DATA_PROTECTION_RESPONSIBLE_IS_EMPTY); + } + } + + @Test + void validate_Should_NotValidate_When_AlternativeDataResponsibleIsNotSet_And_DataProtectionOfficerPlaceholder() { + // given + ValidateAgencyDTO agencyToValidate = ValidateAgencyDTO.builder() + .dataProtectionDTO(new DataProtectionDTO().dataProtectionResponsibleEntity( + DataProtectionResponsibleEntityEnum.ALTERNATIVE_REPRESENTATIVE)).build(); + // when + try { + agencyDataProtectionValidator.validate( + agencyToValidate, tenantWithPrivacy(DataProtectionPlaceHolderType.DATA_PROTECTION_OFFICER.getPlaceholder())); + } catch (InvalidOfflineStatusException e) { + // then + assertThat(e.getHttpStatusExceptionReason()).isEqualTo(HttpStatusExceptionReason.DATA_PROTECTION_ALTERNATIVE_RESPONSIBLE_IS_EMPTY); + } + } + + + @Test + void validate_Should_Validate_When_AlternativeDataResponsibleIsSet_And_DataProtectionOfficerPlaceholder() { + // given + ValidateAgencyDTO agencyToValidate = ValidateAgencyDTO.builder() + .dataProtectionDTO(new DataProtectionDTO().dataProtectionResponsibleEntity( + DataProtectionResponsibleEntityEnum.ALTERNATIVE_REPRESENTATIVE) + .alternativeDataProtectionRepresentativeContact(new DataProtectionContactDTO().nameAndLegalForm("name").city("city").postcode("postcode").email("email"))).build(); + + // when + try { + agencyDataProtectionValidator.validate( + agencyToValidate, tenantWithPrivacy(DataProtectionPlaceHolderType.DATA_PROTECTION_OFFICER.getPlaceholder())); + } catch (Exception e) { + // then + Fail.fail("Should not throw exception"); + } + } + + @Test + void validate_Should_Validate_When_AlternativeDataResponsibleIsNotSet_And_PrivacyWithoutPlaceholder() { + // given + ValidateAgencyDTO agencyToValidate = ValidateAgencyDTO.builder() + .dataProtectionDTO(new DataProtectionDTO().dataProtectionResponsibleEntity( + DataProtectionResponsibleEntityEnum.ALTERNATIVE_REPRESENTATIVE)).build(); + + // when + try { + agencyDataProtectionValidator.validate( + agencyToValidate, tenantWithPrivacy("privacy without placeholder")); + } catch (Exception e) { + // then + Fail.fail("Should not throw exception"); + } + } + + +} \ No newline at end of file diff --git a/src/test/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidatorTest.java b/src/test/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidatorTest.java new file mode 100644 index 00000000..a5fd9d7c --- /dev/null +++ b/src/test/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidatorTest.java @@ -0,0 +1,101 @@ +package de.caritas.cob.agencyservice.api.admin.validation.validators; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; + +import de.caritas.cob.agencyservice.api.admin.validation.validators.model.ValidateAgencyDTO; +import de.caritas.cob.agencyservice.api.model.DataProtectionDTO; +import de.caritas.cob.agencyservice.api.model.DataProtectionDTO.DataProtectionResponsibleEntityEnum; +import de.caritas.cob.agencyservice.api.repository.agency.DataProtectionPlaceHolderType; +import de.caritas.cob.agencyservice.api.service.ApplicationSettingsService; +import de.caritas.cob.agencyservice.api.service.TenantService; +import de.caritas.cob.agencyservice.applicationsettingsservice.generated.web.model.ApplicationSettingsDTO; +import de.caritas.cob.agencyservice.applicationsettingsservice.generated.web.model.ApplicationSettingsDTOMainTenantSubdomainForSingleDomainMultitenancy; +import de.caritas.cob.agencyservice.tenantservice.generated.web.model.Content; +import de.caritas.cob.agencyservice.tenantservice.generated.web.model.RestrictedTenantDTO; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.test.util.ReflectionTestUtils; + +@ExtendWith(MockitoExtension.class) +class AgencyDataProtectionValidatorTest { + + @InjectMocks + AgencyDataProtectionValidator agencyDataProtectionValidator; + + private @Mock AgencyDataProtectionValidationService agencyDataProtectionValidationService; + + private @Mock TenantService tenantService; + + private @Mock ApplicationSettingsService applicationSettingsService; + + @Test + void validate_Should_ValidateForAgencyTenant_When_NonSingleDomainMultitenancy() { + // given + ValidateAgencyDTO agencyToValidate = ValidateAgencyDTO.builder() + .dataProtectionDTO(new DataProtectionDTO().dataProtectionResponsibleEntity( + DataProtectionResponsibleEntityEnum.DATA_PROTECTION_OFFICER)).build(); + ReflectionTestUtils.setField(agencyDataProtectionValidator, "multitenancyWithSingleDomain", + false); + givenAgencyTenantWithPrivacy(agencyToValidate, "${dataProtectionOfficer}"); + // when + agencyDataProtectionValidator.validate(agencyToValidate); + // then + ArgumentCaptor captor = ArgumentCaptor.forClass(RestrictedTenantDTO.class); + Mockito.verify(agencyDataProtectionValidationService, Mockito.times(1)) + .validate(Mockito.eq(agencyToValidate), captor.capture()); + assertThat(captor.getValue().getContent().getPrivacy()).isEqualTo("${dataProtectionOfficer}"); + } + + @Test + void validate_Should_ValidateForAgencyTenant_And_MainTenant_When_SingleDomainMultitenancy() { + // given + ValidateAgencyDTO agencyToValidate = ValidateAgencyDTO.builder() + .dataProtectionDTO(new DataProtectionDTO().dataProtectionResponsibleEntity( + DataProtectionResponsibleEntityEnum.DATA_PROTECTION_OFFICER)).build(); + ReflectionTestUtils.setField(agencyDataProtectionValidator, "multitenancyWithSingleDomain", + true); + givenAgencyTenantWithPrivacy(agencyToValidate, "${dataProtectionOfficer}"); + givenSingleDomainWithValue("app"); + givenMainTenantWithPrivacy("app", + DataProtectionPlaceHolderType.DATA_PROTECTION_RESPONSIBLE.getPlaceholder()); + // when + agencyDataProtectionValidator.validate(agencyToValidate); + // then + ArgumentCaptor captor = ArgumentCaptor.forClass(RestrictedTenantDTO.class); + + Mockito.verify(agencyDataProtectionValidationService, Mockito.times(2)) + .validate(Mockito.eq(agencyToValidate), captor.capture()); + + List allCapturedValues = captor.getAllValues(); + assertThat(allCapturedValues.get(0).getContent().getPrivacy()).isEqualTo( + "${dataProtectionOfficer}"); + assertThat(allCapturedValues.get(1).getContent().getPrivacy()).isEqualTo( + DataProtectionPlaceHolderType.DATA_PROTECTION_RESPONSIBLE.getPlaceholder()); + } + + + private void givenAgencyTenantWithPrivacy(ValidateAgencyDTO agency, String privacy) { + Mockito.when(tenantService.getRestrictedTenantDataByTenantId(agency.getTenantId())) + .thenReturn(new RestrictedTenantDTO().content(new Content().privacy(privacy))); + } + + private void givenMainTenantWithPrivacy(String domain, String placeholder) { + Mockito.when(tenantService.getRestrictedTenantDataBySubdomain(domain)) + .thenReturn(new RestrictedTenantDTO().content(new Content().privacy(placeholder))); + } + + private void givenSingleDomainWithValue(String domain) { + Mockito.when(applicationSettingsService.getApplicationSettings()).thenReturn( + new ApplicationSettingsDTO().mainTenantSubdomainForSingleDomainMultitenancy( + new ApplicationSettingsDTOMainTenantSubdomainForSingleDomainMultitenancy().value( + domain))); + } + + +} \ No newline at end of file diff --git a/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerIT.java b/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerIT.java index f5005e2b..ad7b768d 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerIT.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerIT.java @@ -3,6 +3,7 @@ import static javax.ws.rs.core.MediaType.APPLICATION_JSON; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.when; import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; @@ -16,6 +17,7 @@ import de.caritas.cob.agencyservice.api.admin.service.UserAdminService; import de.caritas.cob.agencyservice.api.model.DataProtectionContactDTO; import de.caritas.cob.agencyservice.api.model.DataProtectionDTO; +import de.caritas.cob.agencyservice.api.service.TenantService; import de.caritas.cob.agencyservice.api.util.AuthenticatedUser; import de.caritas.cob.agencyservice.api.manager.consultingtype.ConsultingTypeManager; import de.caritas.cob.agencyservice.api.model.AgencyDTO; @@ -28,6 +30,7 @@ import org.jeasy.random.EasyRandom; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; @@ -68,6 +71,9 @@ class AgencyAdminControllerIT { @Autowired private AgencyRepository agencyRepository; + @MockBean + private TenantService tenantService; + @BeforeEach public void setup() { TenantContext.clear(); @@ -75,6 +81,8 @@ public void setup() { .webAppContextSetup(context) .apply(springSecurity()) .build(); + when(tenantService.getRestrictedTenantDataByTenantId(Mockito.any())) + .thenReturn(new de.caritas.cob.agencyservice.tenantservice.generated.web.model.RestrictedTenantDTO().content(new de.caritas.cob.agencyservice.tenantservice.generated.web.model.Content().privacy("test privacy"))); } @Test @@ -251,6 +259,7 @@ void updateAgency_Should_persistDataProtectionAttributes_When_payloadContainsDat var response = new ExtendedConsultingTypeResponseDTO(); when(consultingTypeManager.getConsultingTypeSettings(anyInt())).thenReturn(response); + var agencyDTO = new UpdateAgencyDTO() .name("Test update name") .description(null) diff --git a/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerWithDemographicsIT.java b/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerWithDemographicsIT.java index 85ca391e..ba02bdac 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerWithDemographicsIT.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerWithDemographicsIT.java @@ -12,6 +12,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import de.caritas.cob.agencyservice.api.service.TenantService; import de.caritas.cob.agencyservice.api.util.AuthenticatedUser; import de.caritas.cob.agencyservice.api.manager.consultingtype.ConsultingTypeManager; import de.caritas.cob.agencyservice.api.model.AgencyDTO; @@ -25,6 +26,7 @@ import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; @@ -58,6 +60,9 @@ class AgencyAdminControllerWithDemographicsIT { @MockBean AuthenticatedUser authenticatedUser; + @MockBean + TenantService tenantService; + @BeforeEach public void setup() { TenantContext.clear(); @@ -65,6 +70,9 @@ public void setup() { .webAppContextSetup(context) .apply(springSecurity()) .build(); + when(tenantService.getRestrictedTenantDataByTenantId(Mockito.any())) + .thenReturn(new de.caritas.cob.agencyservice.tenantservice.generated.web.model.RestrictedTenantDTO().content(new de.caritas.cob.agencyservice.tenantservice.generated.web.model.Content().privacy("test privacy"))); + } @Test diff --git a/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerWithTopicsIT.java b/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerWithTopicsIT.java index e7daf7b7..6cb4b9b0 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerWithTopicsIT.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerWithTopicsIT.java @@ -11,6 +11,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import de.caritas.cob.agencyservice.api.service.TenantService; import de.caritas.cob.agencyservice.api.util.AuthenticatedUser; import de.caritas.cob.agencyservice.api.manager.consultingtype.ConsultingTypeManager; import de.caritas.cob.agencyservice.api.model.AgencyDTO; @@ -23,6 +24,7 @@ import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; @@ -59,6 +61,9 @@ class AgencyAdminControllerWithTopicsIT { @MockBean private AuthenticatedUser authenticatedUser; + @MockBean + private TenantService tenantService; + @BeforeEach public void setup() { TenantContext.clear(); @@ -66,6 +71,8 @@ public void setup() { .webAppContextSetup(context) .apply(springSecurity()) .build(); + when(tenantService.getRestrictedTenantDataByTenantId(Mockito.any())) + .thenReturn(new de.caritas.cob.agencyservice.tenantservice.generated.web.model.RestrictedTenantDTO().content(new de.caritas.cob.agencyservice.tenantservice.generated.web.model.Content().privacy("test privacy"))); } @Test From a298be6a275eca4f57a423f08916b6bca325da81 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Thu, 28 Dec 2023 13:43:16 +0100 Subject: [PATCH 18/29] feat: changed logic for validation to validate regardless of existence of placeholders in tenant privacy if central data protection is enabled --- ...AgencyDataProtectionValidationService.java | 63 ++++++---- .../AgencyDataProtectionValidator.java | 10 +- .../HttpStatusExceptionReason.java | 6 +- ...cyDataProtectionValidationServiceTest.java | 117 ++---------------- .../AgencyDataProtectionValidatorTest.java | 68 +++++----- .../controller/AgencyAdminControllerIT.java | 69 ++++++++++- ...encyAdminControllerWithDemographicsIT.java | 2 +- .../AgencyAdminControllerWithTopicsIT.java | 2 +- 8 files changed, 174 insertions(+), 163 deletions(-) diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidationService.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidationService.java index d2861af9..5e8bd07c 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidationService.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidationService.java @@ -17,42 +17,59 @@ @Slf4j public class AgencyDataProtectionValidationService { - public void validate(ValidateAgencyDTO validateAgencyDto, - de.caritas.cob.agencyservice.tenantservice.generated.web.model.RestrictedTenantDTO tenant) { - if (DataProtectionPlaceHolderType.DATA_PROTECTION_OFFICER.existsInText(tenant.getContent().getPrivacy())) { - log.info("Validating data protection officer for agency with id {}.", validateAgencyDto.getId()); - validateIfDataProtectionOfficer(validateAgencyDto); - validateIfAgencyResponsible(validateAgencyDto); - validateIfAlternativeRepresentative(validateAgencyDto); - } + public void validate(ValidateAgencyDTO validateAgencyDto) { + validateThatDataProtectionDtoExists(validateAgencyDto); + validateIfDataProtectionOfficer(validateAgencyDto); + validateIfAgencyResponsible(validateAgencyDto); + validateIfAlternativeRepresentative(validateAgencyDto); + } - if (DataProtectionPlaceHolderType.DATA_PROTECTION_RESPONSIBLE.existsInText(tenant.getContent().getPrivacy())) { - log.info("Validating agency responsible for agency with id {}.", validateAgencyDto.getId()); - validateIfAgencyResponsible(validateAgencyDto); + private void validateThatDataProtectionDtoExists(ValidateAgencyDTO validateAgencyDto) { + if (validateAgencyDto.getDataProtectionDTO() == null) { + log.warn( + "Could not save agency with id {} status. Required fields for data protection officer is empty.", + validateAgencyDto.getId()); + throw new InvalidOfflineStatusException( + HttpStatusExceptionReason.DATA_PROTECTION_DTO_IS_NULL); } } private void validateIfDataProtectionOfficer(ValidateAgencyDTO validateAgencyDto) { - if (DATA_PROTECTION_OFFICER.equals(validateAgencyDto.getDataProtectionDTO().getDataProtectionResponsibleEntity()) - && areFieldsEmpty(validateAgencyDto.getDataProtectionDTO().getDataProtectionOfficerContact())) { - log.warn("Could not bring agency with id {} status to ONLINE. Required fields for data protection officer is empty and privacy text requires placeholder.", validateAgencyDto.getId()); - throw new InvalidOfflineStatusException(HttpStatusExceptionReason.DATA_PROTECTION_OFFICER_IS_EMPTY); + if (DATA_PROTECTION_OFFICER.equals( + validateAgencyDto.getDataProtectionDTO().getDataProtectionResponsibleEntity()) + && areFieldsEmpty( + validateAgencyDto.getDataProtectionDTO().getDataProtectionOfficerContact())) { + log.warn( + "Could not save agency with id {}. Required fields for data protection officer is empty.", + validateAgencyDto.getId()); + throw new InvalidOfflineStatusException( + HttpStatusExceptionReason.DATA_PROTECTION_OFFICER_IS_EMPTY); } } private void validateIfAgencyResponsible(ValidateAgencyDTO validateAgencyDto) { - if (AGENCY_RESPONSIBLE.equals(validateAgencyDto.getDataProtectionDTO().getDataProtectionResponsibleEntity()) - && areFieldsEmpty(validateAgencyDto.getDataProtectionDTO().getAgencyDataProtectionResponsibleContact())) { - log.warn("Could not bring agency with id {} status to ONLINE. Required fields for agency responsible is empty and privacy text requires data protection placeholder.", validateAgencyDto.getId()); - throw new InvalidOfflineStatusException(HttpStatusExceptionReason.DATA_PROTECTION_RESPONSIBLE_IS_EMPTY); + if (AGENCY_RESPONSIBLE.equals( + validateAgencyDto.getDataProtectionDTO().getDataProtectionResponsibleEntity()) + && areFieldsEmpty( + validateAgencyDto.getDataProtectionDTO().getAgencyDataProtectionResponsibleContact())) { + log.warn( + "Could not save agency with id {} status. Required fields for agency responsible is empty.", + validateAgencyDto.getId()); + throw new InvalidOfflineStatusException( + HttpStatusExceptionReason.DATA_PROTECTION_RESPONSIBLE_IS_EMPTY); } } private void validateIfAlternativeRepresentative(ValidateAgencyDTO validateAgencyDto) { - if (ALTERNATIVE_REPRESENTATIVE.equals(validateAgencyDto.getDataProtectionDTO().getDataProtectionResponsibleEntity()) - && areFieldsEmpty(validateAgencyDto.getDataProtectionDTO().getAlternativeDataProtectionRepresentativeContact())) { - log.warn("Could not bring agency with id {} status to ONLINE. Required fields for alternative responsible is empty and privacy text requires data protection placeholder.", validateAgencyDto.getId()); - throw new InvalidOfflineStatusException(HttpStatusExceptionReason.DATA_PROTECTION_ALTERNATIVE_RESPONSIBLE_IS_EMPTY); + if (ALTERNATIVE_REPRESENTATIVE.equals( + validateAgencyDto.getDataProtectionDTO().getDataProtectionResponsibleEntity()) + && areFieldsEmpty(validateAgencyDto.getDataProtectionDTO() + .getAlternativeDataProtectionRepresentativeContact())) { + log.warn( + "Could not save agency with id {} status. Required fields for alternative responsible is empty.", + validateAgencyDto.getId()); + throw new InvalidOfflineStatusException( + HttpStatusExceptionReason.DATA_PROTECTION_ALTERNATIVE_RESPONSIBLE_IS_EMPTY); } } diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidator.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidator.java index a7d9ec06..634c50d3 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidator.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidator.java @@ -29,14 +29,20 @@ public class AgencyDataProtectionValidator implements ConcreteAgencyValidator { public void validate(ValidateAgencyDTO validateAgencyDto) { var tenant = tenantService.getRestrictedTenantDataByTenantId(validateAgencyDto.getTenantId()); - agencyDataProtectionValidationService.validate(validateAgencyDto, tenant); + + if (Boolean.TRUE.equals(tenant.getSettings().getFeatureCentralDataProtectionTemplateEnabled())) { + log.info("Validating agency data protection for agency with id {}.", validateAgencyDto.getId()); + agencyDataProtectionValidationService.validate(validateAgencyDto); + } if (multitenancyWithSingleDomain) { var mainTenantSubdomainForSingleDomainMultitenancy = applicationSettingsService.getApplicationSettings() .getMainTenantSubdomainForSingleDomainMultitenancy(); de.caritas.cob.agencyservice.tenantservice.generated.web.model.RestrictedTenantDTO mainTenant = tenantService.getRestrictedTenantDataBySubdomain( mainTenantSubdomainForSingleDomainMultitenancy.getValue()); - agencyDataProtectionValidationService.validate(validateAgencyDto, mainTenant); + if (Boolean.TRUE.equals(mainTenant.getSettings().getFeatureCentralDataProtectionTemplateEnabled())) { + agencyDataProtectionValidationService.validate(validateAgencyDto); + } } } } diff --git a/src/main/java/de/caritas/cob/agencyservice/api/exception/httpresponses/HttpStatusExceptionReason.java b/src/main/java/de/caritas/cob/agencyservice/api/exception/httpresponses/HttpStatusExceptionReason.java index 935b6b97..82479849 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/exception/httpresponses/HttpStatusExceptionReason.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/exception/httpresponses/HttpStatusExceptionReason.java @@ -14,5 +14,9 @@ public enum HttpStatusExceptionReason { DATA_PROTECTION_OFFICER_IS_EMPTY, DATA_PROTECTION_RESPONSIBLE_IS_EMPTY, - DATA_PROTECTION_ALTERNATIVE_RESPONSIBLE_IS_EMPTY, AGENCY_ACCESS_DENIED + DATA_PROTECTION_ALTERNATIVE_RESPONSIBLE_IS_EMPTY, + + DATA_PROTECTION_DTO_IS_NULL, + + AGENCY_ACCESS_DENIED } diff --git a/src/test/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidationServiceTest.java b/src/test/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidationServiceTest.java index b694fd0e..48dced04 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidationServiceTest.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidationServiceTest.java @@ -8,7 +8,6 @@ import de.caritas.cob.agencyservice.api.model.DataProtectionContactDTO; import de.caritas.cob.agencyservice.api.model.DataProtectionDTO; import de.caritas.cob.agencyservice.api.model.DataProtectionDTO.DataProtectionResponsibleEntityEnum; -import de.caritas.cob.agencyservice.api.repository.agency.DataProtectionPlaceHolderType; import de.caritas.cob.agencyservice.tenantservice.generated.web.model.Content; import de.caritas.cob.agencyservice.tenantservice.generated.web.model.RestrictedTenantDTO; import org.assertj.core.api.Fail; @@ -33,7 +32,7 @@ void validate_Should_NotValidate_When_DataProtectionOfficerIsNotSet() { // when try { agencyDataProtectionValidator.validate( - agencyToValidate, tenantWithPrivacy("${dataProtectionOfficer}")); + agencyToValidate); } catch (InvalidOfflineStatusException e) { // then assertThat(e.getHttpStatusExceptionReason()).isEqualTo(HttpStatusExceptionReason.DATA_PROTECTION_OFFICER_IS_EMPTY); @@ -54,7 +53,7 @@ void validate_Should_Validate_When_DataProtectionOfficerIsSet() { // when try { agencyDataProtectionValidator.validate( - agencyToValidate, tenantWithPrivacy("${dataProtectionOfficer}")); + agencyToValidate); } catch (Exception e) { // then Fail.fail("Should not throw exception"); @@ -62,41 +61,7 @@ void validate_Should_Validate_When_DataProtectionOfficerIsSet() { } @Test - void validate_Should_Validate_When_DataProtectionOfficerIsNotSet_And_PrivacyWithoutPlaceholder() { - // given - ValidateAgencyDTO agencyToValidate = ValidateAgencyDTO.builder() - .dataProtectionDTO(new DataProtectionDTO().dataProtectionResponsibleEntity(DataProtectionResponsibleEntityEnum.DATA_PROTECTION_OFFICER)).build(); - // when - try { - agencyDataProtectionValidator.validate( - agencyToValidate, tenantWithPrivacy("privacy without placeholder")); - } catch (Exception e) { - // then - Fail.fail("Should not throw exception"); - } - } - - - - @Test - void validate_Should_Validate_When_DataResponsibleIsNotSet_And_PrivacyWithoutPlaceholder() { - // given - ValidateAgencyDTO agencyToValidate = ValidateAgencyDTO.builder() - .dataProtectionDTO(new DataProtectionDTO().dataProtectionResponsibleEntity( - DataProtectionResponsibleEntityEnum.AGENCY_RESPONSIBLE) - ).build(); - // when - try { - agencyDataProtectionValidator.validate( - agencyToValidate, tenantWithPrivacy("privacy without placeholder")); - } catch (Exception e) { - // then - Fail.fail("Should not throw exception"); - } - } - - @Test - void validate_Should_Validate_When_DataResponsibleIsSet_And_ResponsiblePlaceholderExistsInPrivacy() { + void validate_Should_Validate_When_DataResponsibleIsSet() { // given ValidateAgencyDTO agencyToValidate = ValidateAgencyDTO.builder() .dataProtectionDTO(new DataProtectionDTO().dataProtectionResponsibleEntity( @@ -105,7 +70,7 @@ void validate_Should_Validate_When_DataResponsibleIsSet_And_ResponsiblePlacehold // when try { agencyDataProtectionValidator.validate( - agencyToValidate, tenantWithPrivacy(DataProtectionPlaceHolderType.DATA_PROTECTION_RESPONSIBLE.getPlaceholder())); + agencyToValidate); } catch (Exception e) { // then Fail.fail("Should not throw exception"); @@ -114,7 +79,7 @@ void validate_Should_Validate_When_DataResponsibleIsSet_And_ResponsiblePlacehold @Test - void validate_Should_NotValidate_When_DataResponsibleIsNotSet_And_DataResponsiblePlaceholder() { + void validate_Should_NotValidate_When_DataResponsibleIsNotSet() { // given ValidateAgencyDTO agencyToValidate = ValidateAgencyDTO.builder() .dataProtectionDTO(new DataProtectionDTO().dataProtectionResponsibleEntity( @@ -123,61 +88,22 @@ void validate_Should_NotValidate_When_DataResponsibleIsNotSet_And_DataResponsibl // when try { agencyDataProtectionValidator.validate( - agencyToValidate, tenantWithPrivacy(DataProtectionPlaceHolderType.DATA_PROTECTION_RESPONSIBLE.getPlaceholder())); + agencyToValidate); } catch (InvalidOfflineStatusException e) { // then assertThat(e.getHttpStatusExceptionReason()).isEqualTo(HttpStatusExceptionReason.DATA_PROTECTION_RESPONSIBLE_IS_EMPTY); } } - - - @Test - void validate_Should_Validate_When_DataResponsibleIsSet_And_DataProtectionOfficerPlaceholder() { - // given - ValidateAgencyDTO agencyToValidate = ValidateAgencyDTO.builder() - .dataProtectionDTO(new DataProtectionDTO().dataProtectionResponsibleEntity( - DataProtectionResponsibleEntityEnum.AGENCY_RESPONSIBLE) - .agencyDataProtectionResponsibleContact(new DataProtectionContactDTO().nameAndLegalForm("name").email("email").city("city").postcode("postcode")) - ).build(); - - // when - try { - agencyDataProtectionValidator.validate( - agencyToValidate, tenantWithPrivacy(DataProtectionPlaceHolderType.DATA_PROTECTION_OFFICER.getPlaceholder())); - } catch (Exception e) { - // then - Fail.fail("Should not throw exception"); - } - } - - @Test - void validate_Should_NotValidate_When_DataResponsibleIsNotSet_And_DataProtectionOfficerPlaceholder() { - // given - ValidateAgencyDTO agencyToValidate = ValidateAgencyDTO.builder() - .dataProtectionDTO(new DataProtectionDTO().dataProtectionResponsibleEntity( - DataProtectionResponsibleEntityEnum.AGENCY_RESPONSIBLE)).build(); - // when - try { - agencyDataProtectionValidator.validate( - agencyToValidate, tenantWithPrivacy(DataProtectionPlaceHolderType.DATA_PROTECTION_OFFICER.getPlaceholder())); - } catch (InvalidOfflineStatusException e) { - // then - assertThat(e.getHttpStatusExceptionReason()).isEqualTo(HttpStatusExceptionReason.DATA_PROTECTION_RESPONSIBLE_IS_EMPTY); - } - } - - @Test - void validate_Should_NotValidate_When_AlternativeDataResponsibleIsNotSet_And_DataProtectionOfficerPlaceholder() { + void validate_Should_NotValidate_When_AlternativeDataResponsibleIsNotSet() { // given ValidateAgencyDTO agencyToValidate = ValidateAgencyDTO.builder() .dataProtectionDTO(new DataProtectionDTO().dataProtectionResponsibleEntity( DataProtectionResponsibleEntityEnum.ALTERNATIVE_REPRESENTATIVE)).build(); // when try { - agencyDataProtectionValidator.validate( - agencyToValidate, tenantWithPrivacy(DataProtectionPlaceHolderType.DATA_PROTECTION_OFFICER.getPlaceholder())); + agencyDataProtectionValidator.validate(agencyToValidate); } catch (InvalidOfflineStatusException e) { // then assertThat(e.getHttpStatusExceptionReason()).isEqualTo(HttpStatusExceptionReason.DATA_PROTECTION_ALTERNATIVE_RESPONSIBLE_IS_EMPTY); @@ -186,39 +112,22 @@ void validate_Should_NotValidate_When_AlternativeDataResponsibleIsNotSet_And_Dat @Test - void validate_Should_Validate_When_AlternativeDataResponsibleIsSet_And_DataProtectionOfficerPlaceholder() { + void validate_Should_Validate_When_AlternativeDataResponsibleIsSet() { // given ValidateAgencyDTO agencyToValidate = ValidateAgencyDTO.builder() .dataProtectionDTO(new DataProtectionDTO().dataProtectionResponsibleEntity( DataProtectionResponsibleEntityEnum.ALTERNATIVE_REPRESENTATIVE) - .alternativeDataProtectionRepresentativeContact(new DataProtectionContactDTO().nameAndLegalForm("name").city("city").postcode("postcode").email("email"))).build(); + .alternativeDataProtectionRepresentativeContact( + new DataProtectionContactDTO().nameAndLegalForm("name").city("city") + .postcode("postcode").email("email"))).build(); // when try { agencyDataProtectionValidator.validate( - agencyToValidate, tenantWithPrivacy(DataProtectionPlaceHolderType.DATA_PROTECTION_OFFICER.getPlaceholder())); + agencyToValidate); } catch (Exception e) { // then Fail.fail("Should not throw exception"); } } - - @Test - void validate_Should_Validate_When_AlternativeDataResponsibleIsNotSet_And_PrivacyWithoutPlaceholder() { - // given - ValidateAgencyDTO agencyToValidate = ValidateAgencyDTO.builder() - .dataProtectionDTO(new DataProtectionDTO().dataProtectionResponsibleEntity( - DataProtectionResponsibleEntityEnum.ALTERNATIVE_REPRESENTATIVE)).build(); - - // when - try { - agencyDataProtectionValidator.validate( - agencyToValidate, tenantWithPrivacy("privacy without placeholder")); - } catch (Exception e) { - // then - Fail.fail("Should not throw exception"); - } - } - - } \ No newline at end of file diff --git a/src/test/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidatorTest.java b/src/test/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidatorTest.java index a5fd9d7c..29ef1967 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidatorTest.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDataProtectionValidatorTest.java @@ -1,21 +1,18 @@ package de.caritas.cob.agencyservice.api.admin.validation.validators; -import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; - import de.caritas.cob.agencyservice.api.admin.validation.validators.model.ValidateAgencyDTO; import de.caritas.cob.agencyservice.api.model.DataProtectionDTO; import de.caritas.cob.agencyservice.api.model.DataProtectionDTO.DataProtectionResponsibleEntityEnum; -import de.caritas.cob.agencyservice.api.repository.agency.DataProtectionPlaceHolderType; import de.caritas.cob.agencyservice.api.service.ApplicationSettingsService; import de.caritas.cob.agencyservice.api.service.TenantService; import de.caritas.cob.agencyservice.applicationsettingsservice.generated.web.model.ApplicationSettingsDTO; import de.caritas.cob.agencyservice.applicationsettingsservice.generated.web.model.ApplicationSettingsDTOMainTenantSubdomainForSingleDomainMultitenancy; -import de.caritas.cob.agencyservice.tenantservice.generated.web.model.Content; import de.caritas.cob.agencyservice.tenantservice.generated.web.model.RestrictedTenantDTO; -import java.util.List; +import de.caritas.cob.agencyservice.tenantservice.generated.web.model.Settings; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.ArgumentCaptor; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; @@ -35,59 +32,72 @@ class AgencyDataProtectionValidatorTest { private @Mock ApplicationSettingsService applicationSettingsService; @Test - void validate_Should_ValidateForAgencyTenant_When_NonSingleDomainMultitenancy() { + void validate_Should_ValidateForAgencyTenant_When_NonSingleDomainMultitenancy_And_CentralDataProtectionFeatureEnabled() { // given ValidateAgencyDTO agencyToValidate = ValidateAgencyDTO.builder() .dataProtectionDTO(new DataProtectionDTO().dataProtectionResponsibleEntity( DataProtectionResponsibleEntityEnum.DATA_PROTECTION_OFFICER)).build(); ReflectionTestUtils.setField(agencyDataProtectionValidator, "multitenancyWithSingleDomain", false); - givenAgencyTenantWithPrivacy(agencyToValidate, "${dataProtectionOfficer}"); + givenAgencyTenant(agencyToValidate, true); // when agencyDataProtectionValidator.validate(agencyToValidate); // then - ArgumentCaptor captor = ArgumentCaptor.forClass(RestrictedTenantDTO.class); Mockito.verify(agencyDataProtectionValidationService, Mockito.times(1)) - .validate(Mockito.eq(agencyToValidate), captor.capture()); - assertThat(captor.getValue().getContent().getPrivacy()).isEqualTo("${dataProtectionOfficer}"); + .validate(agencyToValidate); } @Test - void validate_Should_ValidateForAgencyTenant_And_MainTenant_When_SingleDomainMultitenancy() { + void validate_Should_NotValidateForAgencyTenant_When_NonSingleDomainMultitenancy_And_CentralDataProtectionFeatureDisabled() { + // given + ValidateAgencyDTO agencyToValidate = ValidateAgencyDTO.builder() + .dataProtectionDTO(new DataProtectionDTO().dataProtectionResponsibleEntity( + DataProtectionResponsibleEntityEnum.DATA_PROTECTION_OFFICER)).build(); + ReflectionTestUtils.setField(agencyDataProtectionValidator, "multitenancyWithSingleDomain", + false); + givenAgencyTenant(agencyToValidate, false); + // when + agencyDataProtectionValidator.validate(agencyToValidate); + // then + Mockito.verify(agencyDataProtectionValidationService, Mockito.never()) + .validate(agencyToValidate); + } + + @ParameterizedTest + @CsvSource({ + "true,true,2", + "true,false,1", + "false,true,1", + "false,false,0", + }) + void validate_Should_ValidateForAgencyTenantAndMainTenant_When_SingleDomainMultitenancy(boolean isAgencyTenantCentralDataProtectionEnabled, boolean isMainTenantCentralDataProtectionEnabled, int expectedValidationCalls) { // given ValidateAgencyDTO agencyToValidate = ValidateAgencyDTO.builder() .dataProtectionDTO(new DataProtectionDTO().dataProtectionResponsibleEntity( DataProtectionResponsibleEntityEnum.DATA_PROTECTION_OFFICER)).build(); ReflectionTestUtils.setField(agencyDataProtectionValidator, "multitenancyWithSingleDomain", true); - givenAgencyTenantWithPrivacy(agencyToValidate, "${dataProtectionOfficer}"); + givenAgencyTenant(agencyToValidate, isAgencyTenantCentralDataProtectionEnabled); givenSingleDomainWithValue("app"); - givenMainTenantWithPrivacy("app", - DataProtectionPlaceHolderType.DATA_PROTECTION_RESPONSIBLE.getPlaceholder()); + givenMainTenant("app", isMainTenantCentralDataProtectionEnabled); // when agencyDataProtectionValidator.validate(agencyToValidate); // then - ArgumentCaptor captor = ArgumentCaptor.forClass(RestrictedTenantDTO.class); - Mockito.verify(agencyDataProtectionValidationService, Mockito.times(2)) - .validate(Mockito.eq(agencyToValidate), captor.capture()); - - List allCapturedValues = captor.getAllValues(); - assertThat(allCapturedValues.get(0).getContent().getPrivacy()).isEqualTo( - "${dataProtectionOfficer}"); - assertThat(allCapturedValues.get(1).getContent().getPrivacy()).isEqualTo( - DataProtectionPlaceHolderType.DATA_PROTECTION_RESPONSIBLE.getPlaceholder()); + Mockito.verify(agencyDataProtectionValidationService, Mockito.times(expectedValidationCalls)) + .validate(agencyToValidate); } - private void givenAgencyTenantWithPrivacy(ValidateAgencyDTO agency, String privacy) { + + private void givenAgencyTenant(ValidateAgencyDTO agency, boolean isCentralDataProtectionEnabled) { Mockito.when(tenantService.getRestrictedTenantDataByTenantId(agency.getTenantId())) - .thenReturn(new RestrictedTenantDTO().content(new Content().privacy(privacy))); + .thenReturn(new RestrictedTenantDTO().settings(new Settings().featureCentralDataProtectionTemplateEnabled(isCentralDataProtectionEnabled))); } - private void givenMainTenantWithPrivacy(String domain, String placeholder) { + private void givenMainTenant(String domain, boolean isCentralDataProtectionEnabled) { Mockito.when(tenantService.getRestrictedTenantDataBySubdomain(domain)) - .thenReturn(new RestrictedTenantDTO().content(new Content().privacy(placeholder))); + .thenReturn(new RestrictedTenantDTO().settings(new Settings().featureCentralDataProtectionTemplateEnabled(isCentralDataProtectionEnabled))); } private void givenSingleDomainWithValue(String domain) { @@ -96,6 +106,4 @@ private void givenSingleDomainWithValue(String domain) { new ApplicationSettingsDTOMainTenantSubdomainForSingleDomainMultitenancy().value( domain))); } - - } \ No newline at end of file diff --git a/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerIT.java b/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerIT.java index ad7b768d..e57be60f 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerIT.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerIT.java @@ -26,6 +26,7 @@ import de.caritas.cob.agencyservice.api.tenant.TenantContext; import de.caritas.cob.agencyservice.consultingtypeservice.generated.web.model.ExtendedConsultingTypeResponseDTO; import de.caritas.cob.agencyservice.api.util.JsonConverter; +import de.caritas.cob.agencyservice.tenantservice.generated.web.model.Settings; import de.caritas.cob.agencyservice.testHelper.PathConstants; import org.jeasy.random.EasyRandom; import org.junit.jupiter.api.BeforeEach; @@ -82,7 +83,7 @@ public void setup() { .apply(springSecurity()) .build(); when(tenantService.getRestrictedTenantDataByTenantId(Mockito.any())) - .thenReturn(new de.caritas.cob.agencyservice.tenantservice.generated.web.model.RestrictedTenantDTO().content(new de.caritas.cob.agencyservice.tenantservice.generated.web.model.Content().privacy("test privacy"))); + .thenReturn(new de.caritas.cob.agencyservice.tenantservice.generated.web.model.RestrictedTenantDTO().settings(new Settings().featureCentralDataProtectionTemplateEnabled(false))); } @Test @@ -253,6 +254,72 @@ void updateAgency_Should_returnStatusOk_When_calledWithEmptyDescription() throws assertNull(savedAgency.getDescription()); } + @Test + @WithMockUser(authorities = "AUTHORIZATION_AGENCY_ADMIN") + void updateAgency_Should_returnStatusOk_When_CentralDataProtectionIsEnabled_And_PayloadContainsValidDataProtectionContent() throws Exception { + var response = new ExtendedConsultingTypeResponseDTO(); + + Long tenantId = agencyRepository.findById(1L).get().getTenantId(); + when(consultingTypeManager.getConsultingTypeSettings(anyInt())).thenReturn(response); + + when(tenantService.getRestrictedTenantDataByTenantId(tenantId)) + .thenReturn(new de.caritas.cob.agencyservice.tenantservice.generated.web.model.RestrictedTenantDTO().settings(new Settings().featureCentralDataProtectionTemplateEnabled(true))); + + var agencyDTO = new UpdateAgencyDTO() + .name("Test update name") + .description(null) + .offline(true) + .external(false) + .dataProtection(new DataProtectionDTO().dataProtectionResponsibleEntity(DataProtectionDTO.DataProtectionResponsibleEntityEnum.DATA_PROTECTION_OFFICER) + .dataProtectionOfficerContact(new DataProtectionContactDTO().nameAndLegalForm("data protection contact").city("Munich") + .postcode("00001").phoneNumber("321-321-321").email("dataprotection@onlineberatung.net"))); + + + mockMvc.perform(put(PathConstants.UPDATE_DELETE_AGENCY_PATH) + .contentType(APPLICATION_JSON) + .content(JsonConverter.convertToJson(agencyDTO))) + .andExpect(status().isOk()) + .andExpect(jsonPath("_embedded.id").value(1)) + .andExpect(jsonPath("_embedded.name").value("Test update name")) + .andExpect(jsonPath("_embedded.description").isEmpty()) + .andExpect(jsonPath("_embedded.teamAgency").value("false")) + .andExpect(jsonPath("_embedded.external").value("false")) + .andExpect(jsonPath("_embedded.offline").exists()) + .andExpect(jsonPath("_embedded.topics").exists()) + .andExpect(jsonPath("_embedded.createDate").exists()) + .andExpect(jsonPath("_embedded.updateDate").exists()) + .andExpect(jsonPath("_embedded.deleteDate").exists()); + + var savedAgency = agencyRepository.findById(1L).orElseThrow(); + assertNull(savedAgency.getDescription()); + } + + @Test + @WithMockUser(authorities = "AUTHORIZATION_AGENCY_ADMIN") + void updateAgency_Should_returnStatusBadRequest_When_CentralDataProtectionIsEnabled_And_PayloadContainsInvalidDataProtectionContent() throws Exception { + var response = new ExtendedConsultingTypeResponseDTO(); + + Long tenantId = agencyRepository.findById(1L).get().getTenantId(); + when(consultingTypeManager.getConsultingTypeSettings(anyInt())).thenReturn(response); + + when(tenantService.getRestrictedTenantDataByTenantId(tenantId)) + .thenReturn(new de.caritas.cob.agencyservice.tenantservice.generated.web.model.RestrictedTenantDTO().settings(new Settings().featureCentralDataProtectionTemplateEnabled(true))); + + var agencyDTO = new UpdateAgencyDTO() + .name("Test update name") + .description(null) + .offline(true) + .external(false) + .dataProtection(new DataProtectionDTO().dataProtectionResponsibleEntity(DataProtectionDTO.DataProtectionResponsibleEntityEnum.DATA_PROTECTION_OFFICER) + .dataProtectionOfficerContact(new DataProtectionContactDTO())); + + + mockMvc.perform(put(PathConstants.UPDATE_DELETE_AGENCY_PATH) + .contentType(APPLICATION_JSON) + .content(JsonConverter.convertToJson(agencyDTO))) + .andExpect(status().isBadRequest()); + } + @Test @WithMockUser(authorities = "AUTHORIZATION_AGENCY_ADMIN") void updateAgency_Should_persistDataProtectionAttributes_When_payloadContainsDataProtection() throws Exception { diff --git a/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerWithDemographicsIT.java b/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerWithDemographicsIT.java index ba02bdac..489b4f90 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerWithDemographicsIT.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerWithDemographicsIT.java @@ -71,7 +71,7 @@ public void setup() { .apply(springSecurity()) .build(); when(tenantService.getRestrictedTenantDataByTenantId(Mockito.any())) - .thenReturn(new de.caritas.cob.agencyservice.tenantservice.generated.web.model.RestrictedTenantDTO().content(new de.caritas.cob.agencyservice.tenantservice.generated.web.model.Content().privacy("test privacy"))); + .thenReturn(new de.caritas.cob.agencyservice.tenantservice.generated.web.model.RestrictedTenantDTO().settings(new de.caritas.cob.agencyservice.tenantservice.generated.web.model.Settings().featureCentralDataProtectionTemplateEnabled(false))); } diff --git a/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerWithTopicsIT.java b/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerWithTopicsIT.java index 6cb4b9b0..6d47367b 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerWithTopicsIT.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerWithTopicsIT.java @@ -72,7 +72,7 @@ public void setup() { .apply(springSecurity()) .build(); when(tenantService.getRestrictedTenantDataByTenantId(Mockito.any())) - .thenReturn(new de.caritas.cob.agencyservice.tenantservice.generated.web.model.RestrictedTenantDTO().content(new de.caritas.cob.agencyservice.tenantservice.generated.web.model.Content().privacy("test privacy"))); + .thenReturn(new de.caritas.cob.agencyservice.tenantservice.generated.web.model.RestrictedTenantDTO().settings(new de.caritas.cob.agencyservice.tenantservice.generated.web.model.Settings().featureCentralDataProtectionTemplateEnabled(false))); } @Test From 7270c54247e0596410862ba52f05b95ce32f6862 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Mon, 29 Jan 2024 11:15:46 +0100 Subject: [PATCH 19/29] fix: NPE fix in case feature central data protection is not existent --- .../de/caritas/cob/agencyservice/api/service/AgencyService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/de/caritas/cob/agencyservice/api/service/AgencyService.java b/src/main/java/de/caritas/cob/agencyservice/api/service/AgencyService.java index 3a41379b..49dde67f 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/service/AgencyService.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/service/AgencyService.java @@ -314,7 +314,7 @@ protected String getRenderedAgencySpecificPrivacy(Agency agency) { RestrictedTenantDTO tenantDataHoldingFeatureToggles = getTenantDataRelevantForFeatureToggles( agency); Settings settings = tenantDataHoldingFeatureToggles != null ? tenantDataHoldingFeatureToggles.getSettings() : null; - if (settings != null && settings.getFeatureCentralDataProtectionTemplateEnabled()) { + if (settings != null && settings.getFeatureCentralDataProtectionTemplateEnabled() != null && Boolean.TRUE.equals(settings.getFeatureCentralDataProtectionTemplateEnabled())) { return centralDataProtectionTemplateService.renderPrivacyTemplateWithRenderedPlaceholderValues( agency); } else { From b2b7c9e84d04560dbfec9284283fc8700cec5637 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Tue, 30 Jan 2024 17:10:14 +0100 Subject: [PATCH 20/29] fix: add logic that enables data protection persistence on agency create --- api/agencyadminservice.yaml | 3 +++ .../api/admin/service/AgencyAdminService.java | 9 +++++++-- .../api/admin/service/AgencyAdminServiceTest.java | 8 ++++++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/api/agencyadminservice.yaml b/api/agencyadminservice.yaml index 237dbf1c..b630ca4e 100644 --- a/api/agencyadminservice.yaml +++ b/api/agencyadminservice.yaml @@ -630,6 +630,9 @@ components: items: type: string enum: [ RELATIVE_COUNSELLING, SELF_COUNSELLING, PARENTAL_COUNSELLING] + dataProtection: + type: object + $ref: '#/components/schemas/DataProtectionDTO' AgencyAdminFullResponseDTO: type: object diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminService.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminService.java index 07b9438c..b8411500 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminService.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminService.java @@ -49,14 +49,13 @@ public class AgencyAdminService { private final @NonNull AgencyTopicMergeService agencyTopicMergeService; private final @NonNull AppointmentService appointmentService; + private final @NonNull DataProtectionConverter dataProtectionConverter; @Autowired(required = false) private AgencyTopicEnrichmentService agencyTopicEnrichmentService; @Autowired(required = false) private DemographicsConverter demographicsConverter; - @Autowired - private DataProtectionConverter dataProtectionConverter; @Value("${feature.topics.enabled}") private boolean featureTopicsEnabled; @@ -148,6 +147,12 @@ private Agency fromAgencyDTO(AgencyDTO agencyDTO) { demographicsConverter.convertToEntity(agencyDTO.getDemographics(), agencyBuilder); } + if (dataProtectionConverter != null) { + dataProtectionConverter.convertToEntity(agencyDTO.getDataProtection(), agencyBuilder); + } + + + var agencyToCreate = agencyBuilder.build(); if (featureTopicsEnabled) { diff --git a/src/test/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminServiceTest.java b/src/test/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminServiceTest.java index edf30c75..0ef74ef9 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminServiceTest.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminServiceTest.java @@ -26,15 +26,14 @@ import de.caritas.cob.agencyservice.api.model.AgencyAdminResponseDTO; import de.caritas.cob.agencyservice.api.model.AgencyTypeRequestDTO; import de.caritas.cob.agencyservice.api.model.DataProtectionContactDTO; +import de.caritas.cob.agencyservice.api.model.DataProtectionDTO; import de.caritas.cob.agencyservice.api.model.DemographicsDTO; import de.caritas.cob.agencyservice.api.model.UpdateAgencyDTO; import de.caritas.cob.agencyservice.api.model.AgencyDTO; import de.caritas.cob.agencyservice.api.repository.agency.Agency; -import de.caritas.cob.agencyservice.api.repository.agency.AgencyRepository; import de.caritas.cob.agencyservice.api.repository.agency.AgencyTenantUnawareRepository; import de.caritas.cob.agencyservice.api.repository.agency.DataProtectionResponsibleEntity; import de.caritas.cob.agencyservice.api.service.AppointmentService; -import de.caritas.cob.agencyservice.api.service.LogService; import de.caritas.cob.agencyservice.api.util.JsonConverter; import java.util.List; import java.util.Optional; @@ -108,6 +107,7 @@ void updateAgency_Should_ThrowNotFoundException_WhenAgencyIsNotFound() { @Test void createAgency_Should_CreateAgencyAndAddDefaultCounsellingRelations() { + // given var agency = this.easyRandom.nextObject(Agency.class); agency.setCounsellingRelations(null); agency.setDataProtectionOfficerContactData(null); @@ -115,11 +115,15 @@ void createAgency_Should_CreateAgencyAndAddDefaultCounsellingRelations() { var agencyDTO = this.easyRandom.nextObject(AgencyDTO.class); agencyDTO.setCounsellingRelations(null); agencyDTO.setConsultingType(1); + agencyDTO.setDataProtection(new DataProtectionDTO()); when(agencyRepository.save(any())).thenReturn(agency); + // when agencyAdminService.createAgency(agencyDTO); + // then verify(agencyRepository).save(agencyArgumentCaptor.capture()); assertThat(agencyArgumentCaptor.getValue().getCounsellingRelations(), is("RELATIVE_COUNSELLING,SELF_COUNSELLING,PARENTAL_COUNSELLING")); + verify(dataProtectionConverter).convertToEntity(Mockito.any(DataProtectionDTO.class), Mockito.any(Agency.AgencyBuilder.class)); } @Test From 199cd47e8a6dd5c93122a3b0fa8f90afca8122ea Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Tue, 30 Jan 2024 17:11:19 +0100 Subject: [PATCH 21/29] fix: add logic that enables data protection persistence on agency create --- .../api/admin/service/AgencyAdminService.java | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminService.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminService.java index b8411500..d22fa70a 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminService.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminService.java @@ -146,13 +146,7 @@ private Agency fromAgencyDTO(AgencyDTO agencyDTO) { if (featureDemographicsEnabled && agencyDTO.getDemographics() != null) { demographicsConverter.convertToEntity(agencyDTO.getDemographics(), agencyBuilder); } - - if (dataProtectionConverter != null) { - dataProtectionConverter.convertToEntity(agencyDTO.getDataProtection(), agencyBuilder); - } - - - + dataProtectionConverter.convertToEntity(agencyDTO.getDataProtection(), agencyBuilder); var agencyToCreate = agencyBuilder.build(); if (featureTopicsEnabled) { @@ -215,9 +209,7 @@ private Agency mergeAgencies(Agency agency, UpdateAgencyDTO updateAgencyDTO) { .counsellingRelations(agency.getCounsellingRelations()) .deleteDate(agency.getDeleteDate()); - if (dataProtectionConverter != null) { - dataProtectionConverter.convertToEntity(updateAgencyDTO.getDataProtection(), agencyBuilder); - } + dataProtectionConverter.convertToEntity(updateAgencyDTO.getDataProtection(), agencyBuilder); if (nonNull(updateAgencyDTO.getConsultingType())) { agencyBuilder.consultingTypeId(updateAgencyDTO.getConsultingType()); From 7b17d331c60e1e2bed9691c7084d3460f51aa822 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Thu, 1 Feb 2024 10:54:21 +0100 Subject: [PATCH 22/29] fix: take privacy template from main tenant if single domain and tenant-level-override is disabled --- .../CentralDataProtectionTemplateService.java | 51 +++++++-- .../api/service/TenantService.java | 19 ++++ ...tralDataProtectionTemplateServiceTest.java | 105 ++++++++++++++---- 3 files changed, 146 insertions(+), 29 deletions(-) diff --git a/src/main/java/de/caritas/cob/agencyservice/api/service/CentralDataProtectionTemplateService.java b/src/main/java/de/caritas/cob/agencyservice/api/service/CentralDataProtectionTemplateService.java index c688d067..f685b7ee 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/service/CentralDataProtectionTemplateService.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/service/CentralDataProtectionTemplateService.java @@ -15,6 +15,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import de.caritas.cob.agencyservice.tenantservice.generated.web.model.RestrictedTenantDTO; @@ -27,9 +28,23 @@ public class CentralDataProtectionTemplateService { private final @NonNull TemplateRenderer templateRenderer; + private final @NonNull ApplicationSettingsService applicationSettingsService; + + @Value("${feature.multitenancy.with.single.domain.enabled}") + private boolean multitenancyWithSingleDomain; + + private boolean isTenantLevelLegalContentOverrideAllowed() { + de.caritas.cob.agencyservice.applicationsettingsservice.generated.web.model.ApplicationSettingsDTOMultitenancyWithSingleDomainEnabled + legalContentChangesBySingleTenantAdminsAllowed = + applicationSettingsService + .getApplicationSettings() + .getLegalContentChangesBySingleTenantAdminsAllowed(); + return legalContentChangesBySingleTenantAdminsAllowed != null + && Boolean.TRUE.equals(legalContentChangesBySingleTenantAdminsAllowed.getValue()); + } + public String renderPrivacyTemplateWithRenderedPlaceholderValues(Agency agency) { - RestrictedTenantDTO restrictedTenantDataByTenantId = tenantService.getRestrictedTenantDataByTenantId( - agency.getTenantId()); + RestrictedTenantDTO restrictedTenantDataByTenantId = retrieveProperTenant(agency); if (restrictedTenantDataByTenantId != null && restrictedTenantDataByTenantId.getContent() != null) { return renderPrivacyTemplateWithRenderedPlaceholderValues(agency, @@ -42,7 +57,8 @@ public String renderPrivacyTemplateWithRenderedPlaceholderValues(Agency agency) @Nullable private String renderPrivacyTemplateWithRenderedPlaceholderValues(Agency agency, RestrictedTenantDTO restrictedTenantDataByTenantId) { - var renderedPlaceholdersMap = renderDataProtectionPlaceholdersFromTemplates(agency); + var renderedPlaceholdersMap = renderDataProtectionPlaceholdersFromTemplates(agency, + restrictedTenantDataByTenantId); Map dataModel = renderedPlaceholdersMap.entrySet().stream() .collect(Collectors.toMap(entry -> entry.getKey().getPlaceholderVariable(), Entry::getValue)); @@ -56,10 +72,26 @@ private String renderPrivacyTemplateWithRenderedPlaceholderValues(Agency agency, } } - protected Map renderDataProtectionPlaceholdersFromTemplates( + private de.caritas.cob.agencyservice.tenantservice.generated.web.model.RestrictedTenantDTO retrieveProperTenant( + Agency agency) { + if (multitenancyWithSingleDomain) { + return getAgencyTenantOrFallbackToMainTenantIfTenantPrivacyOverrideNotAllowed(agency); + } else { + return tenantService.getRestrictedTenantDataByTenantId(agency.getTenantId()); + } + } + + private de.caritas.cob.agencyservice.tenantservice.generated.web.model.RestrictedTenantDTO getAgencyTenantOrFallbackToMainTenantIfTenantPrivacyOverrideNotAllowed( Agency agency) { - RestrictedTenantDTO restrictedTenantDataByTenantId = tenantService.getRestrictedTenantDataByTenantId( - agency.getTenantId()); + if (isTenantLevelLegalContentOverrideAllowed()) { + return tenantService.getRestrictedTenantDataByTenantId(agency.getTenantId()); + } else { + return tenantService.getMainTenant(); + } + } + + protected Map renderDataProtectionPlaceholdersFromTemplates( + Agency agency, RestrictedTenantDTO restrictedTenantDataByTenantId) { Map result = Maps.newHashMap(); if (restrictedTenantDataByTenantId.getContent() != null @@ -67,15 +99,16 @@ protected Map renderDataProtectionPlaceho var renderedDataProtectionOfficerContact = renderDataProtectionOfficerContactFromTemplate( agency, restrictedTenantDataByTenantId.getContent().getDataProtectionContactTemplate()); - result.put(DataProtectionPlaceHolderType.DATA_PROTECTION_OFFICER, - renderedDataProtectionOfficerContact != null ? renderedDataProtectionOfficerContact : StringUtils.EMPTY); + renderedDataProtectionOfficerContact != null ? renderedDataProtectionOfficerContact + : StringUtils.EMPTY); var renderedDataProtectionResponsible = renderDataProtectionResponsibleFromTemplate( agency, restrictedTenantDataByTenantId.getContent().getDataProtectionContactTemplate()); result.put(DataProtectionPlaceHolderType.DATA_PROTECTION_RESPONSIBLE, - renderedDataProtectionResponsible != null ? renderedDataProtectionResponsible : StringUtils.EMPTY); + renderedDataProtectionResponsible != null ? renderedDataProtectionResponsible + : StringUtils.EMPTY); } return result; diff --git a/src/main/java/de/caritas/cob/agencyservice/api/service/TenantService.java b/src/main/java/de/caritas/cob/agencyservice/api/service/TenantService.java index 0e5f2525..0f3a9b9a 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/service/TenantService.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/service/TenantService.java @@ -16,9 +16,15 @@ public class TenantService { private final @NonNull TenantServiceApiControllerFactory tenantServiceApiControllerFactory; + private final @NonNull ApplicationSettingsService applicationSettingsService; + @Value("${multitenancy.enabled}") private boolean multitenancy; + + @Value("${feature.multitenancy.with.single.domain.enabled}") + private boolean multitenancyWithSingleDomain; + @Cacheable(cacheNames = CacheManagerConfig.TENANT_CACHE, key = "#subdomain") public RestrictedTenantDTO getRestrictedTenantDataBySubdomain(String subdomain) { TenantControllerApi controllerApi = tenantServiceApiControllerFactory.createControllerApi(); @@ -34,4 +40,17 @@ public RestrictedTenantDTO getRestrictedTenantDataForSingleTenant() { TenantControllerApi controllerApi = tenantServiceApiControllerFactory.createControllerApi(); return controllerApi.getRestrictedSingleTenancyTenantData(); } + + public RestrictedTenantDTO getMainTenant() { + if (multitenancyWithSingleDomain) { + return getRestrictedTenantDataBySubdomain(getMainTenantSubdomain()); + } + throw new IllegalStateException("Main tenant can only be retrieved if multitenancy with single domain is enabled."); + } + + private String getMainTenantSubdomain() { + return applicationSettingsService + .getApplicationSettings() + .getMainTenantSubdomainForSingleDomainMultitenancy().getValue(); + } } diff --git a/src/test/java/de/caritas/cob/agencyservice/api/service/CentralDataProtectionTemplateServiceTest.java b/src/test/java/de/caritas/cob/agencyservice/api/service/CentralDataProtectionTemplateServiceTest.java index fc4c5511..b1ce330c 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/service/CentralDataProtectionTemplateServiceTest.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/service/CentralDataProtectionTemplateServiceTest.java @@ -8,11 +8,14 @@ import de.caritas.cob.agencyservice.api.repository.agency.Agency; import de.caritas.cob.agencyservice.api.repository.agency.DataProtectionResponsibleEntity; import de.caritas.cob.agencyservice.api.util.JsonConverter; +import de.caritas.cob.agencyservice.applicationsettingsservice.generated.web.model.ApplicationSettingsDTO; +import de.caritas.cob.agencyservice.applicationsettingsservice.generated.web.model.ApplicationSettingsDTOMultitenancyWithSingleDomainEnabled; import de.caritas.cob.agencyservice.tenantservice.generated.web.model.AgencyContextDTO; import de.caritas.cob.agencyservice.tenantservice.generated.web.model.Content; import de.caritas.cob.agencyservice.tenantservice.generated.web.model.DataProtectionContactTemplateDTO; import de.caritas.cob.agencyservice.tenantservice.generated.web.model.DataProtectionOfficerDTO; import de.caritas.cob.agencyservice.tenantservice.generated.web.model.RestrictedTenantDTO; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -22,6 +25,7 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.util.ReflectionTestUtils; @RunWith(SpringRunner.class) @SpringBootTest @@ -37,6 +41,18 @@ class CentralDataProtectionTemplateServiceTest { @MockBean TenantService tenantService; + @MockBean + ApplicationSettingsService applicationSettingsService; + + @BeforeEach + void setup() { + ReflectionTestUtils.setField(centralDataProtectionTemplateService, + "multitenancyWithSingleDomain", false); + when(applicationSettingsService.getApplicationSettings()).thenReturn( + new ApplicationSettingsDTO().legalContentChangesBySingleTenantAdminsAllowed( + new ApplicationSettingsDTOMultitenancyWithSingleDomainEnabled().value(true))); + } + @Test void renderDataProtectionPrivacy_shouldProperlyRenderPrivacy_When_PlaceholdersAreRendered() { @@ -57,7 +73,8 @@ void renderDataProtectionPrivacy_shouldProperlyRenderPrivacy_When_PlaceholdersAr .name("agencyName") .dataProtectionResponsibleEntity(DataProtectionResponsibleEntity.DATA_PROTECTION_OFFICER) .dataProtectionOfficerContactData(JsonConverter.convertToJson(dataProtectionContactDTO)) - .dataProtectionAgencyResponsibleContactData(JsonConverter.convertToJson(dataProtectionContactDTO)) + .dataProtectionAgencyResponsibleContactData( + JsonConverter.convertToJson(dataProtectionContactDTO)) .build(); // when @@ -70,6 +87,47 @@ void renderDataProtectionPrivacy_shouldProperlyRenderPrivacy_When_PlaceholdersAr "Privacy template with placeholders: Data protection officer contact name: Max Mustermann, Data protection responsible contact name: Max Mustermann,"); } + @Test + void renderDataProtectionPrivacy_shouldProperlyRenderPrivacyTakingTemplateFromMainTenant_When_MultitenancySingleDomainAndTenantLevelPrivacyOverrideNotAllowed() { + // given + ReflectionTestUtils.setField(centralDataProtectionTemplateService, + "multitenancyWithSingleDomain", true); + when(applicationSettingsService.getApplicationSettings()).thenReturn( + new ApplicationSettingsDTO().legalContentChangesBySingleTenantAdminsAllowed( + new ApplicationSettingsDTOMultitenancyWithSingleDomainEnabled().value(false))); + + when(tenantService.getMainTenant()).thenReturn( + new RestrictedTenantDTO() + .content( + new Content().dataProtectionContactTemplate(getDataProtectionContactTemplate()) + .privacy( + "Privacy template with placeholders from main tenant: ${dataProtectionOfficer} ${responsible}"))); + DataProtectionContactDTO dataProtectionContactDTO = new DataProtectionContactDTO() + .nameAndLegalForm("Max Mustermann"); + + Agency agency = Agency.builder() + .id(1000L) + .tenantId(1L) + .consultingTypeId(1) + .name("agencyName") + .dataProtectionResponsibleEntity(DataProtectionResponsibleEntity.DATA_PROTECTION_OFFICER) + .dataProtectionOfficerContactData(JsonConverter.convertToJson(dataProtectionContactDTO)) + .dataProtectionAgencyResponsibleContactData( + JsonConverter.convertToJson(dataProtectionContactDTO)) + .build(); + + // when + var renderedPrivacy = centralDataProtectionTemplateService.renderPrivacyTemplateWithRenderedPlaceholderValues( + agency); + + // then + assertThat( + renderedPrivacy).isEqualTo( + "Privacy template with placeholders from main tenant: Data protection officer contact name: Max Mustermann, Data protection responsible contact name: Max Mustermann,"); + + } + + @Test void renderDataProtectionPrivacy_shouldReturnPrivacyAsItIs_When_PlaceholdersAreNotIncludedInPrivacy() { @@ -90,7 +148,8 @@ void renderDataProtectionPrivacy_shouldReturnPrivacyAsItIs_When_PlaceholdersAreN .name("agencyName") .dataProtectionResponsibleEntity(DataProtectionResponsibleEntity.DATA_PROTECTION_OFFICER) .dataProtectionOfficerContactData(JsonConverter.convertToJson(dataProtectionContactDTO)) - .dataProtectionAgencyResponsibleContactData(JsonConverter.convertToJson(dataProtectionContactDTO)) + .dataProtectionAgencyResponsibleContactData( + JsonConverter.convertToJson(dataProtectionContactDTO)) .build(); // when @@ -107,10 +166,11 @@ void renderDataProtectionPrivacy_shouldReturnPrivacyAsItIs_When_PlaceholdersAreN void renderDataProtectionTemplatePlaceholders_shouldProperlyRenderPlaceholders_If_SomeVariableDataIsMissing() { // given + RestrictedTenantDTO tenantDTO = new RestrictedTenantDTO() + .content( + new Content().dataProtectionContactTemplate(getDataProtectionContactTemplate())); when(tenantService.getRestrictedTenantDataByTenantId(anyLong())).thenReturn( - new RestrictedTenantDTO() - .content( - new Content().dataProtectionContactTemplate(getDataProtectionContactTemplate()))); + tenantDTO); DataProtectionContactDTO dataProtectionContactDTO = new DataProtectionContactDTO() .nameAndLegalForm("Max Mustermann"); @@ -121,12 +181,13 @@ void renderDataProtectionTemplatePlaceholders_shouldProperlyRenderPlaceholders_I .name("agencyName") .dataProtectionResponsibleEntity(DataProtectionResponsibleEntity.DATA_PROTECTION_OFFICER) .dataProtectionOfficerContactData(JsonConverter.convertToJson(dataProtectionContactDTO)) - .dataProtectionAgencyResponsibleContactData(JsonConverter.convertToJson(dataProtectionContactDTO)) + .dataProtectionAgencyResponsibleContactData( + JsonConverter.convertToJson(dataProtectionContactDTO)) .build(); // when var renderedPlaceholders = centralDataProtectionTemplateService.renderDataProtectionPlaceholdersFromTemplates( - agency); + agency, tenantDTO); // then assertThat( @@ -140,10 +201,11 @@ void renderDataProtectionTemplatePlaceholders_shouldProperlyRenderPlaceholders_I void renderDataProtectionTemplatePlaceholders_shouldProperlyRenderPlaceholders() { // given + RestrictedTenantDTO tenantDTO = new RestrictedTenantDTO() + .content( + new Content().dataProtectionContactTemplate(getDataProtectionContactTemplate())); when(tenantService.getRestrictedTenantDataByTenantId(anyLong())).thenReturn( - new RestrictedTenantDTO() - .content( - new Content().dataProtectionContactTemplate(getDataProtectionContactTemplate()))); + tenantDTO); DataProtectionContactDTO dataProtectionContactDTO = new DataProtectionContactDTO() .nameAndLegalForm("Max Mustermann") .street("Musterstraße 1") @@ -158,12 +220,13 @@ void renderDataProtectionTemplatePlaceholders_shouldProperlyRenderPlaceholders() .name("agencyName") .dataProtectionResponsibleEntity(DataProtectionResponsibleEntity.DATA_PROTECTION_OFFICER) .dataProtectionOfficerContactData(JsonConverter.convertToJson(dataProtectionContactDTO)) - .dataProtectionAgencyResponsibleContactData(JsonConverter.convertToJson(dataProtectionContactDTO)) + .dataProtectionAgencyResponsibleContactData( + JsonConverter.convertToJson(dataProtectionContactDTO)) .build(); // when var renderedPlaceholders = centralDataProtectionTemplateService.renderDataProtectionPlaceholdersFromTemplates( - agency); + agency, tenantDTO); // then assertThat( @@ -178,10 +241,11 @@ void renderDataProtectionTemplatePlaceholders_shouldProperlyRenderPlaceholders() void renderDataProtectionTemplatePlaceholders_shouldReturnPlaceholderTemplate_IfDataProtectionAgencyContactDataIsNotSet() { // given + RestrictedTenantDTO tenantDTO = new RestrictedTenantDTO() + .content( + new Content().dataProtectionContactTemplate(getDataProtectionContactTemplate())); when(tenantService.getRestrictedTenantDataByTenantId(anyLong())).thenReturn( - new RestrictedTenantDTO() - .content( - new Content().dataProtectionContactTemplate(getDataProtectionContactTemplate()))); + tenantDTO); Agency agency = Agency.builder() .id(1000L) @@ -193,7 +257,7 @@ void renderDataProtectionTemplatePlaceholders_shouldReturnPlaceholderTemplate_If // when var renderedPlaceholders = centralDataProtectionTemplateService.renderDataProtectionPlaceholdersFromTemplates( - agency); + agency, tenantDTO); // then assertThat( @@ -208,10 +272,11 @@ void renderDataProtectionTemplatePlaceholders_shouldReturnPlaceholderTemplate_If void renderDataProtectionTemplatePlaceholders_shouldReturnPlaceholderTemplate_IfNoDataOnAgency() { // given + RestrictedTenantDTO tenantDTO = new RestrictedTenantDTO() + .content( + new Content().dataProtectionContactTemplate(getDataProtectionContactTemplate())); when(tenantService.getRestrictedTenantDataByTenantId(anyLong())).thenReturn( - new RestrictedTenantDTO() - .content( - new Content().dataProtectionContactTemplate(getDataProtectionContactTemplate()))); + tenantDTO); Agency agency = Agency.builder() .id(1000L) @@ -223,7 +288,7 @@ void renderDataProtectionTemplatePlaceholders_shouldReturnPlaceholderTemplate_If // when var renderedPlaceholders = centralDataProtectionTemplateService.renderDataProtectionPlaceholdersFromTemplates( - agency); + agency, tenantDTO); // then assertThat( From 9ea2e25aef62ffa18ba164908a0509f16d37917a Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Tue, 4 Jul 2023 13:09:59 +0200 Subject: [PATCH 23/29] fix: add topicIds response to agency service --- api/agencyservice.yaml | 4 ++++ .../api/service/AgencyService.java | 7 ++++++- .../AgencyControllerWithDemographicsIT.java | 18 ++++++++++++++---- .../testHelper/TestConstants.java | 4 +++- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/api/agencyservice.yaml b/api/agencyservice.yaml index 4ca5efa9..3293fc02 100644 --- a/api/agencyservice.yaml +++ b/api/agencyservice.yaml @@ -175,6 +175,10 @@ components: agencySpecificPrivacy: type: string example: "specific for agency privacy text" + topicIds: + type: array + items: + type: long FullAgencyResponseDTO: type: object diff --git a/src/main/java/de/caritas/cob/agencyservice/api/service/AgencyService.java b/src/main/java/de/caritas/cob/agencyservice/api/service/AgencyService.java index 49dde67f..5ae838f3 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/service/AgencyService.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/service/AgencyService.java @@ -16,6 +16,7 @@ import de.caritas.cob.agencyservice.api.model.FullAgencyResponseDTO; import de.caritas.cob.agencyservice.api.repository.agency.Agency; import de.caritas.cob.agencyservice.api.repository.agency.AgencyRepository; +import de.caritas.cob.agencyservice.api.repository.agencytopic.AgencyTopic; import de.caritas.cob.agencyservice.api.tenant.TenantContext; import de.caritas.cob.agencyservice.consultingtypeservice.generated.web.model.ExtendedConsultingTypeResponseDTO; import de.caritas.cob.agencyservice.tenantservice.generated.web.model.RestrictedTenantDTO; @@ -25,6 +26,7 @@ import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -336,7 +338,10 @@ private FullAgencyResponseDTO convertToFullAgencyResponseDTO(Agency agency) { .url(agency.getUrl()) .external(agency.isExternal()) .demographics(getDemographics(agency)) - .tenantId(agency.getTenantId()); + .tenantId(agency.getTenantId()) + .topicIds(agency.getAgencyTopics().stream().map(AgencyTopic::getTopicId).collect( + Collectors.toList())); + } private DemographicsDTO getDemographics(Agency agency) { diff --git a/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyControllerWithDemographicsIT.java b/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyControllerWithDemographicsIT.java index ab6150b7..1d09f49a 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyControllerWithDemographicsIT.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyControllerWithDemographicsIT.java @@ -16,6 +16,8 @@ import de.caritas.cob.agencyservice.api.manager.consultingtype.ConsultingTypeManager; import de.caritas.cob.agencyservice.api.tenant.TenantContext; + +import jakarta.transaction.Transactional; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -26,6 +28,8 @@ import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; @@ -33,6 +37,7 @@ @TestPropertySource(properties = "feature.demographics.enabled=true") @AutoConfigureMockMvc(addFilters = false) @ActiveProfiles("testing") +@Transactional class AgencyControllerWithDemographicsIT { private MockMvc mvc; @@ -87,17 +92,22 @@ void getAgencies_Should_ReturnNoContent_When_GenderParamsIsProvidedButNotMatchin @Test void getAgencies_Should_ReturnOk_When_MatchingSearchParametersAreProvided() throws Exception { - mvc.perform( - get(PATH_GET_LIST_OF_AGENCIES + "?" + "postcode=99999" + "&" - + "consultingType=19" + "&" + VALID_AGE_QUERY + "&" + VALID_GENDER_QUERY) - .accept(MediaType.APPLICATION_JSON)) + ResultActions perform = mvc.perform( + get(PATH_GET_LIST_OF_AGENCIES + "?" + "postcode=99999" + "&" + + "consultingType=19" + "&" + VALID_AGE_QUERY + "&" + VALID_GENDER_QUERY) + .accept(MediaType.APPLICATION_JSON)); + perform .andExpect(status().isOk()) .andExpect(jsonPath("$", hasSize(1))) .andExpect(jsonPath("$[0].id").value(1737)) + .andExpect(jsonPath("$[0].topicIds").isArray()) .andExpect(jsonPath("$[0].demographics.ageFrom").value(30)) .andExpect(jsonPath("$[0].demographics.ageTo").value(60)) .andExpect(jsonPath("$[0].demographics.genders[0]").value("FEMALE")) .andExpect(jsonPath("$[0].demographics.genders[1]").value("DIVERS")); + MvcResult mvcResult = perform.andReturn(); + String contentAsString = mvcResult.getResponse().getContentAsString(); } + } diff --git a/src/test/java/de/caritas/cob/agencyservice/testHelper/TestConstants.java b/src/test/java/de/caritas/cob/agencyservice/testHelper/TestConstants.java index 74daa903..50482808 100644 --- a/src/test/java/de/caritas/cob/agencyservice/testHelper/TestConstants.java +++ b/src/test/java/de/caritas/cob/agencyservice/testHelper/TestConstants.java @@ -11,6 +11,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.assertj.core.util.Lists; public class TestConstants { @@ -176,7 +177,8 @@ public class TestConstants { public static final AgencyResponseDTO AGENCY_RESPONSE_DTO = new AgencyResponseDTO().id(AGENCY_ID).name(AGENCY_NAME).postcode(POSTCODE) .city(AGENCY_CITY).description(AGENCY_DESCRIPTION).teamAgency(false).offline(false) - .consultingType(CONSULTING_TYPE_SUCHT); + .consultingType(CONSULTING_TYPE_SUCHT) + .topicIds(Lists.newArrayList(1L, 2L)); public static final List AGENCY_RESPONSE_DTO_LIST = Collections.singletonList( AGENCY_RESPONSE_DTO); public static final FullAgencyResponseDTO FULL_AGENCY_RESPONSE_DTO = From 6ae15ea3dfac2269c79402efeeaca8e1fc08d17c Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Thu, 15 Feb 2024 14:21:23 +0100 Subject: [PATCH 24/29] fix: add topicIds to response --- .../caritas/cob/agencyservice/api/service/AgencyService.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/de/caritas/cob/agencyservice/api/service/AgencyService.java b/src/main/java/de/caritas/cob/agencyservice/api/service/AgencyService.java index 5ae838f3..48a8ffd0 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/service/AgencyService.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/service/AgencyService.java @@ -309,7 +309,8 @@ private AgencyResponseDTO convertToAgencyResponseDTO(Agency agency) { .offline(agency.isOffline()) .tenantId(agency.getTenantId()) .consultingType(agency.getConsultingTypeId()) - .agencySpecificPrivacy(renderedAgencySpecificPrivacy); + .agencySpecificPrivacy(renderedAgencySpecificPrivacy) + .topicIds(agency.getAgencyTopics().stream().map(AgencyTopic::getTopicId).collect(Collectors.toList())); } protected String getRenderedAgencySpecificPrivacy(Agency agency) { From 7032b6018d2c1ad9a247c46a266962060f5f6f21 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Thu, 15 Feb 2024 17:31:45 +0100 Subject: [PATCH 25/29] feat: add association logo --- api/agencyadminservice.yaml | 9 +++++++++ api/agencyservice.yaml | 3 +++ .../api/admin/service/AgencyAdminService.java | 5 ++++- .../agency/AgencyAdminFullResponseDTOBuilder.java | 3 ++- .../agencyservice/api/repository/agency/Agency.java | 3 +++ .../agencyservice/api/service/AgencyService.java | 8 +++++--- .../db/changelog/agencyservice-dev-master.xml | 1 + .../db/changelog/agencyservice-local-master.xml | 1 + .../db/changelog/agencyservice-prod-master.xml | 1 + .../db/changelog/agencyservice-staging-master.xml | 1 + .../addAssociationLogo.sql | 2 ++ .../AgencyAdminFullResponseDTOBuilderTest.java | 1 + .../api/controller/AgencyAdminControllerIT.java | 13 +++++++++---- .../AgencyControllerWithDemographicsIT.java | 3 +-- .../cob/agencyservice/testHelper/TestConstants.java | 6 +++--- src/test/resources/database/AgencyDatabase.sql | 3 ++- 16 files changed, 48 insertions(+), 15 deletions(-) create mode 100644 src/main/resources/db/changelog/changeset/0017_add_association_logo/addAssociationLogo.sql diff --git a/api/agencyadminservice.yaml b/api/agencyadminservice.yaml index b630ca4e..0affcb91 100644 --- a/api/agencyadminservice.yaml +++ b/api/agencyadminservice.yaml @@ -524,6 +524,9 @@ components: dataProtection: type: object $ref: '#/components/schemas/DataProtectionDTO' + associationLogo: + type: string + example: "base64 encoded image" DataProtectionDTO: type: object @@ -633,6 +636,9 @@ components: dataProtection: type: object $ref: '#/components/schemas/DataProtectionDTO' + associationLogo: + type: string + example: "base64 encoded image" AgencyAdminFullResponseDTO: type: object @@ -696,6 +702,9 @@ components: dataProtection: type: object $ref: '#/components/schemas/DataProtectionDTO' + associationLogo: + type: string + example: "base64 encoded image" DemographicsDTO: type: object diff --git a/api/agencyservice.yaml b/api/agencyservice.yaml index 3293fc02..c835364e 100644 --- a/api/agencyservice.yaml +++ b/api/agencyservice.yaml @@ -179,6 +179,9 @@ components: type: array items: type: long + associationLogo: + type: string + example: "base64 encoded image" FullAgencyResponseDTO: type: object diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminService.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminService.java index d22fa70a..8d694d81 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminService.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminService.java @@ -140,9 +140,11 @@ private Agency fromAgencyDTO(AgencyDTO agencyDTO) { .url(agencyDTO.getUrl()) .isExternal(agencyDTO.getExternal()) .counsellingRelations(Joiner.on(",").join(agencyDTO.getCounsellingRelations())) + .associationLogo(agencyDTO.getAssociationLogo()) .createDate(LocalDateTime.now(ZoneOffset.UTC)) .updateDate(LocalDateTime.now(ZoneOffset.UTC)); + if (featureDemographicsEnabled && agencyDTO.getDemographics() != null) { demographicsConverter.convertToEntity(agencyDTO.getDemographics(), agencyBuilder); } @@ -207,7 +209,8 @@ private Agency mergeAgencies(Agency agency, UpdateAgencyDTO updateAgencyDTO) { .createDate(agency.getCreateDate()) .updateDate(LocalDateTime.now(ZoneOffset.UTC)) .counsellingRelations(agency.getCounsellingRelations()) - .deleteDate(agency.getDeleteDate()); + .deleteDate(agency.getDeleteDate()) + .associationLogo(updateAgencyDTO.getAssociationLogo()); dataProtectionConverter.convertToEntity(updateAgencyDTO.getDataProtection(), agencyBuilder); diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/service/agency/AgencyAdminFullResponseDTOBuilder.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/service/agency/AgencyAdminFullResponseDTOBuilder.java index ce0ef0b9..7b9bc1b1 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/admin/service/agency/AgencyAdminFullResponseDTOBuilder.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/service/agency/AgencyAdminFullResponseDTOBuilder.java @@ -53,7 +53,8 @@ private AgencyAdminResponseDTO createAgency() { .createDate(String.valueOf(this.agency.getCreateDate())) .updateDate(String.valueOf(this.agency.getUpdateDate())) .deleteDate(String.valueOf(this.agency.getDeleteDate())) - .dataProtection(new DataProtectionDTOBuilder(this.agency).fromAgency()); + .dataProtection(new DataProtectionDTOBuilder(this.agency).fromAgency()) + .associationLogo(this.agency.getAssociationLogo()); responseDTO.demographics(getDemographics(this.agency)); return responseDTO; diff --git a/src/main/java/de/caritas/cob/agencyservice/api/repository/agency/Agency.java b/src/main/java/de/caritas/cob/agencyservice/api/repository/agency/Agency.java index a2723d72..fdf5ad01 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/repository/agency/Agency.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/repository/agency/Agency.java @@ -153,6 +153,9 @@ private Integer getPostCodeInteger() { @Column(name = "counselling_relations") private String counsellingRelations; + @Column(name = "association_logo") + private String associationLogo; + @Transient public boolean hasAnyDemographicsAttributes() { return getAgeTo() != null || getAgeFrom() != null || getGenders() != null; diff --git a/src/main/java/de/caritas/cob/agencyservice/api/service/AgencyService.java b/src/main/java/de/caritas/cob/agencyservice/api/service/AgencyService.java index 48a8ffd0..b761d8eb 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/service/AgencyService.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/service/AgencyService.java @@ -2,6 +2,7 @@ import static java.util.Objects.nonNull; +import static java.util.stream.Collectors.toList; import static org.apache.commons.lang3.BooleanUtils.isTrue; import com.google.common.collect.Lists; @@ -310,7 +311,8 @@ private AgencyResponseDTO convertToAgencyResponseDTO(Agency agency) { .tenantId(agency.getTenantId()) .consultingType(agency.getConsultingTypeId()) .agencySpecificPrivacy(renderedAgencySpecificPrivacy) - .topicIds(agency.getAgencyTopics().stream().map(AgencyTopic::getTopicId).collect(Collectors.toList())); + .topicIds(agency.getAgencyTopics().stream().map(AgencyTopic::getTopicId).collect(toList())) + .associationLogo(agency.getAssociationLogo()); } protected String getRenderedAgencySpecificPrivacy(Agency agency) { @@ -340,8 +342,8 @@ private FullAgencyResponseDTO convertToFullAgencyResponseDTO(Agency agency) { .external(agency.isExternal()) .demographics(getDemographics(agency)) .tenantId(agency.getTenantId()) - .topicIds(agency.getAgencyTopics().stream().map(AgencyTopic::getTopicId).collect( - Collectors.toList())); + .topicIds(agency.getAgencyTopics().stream().map(AgencyTopic::getTopicId).toList()) + .associationLogo(agency.getAssociationLogo()); } diff --git a/src/main/resources/db/changelog/agencyservice-dev-master.xml b/src/main/resources/db/changelog/agencyservice-dev-master.xml index 159bc005..3b9aed94 100644 --- a/src/main/resources/db/changelog/agencyservice-dev-master.xml +++ b/src/main/resources/db/changelog/agencyservice-dev-master.xml @@ -24,4 +24,5 @@ --> + diff --git a/src/main/resources/db/changelog/agencyservice-local-master.xml b/src/main/resources/db/changelog/agencyservice-local-master.xml index 8e06fc5b..c9abe790 100644 --- a/src/main/resources/db/changelog/agencyservice-local-master.xml +++ b/src/main/resources/db/changelog/agencyservice-local-master.xml @@ -23,4 +23,5 @@ --> + diff --git a/src/main/resources/db/changelog/agencyservice-prod-master.xml b/src/main/resources/db/changelog/agencyservice-prod-master.xml index e0758e35..077293a3 100644 --- a/src/main/resources/db/changelog/agencyservice-prod-master.xml +++ b/src/main/resources/db/changelog/agencyservice-prod-master.xml @@ -20,4 +20,5 @@ --> + diff --git a/src/main/resources/db/changelog/agencyservice-staging-master.xml b/src/main/resources/db/changelog/agencyservice-staging-master.xml index c84782e1..e96b9870 100644 --- a/src/main/resources/db/changelog/agencyservice-staging-master.xml +++ b/src/main/resources/db/changelog/agencyservice-staging-master.xml @@ -20,4 +20,5 @@ --> + diff --git a/src/main/resources/db/changelog/changeset/0017_add_association_logo/addAssociationLogo.sql b/src/main/resources/db/changelog/changeset/0017_add_association_logo/addAssociationLogo.sql new file mode 100644 index 00000000..bd83d3f3 --- /dev/null +++ b/src/main/resources/db/changelog/changeset/0017_add_association_logo/addAssociationLogo.sql @@ -0,0 +1,2 @@ +ALTER TABLE `agencyservice`.`agency` +ADD COLUMN `association_logo` longtext NULL; \ No newline at end of file diff --git a/src/test/java/de/caritas/cob/agencyservice/api/admin/service/agency/AgencyAdminFullResponseDTOBuilderTest.java b/src/test/java/de/caritas/cob/agencyservice/api/admin/service/agency/AgencyAdminFullResponseDTOBuilderTest.java index 7780435c..eef1f1a0 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/admin/service/agency/AgencyAdminFullResponseDTOBuilderTest.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/admin/service/agency/AgencyAdminFullResponseDTOBuilderTest.java @@ -57,6 +57,7 @@ private void assertBaseDTOAttributesAreMapped(AgencyAdminFullResponseDTO result) assertEquals(agency.getUrl(), result.getEmbedded().getUrl()); assertEquals(agency.isExternal(), result.getEmbedded().getExternal()); assertEquals(agency.getConsultingTypeId(), result.getEmbedded().getConsultingType()); + assertEquals(agency.getAssociationLogo(), result.getEmbedded().getAssociationLogo()); assertThat(result.getEmbedded().getCounsellingRelations()).containsOnly(AgencyAdminResponseDTO.CounsellingRelationsEnum.PARENTAL_COUNSELLING, AgencyAdminResponseDTO.CounsellingRelationsEnum.RELATIVE_COUNSELLING); assertEquals(String.valueOf(agency.getCreateDate()), result.getEmbedded().getCreateDate()); assertEquals(String.valueOf(agency.getUpdateDate()), result.getEmbedded().getUpdateDate()); diff --git a/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerIT.java b/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerIT.java index e57be60f..62b09eb8 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerIT.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerIT.java @@ -105,7 +105,8 @@ void getAgencyById_Should_ReturnAgencyData() throws Exception { .andExpect(jsonPath("_embedded.topics").exists()) .andExpect(jsonPath("_embedded.createDate").exists()) .andExpect(jsonPath("_embedded.updateDate").exists()) - .andExpect(jsonPath("_embedded.deleteDate").exists()); + .andExpect(jsonPath("_embedded.deleteDate").exists()) + .andExpect(jsonPath("_embedded.associationLogo").exists()); } @Test @@ -124,7 +125,8 @@ void createAgency_Should_returnStatusCreated_When_calledWithValidCreateParamsAnd .teamAgency(true) .consultingType(0) .url("https://www.test.de") - .external(true); + .external(true) + .associationLogo("base64 encoded logo"); String payload = JsonConverter.convertToJson(agencyDTO); // when, then @@ -145,7 +147,8 @@ void createAgency_Should_returnStatusCreated_When_calledWithValidCreateParamsAnd .andExpect(jsonPath("_embedded.topics").exists()) .andExpect(jsonPath("_embedded.createDate").exists()) .andExpect(jsonPath("_embedded.updateDate").exists()) - .andExpect(jsonPath("_embedded.deleteDate").exists()); + .andExpect(jsonPath("_embedded.deleteDate").exists()) + .andExpect(jsonPath("_embedded.associationLogo").value("base64 encoded logo")); } @Test @@ -269,6 +272,7 @@ void updateAgency_Should_returnStatusOk_When_CentralDataProtectionIsEnabled_And_ .name("Test update name") .description(null) .offline(true) + .associationLogo("base64 encoded logo") .external(false) .dataProtection(new DataProtectionDTO().dataProtectionResponsibleEntity(DataProtectionDTO.DataProtectionResponsibleEntityEnum.DATA_PROTECTION_OFFICER) .dataProtectionOfficerContact(new DataProtectionContactDTO().nameAndLegalForm("data protection contact").city("Munich") @@ -288,7 +292,8 @@ void updateAgency_Should_returnStatusOk_When_CentralDataProtectionIsEnabled_And_ .andExpect(jsonPath("_embedded.topics").exists()) .andExpect(jsonPath("_embedded.createDate").exists()) .andExpect(jsonPath("_embedded.updateDate").exists()) - .andExpect(jsonPath("_embedded.deleteDate").exists()); + .andExpect(jsonPath("_embedded.deleteDate").exists()) + .andExpect(jsonPath("_embedded.associationLogo").value("base64 encoded logo")); var savedAgency = agencyRepository.findById(1L).orElseThrow(); assertNull(savedAgency.getDescription()); diff --git a/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyControllerWithDemographicsIT.java b/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyControllerWithDemographicsIT.java index 1d09f49a..5d09e747 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyControllerWithDemographicsIT.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyControllerWithDemographicsIT.java @@ -105,8 +105,7 @@ void getAgencies_Should_ReturnOk_When_MatchingSearchParametersAreProvided() thro .andExpect(jsonPath("$[0].demographics.ageTo").value(60)) .andExpect(jsonPath("$[0].demographics.genders[0]").value("FEMALE")) .andExpect(jsonPath("$[0].demographics.genders[1]").value("DIVERS")); - MvcResult mvcResult = perform.andReturn(); - String contentAsString = mvcResult.getResponse().getContentAsString(); + } diff --git a/src/test/java/de/caritas/cob/agencyservice/testHelper/TestConstants.java b/src/test/java/de/caritas/cob/agencyservice/testHelper/TestConstants.java index 50482808..6854ceca 100644 --- a/src/test/java/de/caritas/cob/agencyservice/testHelper/TestConstants.java +++ b/src/test/java/de/caritas/cob/agencyservice/testHelper/TestConstants.java @@ -167,13 +167,13 @@ public class TestConstants { public static final Agency AGENCY_KREUZBUND = new Agency(AGENCY_ID, AGENCY_NAME, AGENCY_DESCRIPTION, POSTCODE, "Test city", false, CONSULTING_TYPE_KREUZBUND, false, null, false, null, null, null, - null, null, null, null, null, null, null, null, null, null, null); + null, null, null, null, null, null, null, null, null, null, null, null); public static final Agency AGENCY_ONLINE_U25 = new Agency(AGENCY_ID, AGENCY_NAME, AGENCY_DESCRIPTION, POSTCODE, "Test city", - false, CONSULTING_TYPE_U25, false, null, false, null, null, null, null, null, null, null, null, null, null, null, null, null, null); + false, CONSULTING_TYPE_U25, false, null, false, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null); public static final Agency AGENCY_OFFLINE = new Agency(AGENCY_ID, AGENCY_NAME, AGENCY_DESCRIPTION, - POSTCODE, "Test city", false, CONSULTING_TYPE_SUCHT, true, null, false, null, null, null, null, null, null, null, null, null, null, null, null, null, null); + POSTCODE, "Test city", false, CONSULTING_TYPE_SUCHT, true, null, false, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null); public static final AgencyResponseDTO AGENCY_RESPONSE_DTO = new AgencyResponseDTO().id(AGENCY_ID).name(AGENCY_NAME).postcode(POSTCODE) .city(AGENCY_CITY).description(AGENCY_DESCRIPTION).teamAgency(false).offline(false) diff --git a/src/test/resources/database/AgencyDatabase.sql b/src/test/resources/database/AgencyDatabase.sql index 8f228608..2f4d72b9 100644 --- a/src/test/resources/database/AgencyDatabase.sql +++ b/src/test/resources/database/AgencyDatabase.sql @@ -32,6 +32,7 @@ create table AGENCY DATA_PROTECTION_AGENCY_CONTACT longtext null default null, DATA_PROTECTION_OFFICER_CONTACT longtext null default null, DATA_PROTECTION_ALTERNATIVE_CONTACT longtext null default null, + ASSOCIATION_LOGO longtext null default null, primary key (ID) ); CREATE SEQUENCE SEQUENCE_AGENCY @@ -70,7 +71,7 @@ CREATE SEQUENCE SEQUENCE_AGENCY_TOPIC INSERT INTO AGENCY (ID, TENANT_ID, NAME, DESCRIPTION, POSTCODE, CITY, IS_TEAM_AGENCY, CONSULTING_TYPE, IS_OFFLINE, URL, IS_EXTERNAL, ID_OLD, CREATE_DATE, UPDATE_DATE, DELETE_DATE, COUNSELLING_RELATIONS) VALUES (0, null, 'Fachambulanz Sucht Caritas/Diakonie Bonn', 'Beratung , Behandlung und Betreuung von Alkohol-, Drogen- und Medikamentenabhängige , Spielsüchtige und Angehörige.', '53113', 'Bonn', 1, 0, 0, null, 0, 9, '2018-12-11 10:19:13', '2019-06-24 12:53:58', null, 'PARENTAL_COUNSELLING,SELF_COUNSELLING'); -INSERT INTO AGENCY (ID, TENANT_ID, NAME, DESCRIPTION, POSTCODE, CITY, IS_TEAM_AGENCY, CONSULTING_TYPE, IS_OFFLINE, URL, IS_EXTERNAL, ID_OLD, CREATE_DATE, UPDATE_DATE, DELETE_DATE, COUNSELLING_RELATIONS) VALUES (1, null, 'JUGEND SUCHT BERATUNG Köln, SKM e.V. Köln', 'Offene Sprechstunden für Jugendliche und junge Erwachsene: Dienstag 16.00-18.00 Uhr Mittwoch 16.00-17.00 Uhr Freitag 13.00-14.00 Uhr', '50672', 'Köln', 0, 0, 0, null, 0, 10, '2018-12-11 10:19:13', '2019-06-24 12:53:58', null, 'RELATIVE_COUNSELLING,SELF_COUNSELLING'); +INSERT INTO AGENCY (ID, TENANT_ID, NAME, DESCRIPTION, POSTCODE, CITY, IS_TEAM_AGENCY, CONSULTING_TYPE, IS_OFFLINE, URL, IS_EXTERNAL, ID_OLD, CREATE_DATE, UPDATE_DATE, DELETE_DATE, COUNSELLING_RELATIONS, ASSOCIATION_LOGO) VALUES (1, null, 'JUGEND SUCHT BERATUNG Köln, SKM e.V. Köln', 'Offene Sprechstunden für Jugendliche und junge Erwachsene: Dienstag 16.00-18.00 Uhr Mittwoch 16.00-17.00 Uhr Freitag 13.00-14.00 Uhr', '50672', 'Köln', 0, 0, 0, null, 0, 10, '2018-12-11 10:19:13', '2019-06-24 12:53:58', null, 'RELATIVE_COUNSELLING,SELF_COUNSELLING', 'base64 encoded logo'); INSERT INTO AGENCY (ID, TENANT_ID, NAME, DESCRIPTION, POSTCODE, CITY, IS_TEAM_AGENCY, CONSULTING_TYPE, IS_OFFLINE, URL, IS_EXTERNAL, ID_OLD, CREATE_DATE, UPDATE_DATE, DELETE_DATE, COUNSELLING_RELATIONS) VALUES (2, null, 'Caritas Suchthilfe des Rheinisch-Bergischer Kreises', null, '51465', 'Bergisch Gladbach', 0, 0, 0, null, 0, 11, '2018-12-11 10:19:13', '2019-06-24 12:53:58', null, 'RELATIVE_COUNSELLING'); From e0e5f0940982d510b1e7f1ebb3bdd5aaccd7ac78 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Thu, 15 Feb 2024 17:31:58 +0100 Subject: [PATCH 26/29] feat: add association logo --- .../0017_add_association_logo/0017-addAssociationLogo.xml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/resources/db/changelog/changeset/0017_add_association_logo/0017-addAssociationLogo.xml diff --git a/src/main/resources/db/changelog/changeset/0017_add_association_logo/0017-addAssociationLogo.xml b/src/main/resources/db/changelog/changeset/0017_add_association_logo/0017-addAssociationLogo.xml new file mode 100644 index 00000000..5398bac2 --- /dev/null +++ b/src/main/resources/db/changelog/changeset/0017_add_association_logo/0017-addAssociationLogo.xml @@ -0,0 +1,7 @@ + + + + + + + From 2040b0e8cbd4088177aea01b431658e346ed93fa Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Fri, 16 Feb 2024 10:06:54 +0100 Subject: [PATCH 27/29] feat: add association logo --- .../{0017-addAssociationLogo.xml => 0017-changeSet.xml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/main/resources/db/changelog/changeset/0017_add_association_logo/{0017-addAssociationLogo.xml => 0017-changeSet.xml} (100%) diff --git a/src/main/resources/db/changelog/changeset/0017_add_association_logo/0017-addAssociationLogo.xml b/src/main/resources/db/changelog/changeset/0017_add_association_logo/0017-changeSet.xml similarity index 100% rename from src/main/resources/db/changelog/changeset/0017_add_association_logo/0017-addAssociationLogo.xml rename to src/main/resources/db/changelog/changeset/0017_add_association_logo/0017-changeSet.xml From 9d20a0636a1d4defb2402b11342f3a65ed24ae35 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Fri, 16 Feb 2024 10:27:33 +0100 Subject: [PATCH 28/29] fix: classpath issues --- .../resources/db/changelog/agencyservice-dev-master.xml | 2 +- .../resources/db/changelog/agencyservice-local-master.xml | 2 +- .../resources/db/changelog/agencyservice-prod-master.xml | 2 +- .../db/changelog/agencyservice-staging-master.xml | 2 +- .../0017_add_association_logo/0017-changeSet-new.xml | 8 ++++++++ 5 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 src/main/resources/db/changelog/changeset/0017_add_association_logo/0017-changeSet-new.xml diff --git a/src/main/resources/db/changelog/agencyservice-dev-master.xml b/src/main/resources/db/changelog/agencyservice-dev-master.xml index 3b9aed94..c6549eb0 100644 --- a/src/main/resources/db/changelog/agencyservice-dev-master.xml +++ b/src/main/resources/db/changelog/agencyservice-dev-master.xml @@ -24,5 +24,5 @@ --> - + diff --git a/src/main/resources/db/changelog/agencyservice-local-master.xml b/src/main/resources/db/changelog/agencyservice-local-master.xml index c9abe790..00c312f1 100644 --- a/src/main/resources/db/changelog/agencyservice-local-master.xml +++ b/src/main/resources/db/changelog/agencyservice-local-master.xml @@ -23,5 +23,5 @@ --> - + diff --git a/src/main/resources/db/changelog/agencyservice-prod-master.xml b/src/main/resources/db/changelog/agencyservice-prod-master.xml index 077293a3..305791dc 100644 --- a/src/main/resources/db/changelog/agencyservice-prod-master.xml +++ b/src/main/resources/db/changelog/agencyservice-prod-master.xml @@ -20,5 +20,5 @@ --> - + diff --git a/src/main/resources/db/changelog/agencyservice-staging-master.xml b/src/main/resources/db/changelog/agencyservice-staging-master.xml index e96b9870..f62c58c1 100644 --- a/src/main/resources/db/changelog/agencyservice-staging-master.xml +++ b/src/main/resources/db/changelog/agencyservice-staging-master.xml @@ -20,5 +20,5 @@ --> - + diff --git a/src/main/resources/db/changelog/changeset/0017_add_association_logo/0017-changeSet-new.xml b/src/main/resources/db/changelog/changeset/0017_add_association_logo/0017-changeSet-new.xml new file mode 100644 index 00000000..fd016957 --- /dev/null +++ b/src/main/resources/db/changelog/changeset/0017_add_association_logo/0017-changeSet-new.xml @@ -0,0 +1,8 @@ + + + + + + + + From 15419d2a346127dee3fd67656c5d844f68ece1de Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Fri, 16 Feb 2024 11:14:09 +0100 Subject: [PATCH 29/29] fix: associationLogo renamed to agencyLogo --- api/agencyadminservice.yaml | 6 +++--- api/agencyservice.yaml | 2 +- .../api/admin/service/AgencyAdminService.java | 4 ++-- .../agency/AgencyAdminFullResponseDTOBuilder.java | 2 +- .../agencyservice/api/repository/agency/Agency.java | 4 ++-- .../cob/agencyservice/api/service/AgencyService.java | 8 +++----- .../db/changelog/agencyservice-dev-master.xml | 2 +- .../db/changelog/agencyservice-local-master.xml | 2 +- .../db/changelog/agencyservice-prod-master.xml | 2 +- .../db/changelog/agencyservice-staging-master.xml | 2 +- .../0017_changeSet.xml} | 4 ++-- .../0017_add_agency_logo/addAgencyLogo-rollback.sql | 2 ++ .../changeset/0017_add_agency_logo/addAgencyLogo.sql | 2 ++ .../0017_add_association_logo/0017-changeSet-new.xml | 8 -------- .../0017_add_association_logo/addAssociationLogo.sql | 2 -- .../agency/AgencyAdminFullResponseDTOBuilderTest.java | 2 +- .../api/controller/AgencyAdminControllerIT.java | 10 +++++----- src/test/resources/database/AgencyDatabase.sql | 4 ++-- 18 files changed, 30 insertions(+), 38 deletions(-) rename src/main/resources/db/changelog/changeset/{0017_add_association_logo/0017-changeSet.xml => 0017_add_agency_logo/0017_changeSet.xml} (74%) create mode 100644 src/main/resources/db/changelog/changeset/0017_add_agency_logo/addAgencyLogo-rollback.sql create mode 100644 src/main/resources/db/changelog/changeset/0017_add_agency_logo/addAgencyLogo.sql delete mode 100644 src/main/resources/db/changelog/changeset/0017_add_association_logo/0017-changeSet-new.xml delete mode 100644 src/main/resources/db/changelog/changeset/0017_add_association_logo/addAssociationLogo.sql diff --git a/api/agencyadminservice.yaml b/api/agencyadminservice.yaml index 0affcb91..835dbe9b 100644 --- a/api/agencyadminservice.yaml +++ b/api/agencyadminservice.yaml @@ -524,7 +524,7 @@ components: dataProtection: type: object $ref: '#/components/schemas/DataProtectionDTO' - associationLogo: + agencyLogo: type: string example: "base64 encoded image" @@ -636,7 +636,7 @@ components: dataProtection: type: object $ref: '#/components/schemas/DataProtectionDTO' - associationLogo: + agencyLogo: type: string example: "base64 encoded image" @@ -702,7 +702,7 @@ components: dataProtection: type: object $ref: '#/components/schemas/DataProtectionDTO' - associationLogo: + agencyLogo: type: string example: "base64 encoded image" diff --git a/api/agencyservice.yaml b/api/agencyservice.yaml index c835364e..9da69b31 100644 --- a/api/agencyservice.yaml +++ b/api/agencyservice.yaml @@ -179,7 +179,7 @@ components: type: array items: type: long - associationLogo: + agencyLogo: type: string example: "base64 encoded image" diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminService.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminService.java index 8d694d81..34967f15 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminService.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminService.java @@ -140,7 +140,7 @@ private Agency fromAgencyDTO(AgencyDTO agencyDTO) { .url(agencyDTO.getUrl()) .isExternal(agencyDTO.getExternal()) .counsellingRelations(Joiner.on(",").join(agencyDTO.getCounsellingRelations())) - .associationLogo(agencyDTO.getAssociationLogo()) + .agencyLogo(agencyDTO.getAgencyLogo()) .createDate(LocalDateTime.now(ZoneOffset.UTC)) .updateDate(LocalDateTime.now(ZoneOffset.UTC)); @@ -210,7 +210,7 @@ private Agency mergeAgencies(Agency agency, UpdateAgencyDTO updateAgencyDTO) { .updateDate(LocalDateTime.now(ZoneOffset.UTC)) .counsellingRelations(agency.getCounsellingRelations()) .deleteDate(agency.getDeleteDate()) - .associationLogo(updateAgencyDTO.getAssociationLogo()); + .agencyLogo(updateAgencyDTO.getAgencyLogo()); dataProtectionConverter.convertToEntity(updateAgencyDTO.getDataProtection(), agencyBuilder); diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/service/agency/AgencyAdminFullResponseDTOBuilder.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/service/agency/AgencyAdminFullResponseDTOBuilder.java index 7b9bc1b1..a7a6c9f9 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/admin/service/agency/AgencyAdminFullResponseDTOBuilder.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/service/agency/AgencyAdminFullResponseDTOBuilder.java @@ -54,7 +54,7 @@ private AgencyAdminResponseDTO createAgency() { .updateDate(String.valueOf(this.agency.getUpdateDate())) .deleteDate(String.valueOf(this.agency.getDeleteDate())) .dataProtection(new DataProtectionDTOBuilder(this.agency).fromAgency()) - .associationLogo(this.agency.getAssociationLogo()); + .agencyLogo(this.agency.getAgencyLogo()); responseDTO.demographics(getDemographics(this.agency)); return responseDTO; diff --git a/src/main/java/de/caritas/cob/agencyservice/api/repository/agency/Agency.java b/src/main/java/de/caritas/cob/agencyservice/api/repository/agency/Agency.java index fdf5ad01..5de6e9e5 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/repository/agency/Agency.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/repository/agency/Agency.java @@ -153,8 +153,8 @@ private Integer getPostCodeInteger() { @Column(name = "counselling_relations") private String counsellingRelations; - @Column(name = "association_logo") - private String associationLogo; + @Column(name = "agency_logo") + private String agencyLogo; @Transient public boolean hasAnyDemographicsAttributes() { diff --git a/src/main/java/de/caritas/cob/agencyservice/api/service/AgencyService.java b/src/main/java/de/caritas/cob/agencyservice/api/service/AgencyService.java index b761d8eb..7cd53d01 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/service/AgencyService.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/service/AgencyService.java @@ -2,7 +2,6 @@ import static java.util.Objects.nonNull; -import static java.util.stream.Collectors.toList; import static org.apache.commons.lang3.BooleanUtils.isTrue; import com.google.common.collect.Lists; @@ -27,7 +26,6 @@ import java.util.Collections; import java.util.List; import java.util.Optional; -import java.util.stream.Collectors; import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -311,8 +309,8 @@ private AgencyResponseDTO convertToAgencyResponseDTO(Agency agency) { .tenantId(agency.getTenantId()) .consultingType(agency.getConsultingTypeId()) .agencySpecificPrivacy(renderedAgencySpecificPrivacy) - .topicIds(agency.getAgencyTopics().stream().map(AgencyTopic::getTopicId).collect(toList())) - .associationLogo(agency.getAssociationLogo()); + .topicIds(agency.getAgencyTopics().stream().map(AgencyTopic::getTopicId).toList()) + .agencyLogo(agency.getAgencyLogo()); } protected String getRenderedAgencySpecificPrivacy(Agency agency) { @@ -343,7 +341,7 @@ private FullAgencyResponseDTO convertToFullAgencyResponseDTO(Agency agency) { .demographics(getDemographics(agency)) .tenantId(agency.getTenantId()) .topicIds(agency.getAgencyTopics().stream().map(AgencyTopic::getTopicId).toList()) - .associationLogo(agency.getAssociationLogo()); + .agencyLogo(agency.getAgencyLogo()); } diff --git a/src/main/resources/db/changelog/agencyservice-dev-master.xml b/src/main/resources/db/changelog/agencyservice-dev-master.xml index c6549eb0..4f973230 100644 --- a/src/main/resources/db/changelog/agencyservice-dev-master.xml +++ b/src/main/resources/db/changelog/agencyservice-dev-master.xml @@ -24,5 +24,5 @@ --> - + diff --git a/src/main/resources/db/changelog/agencyservice-local-master.xml b/src/main/resources/db/changelog/agencyservice-local-master.xml index 00c312f1..966f960b 100644 --- a/src/main/resources/db/changelog/agencyservice-local-master.xml +++ b/src/main/resources/db/changelog/agencyservice-local-master.xml @@ -23,5 +23,5 @@ --> - + diff --git a/src/main/resources/db/changelog/agencyservice-prod-master.xml b/src/main/resources/db/changelog/agencyservice-prod-master.xml index 305791dc..735a1e68 100644 --- a/src/main/resources/db/changelog/agencyservice-prod-master.xml +++ b/src/main/resources/db/changelog/agencyservice-prod-master.xml @@ -20,5 +20,5 @@ --> - + diff --git a/src/main/resources/db/changelog/agencyservice-staging-master.xml b/src/main/resources/db/changelog/agencyservice-staging-master.xml index f62c58c1..d7245283 100644 --- a/src/main/resources/db/changelog/agencyservice-staging-master.xml +++ b/src/main/resources/db/changelog/agencyservice-staging-master.xml @@ -20,5 +20,5 @@ --> - + diff --git a/src/main/resources/db/changelog/changeset/0017_add_association_logo/0017-changeSet.xml b/src/main/resources/db/changelog/changeset/0017_add_agency_logo/0017_changeSet.xml similarity index 74% rename from src/main/resources/db/changelog/changeset/0017_add_association_logo/0017-changeSet.xml rename to src/main/resources/db/changelog/changeset/0017_add_agency_logo/0017_changeSet.xml index 5398bac2..938fd256 100644 --- a/src/main/resources/db/changelog/changeset/0017_add_association_logo/0017-changeSet.xml +++ b/src/main/resources/db/changelog/changeset/0017_add_agency_logo/0017_changeSet.xml @@ -1,7 +1,7 @@ - - + diff --git a/src/main/resources/db/changelog/changeset/0017_add_agency_logo/addAgencyLogo-rollback.sql b/src/main/resources/db/changelog/changeset/0017_add_agency_logo/addAgencyLogo-rollback.sql new file mode 100644 index 00000000..1705c288 --- /dev/null +++ b/src/main/resources/db/changelog/changeset/0017_add_agency_logo/addAgencyLogo-rollback.sql @@ -0,0 +1,2 @@ +ALTER TABLE `agencyservice`.`agency` +DROP COLUMN `agency_logo`; \ No newline at end of file diff --git a/src/main/resources/db/changelog/changeset/0017_add_agency_logo/addAgencyLogo.sql b/src/main/resources/db/changelog/changeset/0017_add_agency_logo/addAgencyLogo.sql new file mode 100644 index 00000000..996fd91e --- /dev/null +++ b/src/main/resources/db/changelog/changeset/0017_add_agency_logo/addAgencyLogo.sql @@ -0,0 +1,2 @@ +ALTER TABLE `agencyservice`.`agency` +ADD COLUMN `agency_logo` longtext NULL; \ No newline at end of file diff --git a/src/main/resources/db/changelog/changeset/0017_add_association_logo/0017-changeSet-new.xml b/src/main/resources/db/changelog/changeset/0017_add_association_logo/0017-changeSet-new.xml deleted file mode 100644 index fd016957..00000000 --- a/src/main/resources/db/changelog/changeset/0017_add_association_logo/0017-changeSet-new.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/src/main/resources/db/changelog/changeset/0017_add_association_logo/addAssociationLogo.sql b/src/main/resources/db/changelog/changeset/0017_add_association_logo/addAssociationLogo.sql deleted file mode 100644 index bd83d3f3..00000000 --- a/src/main/resources/db/changelog/changeset/0017_add_association_logo/addAssociationLogo.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE `agencyservice`.`agency` -ADD COLUMN `association_logo` longtext NULL; \ No newline at end of file diff --git a/src/test/java/de/caritas/cob/agencyservice/api/admin/service/agency/AgencyAdminFullResponseDTOBuilderTest.java b/src/test/java/de/caritas/cob/agencyservice/api/admin/service/agency/AgencyAdminFullResponseDTOBuilderTest.java index eef1f1a0..32b9b838 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/admin/service/agency/AgencyAdminFullResponseDTOBuilderTest.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/admin/service/agency/AgencyAdminFullResponseDTOBuilderTest.java @@ -57,7 +57,7 @@ private void assertBaseDTOAttributesAreMapped(AgencyAdminFullResponseDTO result) assertEquals(agency.getUrl(), result.getEmbedded().getUrl()); assertEquals(agency.isExternal(), result.getEmbedded().getExternal()); assertEquals(agency.getConsultingTypeId(), result.getEmbedded().getConsultingType()); - assertEquals(agency.getAssociationLogo(), result.getEmbedded().getAssociationLogo()); + assertEquals(agency.getAgencyLogo(), result.getEmbedded().getAgencyLogo()); assertThat(result.getEmbedded().getCounsellingRelations()).containsOnly(AgencyAdminResponseDTO.CounsellingRelationsEnum.PARENTAL_COUNSELLING, AgencyAdminResponseDTO.CounsellingRelationsEnum.RELATIVE_COUNSELLING); assertEquals(String.valueOf(agency.getCreateDate()), result.getEmbedded().getCreateDate()); assertEquals(String.valueOf(agency.getUpdateDate()), result.getEmbedded().getUpdateDate()); diff --git a/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerIT.java b/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerIT.java index 62b09eb8..01397182 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerIT.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/controller/AgencyAdminControllerIT.java @@ -106,7 +106,7 @@ void getAgencyById_Should_ReturnAgencyData() throws Exception { .andExpect(jsonPath("_embedded.createDate").exists()) .andExpect(jsonPath("_embedded.updateDate").exists()) .andExpect(jsonPath("_embedded.deleteDate").exists()) - .andExpect(jsonPath("_embedded.associationLogo").exists()); + .andExpect(jsonPath("_embedded.agencyLogo").exists()); } @Test @@ -126,7 +126,7 @@ void createAgency_Should_returnStatusCreated_When_calledWithValidCreateParamsAnd .consultingType(0) .url("https://www.test.de") .external(true) - .associationLogo("base64 encoded logo"); + .agencyLogo("base64 encoded logo"); String payload = JsonConverter.convertToJson(agencyDTO); // when, then @@ -148,7 +148,7 @@ void createAgency_Should_returnStatusCreated_When_calledWithValidCreateParamsAnd .andExpect(jsonPath("_embedded.createDate").exists()) .andExpect(jsonPath("_embedded.updateDate").exists()) .andExpect(jsonPath("_embedded.deleteDate").exists()) - .andExpect(jsonPath("_embedded.associationLogo").value("base64 encoded logo")); + .andExpect(jsonPath("_embedded.agencyLogo").value("base64 encoded logo")); } @Test @@ -272,7 +272,7 @@ void updateAgency_Should_returnStatusOk_When_CentralDataProtectionIsEnabled_And_ .name("Test update name") .description(null) .offline(true) - .associationLogo("base64 encoded logo") + .agencyLogo("base64 encoded logo") .external(false) .dataProtection(new DataProtectionDTO().dataProtectionResponsibleEntity(DataProtectionDTO.DataProtectionResponsibleEntityEnum.DATA_PROTECTION_OFFICER) .dataProtectionOfficerContact(new DataProtectionContactDTO().nameAndLegalForm("data protection contact").city("Munich") @@ -293,7 +293,7 @@ void updateAgency_Should_returnStatusOk_When_CentralDataProtectionIsEnabled_And_ .andExpect(jsonPath("_embedded.createDate").exists()) .andExpect(jsonPath("_embedded.updateDate").exists()) .andExpect(jsonPath("_embedded.deleteDate").exists()) - .andExpect(jsonPath("_embedded.associationLogo").value("base64 encoded logo")); + .andExpect(jsonPath("_embedded.agencyLogo").value("base64 encoded logo")); var savedAgency = agencyRepository.findById(1L).orElseThrow(); assertNull(savedAgency.getDescription()); diff --git a/src/test/resources/database/AgencyDatabase.sql b/src/test/resources/database/AgencyDatabase.sql index 2f4d72b9..a4a870ce 100644 --- a/src/test/resources/database/AgencyDatabase.sql +++ b/src/test/resources/database/AgencyDatabase.sql @@ -32,7 +32,7 @@ create table AGENCY DATA_PROTECTION_AGENCY_CONTACT longtext null default null, DATA_PROTECTION_OFFICER_CONTACT longtext null default null, DATA_PROTECTION_ALTERNATIVE_CONTACT longtext null default null, - ASSOCIATION_LOGO longtext null default null, + AGENCY_LOGO longtext null default null, primary key (ID) ); CREATE SEQUENCE SEQUENCE_AGENCY @@ -71,7 +71,7 @@ CREATE SEQUENCE SEQUENCE_AGENCY_TOPIC INSERT INTO AGENCY (ID, TENANT_ID, NAME, DESCRIPTION, POSTCODE, CITY, IS_TEAM_AGENCY, CONSULTING_TYPE, IS_OFFLINE, URL, IS_EXTERNAL, ID_OLD, CREATE_DATE, UPDATE_DATE, DELETE_DATE, COUNSELLING_RELATIONS) VALUES (0, null, 'Fachambulanz Sucht Caritas/Diakonie Bonn', 'Beratung , Behandlung und Betreuung von Alkohol-, Drogen- und Medikamentenabhängige , Spielsüchtige und Angehörige.', '53113', 'Bonn', 1, 0, 0, null, 0, 9, '2018-12-11 10:19:13', '2019-06-24 12:53:58', null, 'PARENTAL_COUNSELLING,SELF_COUNSELLING'); -INSERT INTO AGENCY (ID, TENANT_ID, NAME, DESCRIPTION, POSTCODE, CITY, IS_TEAM_AGENCY, CONSULTING_TYPE, IS_OFFLINE, URL, IS_EXTERNAL, ID_OLD, CREATE_DATE, UPDATE_DATE, DELETE_DATE, COUNSELLING_RELATIONS, ASSOCIATION_LOGO) VALUES (1, null, 'JUGEND SUCHT BERATUNG Köln, SKM e.V. Köln', 'Offene Sprechstunden für Jugendliche und junge Erwachsene: Dienstag 16.00-18.00 Uhr Mittwoch 16.00-17.00 Uhr Freitag 13.00-14.00 Uhr', '50672', 'Köln', 0, 0, 0, null, 0, 10, '2018-12-11 10:19:13', '2019-06-24 12:53:58', null, 'RELATIVE_COUNSELLING,SELF_COUNSELLING', 'base64 encoded logo'); +INSERT INTO AGENCY (ID, TENANT_ID, NAME, DESCRIPTION, POSTCODE, CITY, IS_TEAM_AGENCY, CONSULTING_TYPE, IS_OFFLINE, URL, IS_EXTERNAL, ID_OLD, CREATE_DATE, UPDATE_DATE, DELETE_DATE, COUNSELLING_RELATIONS, AGENCY_LOGO) VALUES (1, null, 'JUGEND SUCHT BERATUNG Köln, SKM e.V. Köln', 'Offene Sprechstunden für Jugendliche und junge Erwachsene: Dienstag 16.00-18.00 Uhr Mittwoch 16.00-17.00 Uhr Freitag 13.00-14.00 Uhr', '50672', 'Köln', 0, 0, 0, null, 0, 10, '2018-12-11 10:19:13', '2019-06-24 12:53:58', null, 'RELATIVE_COUNSELLING,SELF_COUNSELLING', 'base64 encoded logo'); INSERT INTO AGENCY (ID, TENANT_ID, NAME, DESCRIPTION, POSTCODE, CITY, IS_TEAM_AGENCY, CONSULTING_TYPE, IS_OFFLINE, URL, IS_EXTERNAL, ID_OLD, CREATE_DATE, UPDATE_DATE, DELETE_DATE, COUNSELLING_RELATIONS) VALUES (2, null, 'Caritas Suchthilfe des Rheinisch-Bergischer Kreises', null, '51465', 'Bergisch Gladbach', 0, 0, 0, null, 0, 11, '2018-12-11 10:19:13', '2019-06-24 12:53:58', null, 'RELATIVE_COUNSELLING');