From 3e30cf2d1771a8b2c6e10c85fae67aa08d317444 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Thu, 25 Apr 2019 12:22:45 +0200 Subject: [PATCH] merging current DTO during deserialization --- .../hsadminng/security/SecurityUtils.java | 3 +- .../hsadminng/service/IdToDtoResolver.java | 2 +- .../hsadminng/service/ShareService.java | 2 +- .../accessfilter/JSonAccessFilter.java | 20 +++- .../JSonDeserializerWithAccessFilter.java | 78 +++++++++++---- .../JSonSerializerWithAccessFilter.java | 37 +++---- .../hsadminng/service/accessfilter/Role.java | 12 +-- .../service/accessfilter/SelfId.java | 4 + .../hsadminng/service/dto/AssetDTO.java | 12 +-- .../hsadminng/service/dto/CustomerDTO.java | 18 +++- .../hsadminng/service/dto/FluentBuilder.java | 15 +++ .../hsadminng/service/dto/MembershipDTO.java | 12 +-- .../hsadminng/service/dto/ShareDTO.java | 26 +++-- .../hsadminng/service/mapper/AssetMapper.java | 2 +- .../hsadminng/service/mapper/ShareMapper.java | 2 +- .../hsadminng/web/rest/CustomerResource.java | 13 ++- .../asset/asset-detail.component.html | 2 +- .../app/entities/asset/asset.component.html | 4 +- .../share/share-detail.component.html | 2 +- .../app/entities/share/share.component.html | 4 +- .../webapp/app/shared/model/asset.model.ts | 4 +- .../webapp/app/shared/model/share.model.ts | 4 +- src/main/webapp/i18n/de/custom-error.json | 1 + src/main/webapp/i18n/en/custom-error.json | 1 + ...nDeserializerWithAccessFilterUnitTest.java | 96 +++++++++++++++---- ...SonSerializerWithAccessFilterUnitTest.java | 38 +++++++- .../accessfilter/MockSecurityContext.java | 7 +- .../service/accessfilter/RoleUnitTest.java | 4 +- .../service/dto/CustomerDTOUnitTest.java | 95 +++++++++++++++--- .../service/dto/MembershipDTOUnitTest.java | 28 +++++- .../service/dto/ShareDTOUnitTest.java | 2 +- .../web/rest/CustomerResourceIntTest.java | 44 +++++---- 32 files changed, 431 insertions(+), 163 deletions(-) create mode 100644 src/main/java/org/hostsharing/hsadminng/service/dto/FluentBuilder.java diff --git a/src/main/java/org/hostsharing/hsadminng/security/SecurityUtils.java b/src/main/java/org/hostsharing/hsadminng/security/SecurityUtils.java index e06fe195..f5a4a1cb 100644 --- a/src/main/java/org/hostsharing/hsadminng/security/SecurityUtils.java +++ b/src/main/java/org/hostsharing/hsadminng/security/SecurityUtils.java @@ -80,7 +80,6 @@ public final class SecurityUtils { } public static Role getLoginUserRoleFor(final Class onDtoClass, final Long onId) { - final Role highestRole = userRoleAssignments.stream(). map(ura -> matches(onDtoClass, onId, ura) @@ -91,7 +90,7 @@ public final class SecurityUtils { } private static boolean matches(Class onDtoClass, Long onId, UserRoleAssignment ura) { - final boolean matches = (ura.onClass == null || onDtoClass == ura.onClass) && (ura.onId == null || onId.equals(ura.onId) ); + final boolean matches = (ura.onClass == null || onDtoClass == ura.onClass) && (ura.onId == null || ura.onId.equals(onId)); return matches; } diff --git a/src/main/java/org/hostsharing/hsadminng/service/IdToDtoResolver.java b/src/main/java/org/hostsharing/hsadminng/service/IdToDtoResolver.java index 14b15828..32851fb6 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/IdToDtoResolver.java +++ b/src/main/java/org/hostsharing/hsadminng/service/IdToDtoResolver.java @@ -3,5 +3,5 @@ package org.hostsharing.hsadminng.service; import java.util.Optional; public interface IdToDtoResolver { - Optional findOne(Long id); + Optional findOne(Long id); } diff --git a/src/main/java/org/hostsharing/hsadminng/service/ShareService.java b/src/main/java/org/hostsharing/hsadminng/service/ShareService.java index f144bf9b..c9ff868b 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/ShareService.java +++ b/src/main/java/org/hostsharing/hsadminng/service/ShareService.java @@ -19,7 +19,7 @@ import java.util.Optional; */ @Service @Transactional -public class ShareService { +public class ShareService implements IdToDtoResolver { private final Logger log = LoggerFactory.getLogger(ShareService.class); diff --git a/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JSonAccessFilter.java b/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JSonAccessFilter.java index 45d2b7ac..e58e2046 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JSonAccessFilter.java +++ b/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JSonAccessFilter.java @@ -4,14 +4,17 @@ import org.hostsharing.hsadminng.security.SecurityUtils; import org.hostsharing.hsadminng.service.IdToDtoResolver; import org.hostsharing.hsadminng.service.dto.MembershipDTO; import org.hostsharing.hsadminng.service.util.ReflectionUtil; +import org.hostsharing.hsadminng.web.rest.errors.BadRequestAlertException; +import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.context.ApplicationContext; -import javax.persistence.EntityNotFoundException; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; +import static com.google.common.base.Verify.verify; + abstract class JSonAccessFilter { private final ApplicationContext ctx; final T dto; @@ -72,7 +75,7 @@ abstract class JSonAccessFilter { final Long parentId = (Long) ReflectionUtil.getValue(dto, parentIdField); final Role roleOnParent = SecurityUtils.getLoginUserRoleFor(parentDtoClass, parentId); - final Object parentEntity = findParentDto(parentDtoLoader, parentId); + final Object parentEntity = loadDto(parentDtoLoader, parentId); return Role.broadest(baseRole, getLoginUserRoleOnAncestorOfDtoClassIfHigher(roleOnParent, parentEntity)); } @@ -91,9 +94,16 @@ abstract class JSonAccessFilter { } @SuppressWarnings("unchecked") - private Object findParentDto(final Class parentDtoLoader, final Long parentId) { - final IdToDtoResolver idToDtoResolver = ctx.getAutowireCapableBeanFactory().createBean(parentDtoLoader); - return idToDtoResolver.findOne(parentId).orElseThrow(() -> new EntityNotFoundException("Can't resolve parent entity ID " + parentId + " via " + parentDtoLoader)); + protected Object loadDto(final Class resolverClass, final Long id) { + verify(id != null, "id must not be null"); + + final AutowireCapableBeanFactory beanFactory = ctx.getAutowireCapableBeanFactory(); + verify(beanFactory != null, "no bean factory found, probably missing mock configuration for ApplicationContext, e.g. given(...)"); + + final IdToDtoResolver resolverBean = beanFactory.createBean(resolverClass); + verify(resolverBean != null, "no " + resolverClass.getSimpleName() + " bean created, probably missing mock configuration for AutowireCapableBeanFactory, e.g. given(...)"); + + return resolverBean.findOne(id).orElseThrow(() -> new BadRequestAlertException("Can't resolve entity ID " + id + " via " + resolverClass, resolverClass.getSimpleName(), "isNotFound")); } private static Field determineFieldWithAnnotation(final Class dtoClass, final Class idAnnotationClass) { diff --git a/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JSonDeserializerWithAccessFilter.java b/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JSonDeserializerWithAccessFilter.java index 5e918e84..de4085ec 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JSonDeserializerWithAccessFilter.java +++ b/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JSonDeserializerWithAccessFilter.java @@ -3,15 +3,18 @@ package org.hostsharing.hsadminng.service.accessfilter; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.TreeNode; import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.IntNode; import com.fasterxml.jackson.databind.node.LongNode; import com.fasterxml.jackson.databind.node.TextNode; import org.apache.commons.lang3.NotImplementedException; +import org.apache.commons.lang3.ObjectUtils; import org.hostsharing.hsadminng.service.util.ReflectionUtil; import org.hostsharing.hsadminng.web.rest.errors.BadRequestAlertException; import org.springframework.context.ApplicationContext; import java.lang.reflect.Field; +import java.time.LocalDate; import java.util.HashSet; import java.util.Set; @@ -20,7 +23,7 @@ import static org.hostsharing.hsadminng.service.util.ReflectionUtil.unchecked; public class JSonDeserializerWithAccessFilter extends JSonAccessFilter { private final TreeNode treeNode; - private final Set modifiedFields = new HashSet<>(); + private final Set writtenFields = new HashSet<>(); public JSonDeserializerWithAccessFilter(final ApplicationContext ctx, final JsonParser jsonParser, final DeserializationContext deserializationContext, Class dtoClass) { super(ctx, unchecked(dtoClass::newInstance)); @@ -30,7 +33,9 @@ public class JSonDeserializerWithAccessFilter extends JSonAccessFilter { // Jackson deserializes from the JsonParser, thus no input parameter needed. public T deserialize() { deserializeValues(); - checkAccessToModifiedFields(); + final T currentDto = loadCurrentDto(getId()); + overwriteUnmodifiedFieldsWithCurrentValues(currentDto); + checkAccessToWrittenFields(currentDto); return dto; } @@ -38,25 +43,52 @@ public class JSonDeserializerWithAccessFilter extends JSonAccessFilter { treeNode.fieldNames().forEachRemaining(fieldName -> { try { final Field field = dto.getClass().getDeclaredField(fieldName); - final Object value = readValue(treeNode, field); - writeValue(dto, field, value); - markAsModified(field); + final Object newValue = readValue(treeNode, field); + writeValue(dto, field, newValue); } catch (NoSuchFieldException e) { throw new RuntimeException("setting field " + fieldName + " failed", e); } }); } + @SuppressWarnings("unchecked") + private T loadCurrentDto(final Long id) { + if (id != null) { + return (T) loadDto(selfIdField.getAnnotation(SelfId.class).resolver(), id); + } + return null; + } + + private void overwriteUnmodifiedFieldsWithCurrentValues(final Object currentDto) { + if ( currentDto == null ) { + return; + } + for (Field field : currentDto.getClass().getDeclaredFields()) { + if (field.isAnnotationPresent(AccessFor.class) && !writtenFields.contains(field)) { + final Object value = ReflectionUtil.getValue(currentDto, field); + ReflectionUtil.setValue(dto, field, value); + } + + } + } + private Object readValue(final TreeNode treeNode, final Field field) { - final TreeNode fieldNode = treeNode.get(field.getName()); + return readValue(treeNode, field.getName(), field.getType()); + + } + + private Object readValue(final TreeNode treeNode, final String fieldName, final Class fieldClass) { + final TreeNode fieldNode = treeNode.get(fieldName); if (fieldNode instanceof TextNode) { return ((TextNode) fieldNode).asText(); } else if (fieldNode instanceof IntNode) { return ((IntNode) fieldNode).asInt(); } else if (fieldNode instanceof LongNode) { return ((LongNode) fieldNode).asLong(); + } else if (fieldNode instanceof ArrayNode && LocalDate.class.isAssignableFrom(fieldClass)) { + return LocalDate.of(((ArrayNode) fieldNode).get(0).asInt(), ((ArrayNode) fieldNode).get(1).asInt(), ((ArrayNode) fieldNode).get(2).asInt()); } else { - throw new NotImplementedException("property type not yet implemented: " + field); + throw new NotImplementedException("property type not yet implemented: " + fieldNode + " -> " + fieldName + ": " + fieldClass); } } @@ -67,30 +99,36 @@ public class JSonDeserializerWithAccessFilter extends JSonAccessFilter { ReflectionUtil.setValue(dto, field, ((Number) value).intValue()); } else if (Long.class.isAssignableFrom(field.getType()) || long.class.isAssignableFrom(field.getType())) { ReflectionUtil.setValue(dto, field, ((Number) value).longValue()); + } else if (field.getType().isEnum()) { + ReflectionUtil.setValue(dto, field, Enum.valueOf((Class) field.getType(), value.toString())); + } else if (LocalDate.class.isAssignableFrom(field.getType())) { + ReflectionUtil.setValue(dto, field, LocalDate.parse(value.toString())); } else { throw new NotImplementedException("property type not yet implemented: " + field); } + writtenFields.add(field); } - private void markAsModified(final Field field) { - modifiedFields.add(field); - } - - private void checkAccessToModifiedFields() { - modifiedFields.forEach(field -> { - if ( !field.equals(selfIdField) ) { + private void checkAccessToWrittenFields(final T currentDto) { + writtenFields.forEach(field -> { + if (!field.equals(selfIdField)) { + final Role role = getLoginUserRole(); if (getId() == null) { - if (!getLoginUserRole().isAllowedToInit(field)) { - if ( !field.equals(parentIdField)) { - throw new BadRequestAlertException("Initialization of field prohibited for current user", toDisplay(field), "initializationProhibited"); + if (!role.isAllowedToInit(field)) { + if (!field.equals(parentIdField)) { + throw new BadRequestAlertException("Initialization of field " + toDisplay(field) + " prohibited for current user role " + role, toDisplay(field), "initializationProhibited"); } else { - throw new BadRequestAlertException("Referencing field prohibited for current user", toDisplay(field), "referencingProhibited"); + throw new BadRequestAlertException("Referencing field " + toDisplay(field) + " prohibited for current user role " + role, toDisplay(field), "referencingProhibited"); } } - } else if (!getLoginUserRole().isAllowedToUpdate(field)) { - throw new BadRequestAlertException("Update of field prohibited for current user", toDisplay(field), "updateProhibited"); + } else if (isUpdate(field, dto, currentDto) && !getLoginUserRole().isAllowedToUpdate(field)){ + throw new BadRequestAlertException("Update of field " + toDisplay(field) + " prohibited for current user role " + role, toDisplay(field), "updateProhibited"); } } }); } + + private boolean isUpdate(final Field field, final T dto, T currentDto) { + return ObjectUtils.notEqual(ReflectionUtil.getValue(dto, field), ReflectionUtil.getValue(currentDto, field)); + } } diff --git a/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JSonSerializerWithAccessFilter.java b/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JSonSerializerWithAccessFilter.java index 20d38832..fbbaade3 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JSonSerializerWithAccessFilter.java +++ b/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JSonSerializerWithAccessFilter.java @@ -10,7 +10,7 @@ import java.io.IOException; import java.lang.reflect.Field; import java.time.LocalDate; -public class JSonSerializerWithAccessFilter extends JSonAccessFilter { +public class JSonSerializerWithAccessFilter extends JSonAccessFilter { private final JsonGenerator jsonGenerator; private final SerializerProvider serializerProvider; @@ -27,32 +27,35 @@ public class JSonSerializerWithAccessFilter extends JSonAccessFilter { public void serialize() throws IOException { jsonGenerator.writeStartObject(); - for (Field prop : dto.getClass().getDeclaredFields()) { - toJSon(dto, jsonGenerator, prop); + for (Field field : dto.getClass().getDeclaredFields()) { + toJSon(dto, jsonGenerator, field); } jsonGenerator.writeEndObject(); } - private void toJSon(final Object dto, final JsonGenerator jsonGenerator, final Field prop) throws IOException { - if (getLoginUserRole().isAllowedToRead(prop)) { - final String fieldName = prop.getName(); + private void toJSon(final Object dto, final JsonGenerator jsonGenerator, final Field field) throws IOException { + if (getLoginUserRole().isAllowedToRead(field)) { + final String fieldName = field.getName(); // TODO: maybe replace by serializerProvider.defaultSerialize...()? // But that makes it difficult for parallel structure with the deserializer (clumsy API). // Alternatively extract the supported types to subclasses of some abstract class and // here as well as in the deserializer just access the matching implementation through a map. // Or even completely switch from Jackson to GSON? - if (Integer.class.isAssignableFrom(prop.getType()) || int.class.isAssignableFrom(prop.getType())) { - jsonGenerator.writeNumberField(fieldName, (int) get(dto, prop)); - } else if (Long.class.isAssignableFrom(prop.getType()) || long.class.isAssignableFrom(prop.getType())) { - jsonGenerator.writeNumberField(fieldName, (long) get(dto, prop)); - } else if (LocalDate.class.isAssignableFrom(prop.getType())) { - jsonGenerator.writeStringField(fieldName, get(dto, prop).toString()); // TODO proper format - } else if (Enum.class.isAssignableFrom(prop.getType())) { - jsonGenerator.writeStringField(fieldName, get(dto, prop).toString()); // TODO proper representation - } else if (String.class.isAssignableFrom(prop.getType())) { - jsonGenerator.writeStringField(fieldName, (String) get(dto, prop)); + final Object fieldValue = get(dto, field); + if (fieldValue == null) { + jsonGenerator.writeNullField(fieldName); + } else if (Integer.class.isAssignableFrom(field.getType()) || int.class.isAssignableFrom(field.getType())) { + jsonGenerator.writeNumberField(fieldName, (int) fieldValue); + } else if (Long.class.isAssignableFrom(field.getType()) || long.class.isAssignableFrom(field.getType())) { + jsonGenerator.writeNumberField(fieldName, (long) fieldValue); + } else if (LocalDate.class.isAssignableFrom(field.getType())) { + jsonGenerator.writeStringField(fieldName, fieldValue.toString()); // TODO proper format + } else if (Enum.class.isAssignableFrom(field.getType())) { + jsonGenerator.writeStringField(fieldName, fieldValue.toString()); // TODO proper representation + } else if (String.class.isAssignableFrom(field.getType())) { + jsonGenerator.writeStringField(fieldName, (String) fieldValue); } else { - throw new NotImplementedException("property type not yet implemented: " + prop); + throw new NotImplementedException("property type not yet implemented: " + field); } } } diff --git a/src/main/java/org/hostsharing/hsadminng/service/accessfilter/Role.java b/src/main/java/org/hostsharing/hsadminng/service/accessfilter/Role.java index 8fbe8c44..e1de24cf 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/accessfilter/Role.java +++ b/src/main/java/org/hostsharing/hsadminng/service/accessfilter/Role.java @@ -33,17 +33,12 @@ public enum Role { */ SUPPORTER(3), - /** - * This meta-role is to specify that any kind of customer contact can get access to the resource. - */ - ANY_CUSTOMER_CONTACT(20), - /** * This role is for contractual contacts of a customer, like a director of the company. * Who has this role, has the broadest access to all resources which belong to this customer. * Everything which relates to the contract with the customer, needs this role. */ - CONTRACTUAL_CONTACT(21), + CONTRACTUAL_CONTACT(20), /** * This role is for financial contacts of a customer, e.g. for accessing billing data. @@ -64,6 +59,11 @@ public enum Role { TECHNICAL_CONTACT(22), + /** + * This meta-role is to specify that any kind of customer contact can get access to the resource. + */ + ANY_CUSTOMER_CONTACT(29), + /** * Any user which belongs to a customer has at least this role. */ diff --git a/src/main/java/org/hostsharing/hsadminng/service/accessfilter/SelfId.java b/src/main/java/org/hostsharing/hsadminng/service/accessfilter/SelfId.java index baf95906..6c67b9fb 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/accessfilter/SelfId.java +++ b/src/main/java/org/hostsharing/hsadminng/service/accessfilter/SelfId.java @@ -1,5 +1,7 @@ package org.hostsharing.hsadminng.service.accessfilter; +import org.hostsharing.hsadminng.service.IdToDtoResolver; + import java.lang.annotation.*; /** @@ -14,4 +16,6 @@ import java.lang.annotation.*; @Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface SelfId { + /// The service which can load the referenced DTO. + Class> resolver(); } diff --git a/src/main/java/org/hostsharing/hsadminng/service/dto/AssetDTO.java b/src/main/java/org/hostsharing/hsadminng/service/dto/AssetDTO.java index b79ea4f1..d52a535a 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/dto/AssetDTO.java +++ b/src/main/java/org/hostsharing/hsadminng/service/dto/AssetDTO.java @@ -34,7 +34,7 @@ public class AssetDTO implements Serializable { private Long membershipId; - private String membershipAdmissionDocumentDate; + private String membershipDisplayReference; public Long getId() { return id; @@ -92,12 +92,12 @@ public class AssetDTO implements Serializable { this.membershipId = membershipId; } - public String getMembershipAdmissionDocumentDate() { - return membershipAdmissionDocumentDate; + public String getMembershipDisplayReference() { + return membershipDisplayReference; } - public void setMembershipAdmissionDocumentDate(String membershipAdmissionDocumentDate) { - this.membershipAdmissionDocumentDate = membershipAdmissionDocumentDate; + public void setMembershipDisplayReference(String membershipDisplayReference) { + this.membershipDisplayReference = membershipDisplayReference; } @Override @@ -131,7 +131,7 @@ public class AssetDTO implements Serializable { ", amount=" + getAmount() + ", remark='" + getRemark() + "'" + ", membership=" + getMembershipId() + - ", membership='" + getMembershipAdmissionDocumentDate() + "'" + + ", membership='" + getMembershipDisplayReference() + "'" + "}"; } } diff --git a/src/main/java/org/hostsharing/hsadminng/service/dto/CustomerDTO.java b/src/main/java/org/hostsharing/hsadminng/service/dto/CustomerDTO.java index ceefc0b9..4b9708d1 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/dto/CustomerDTO.java +++ b/src/main/java/org/hostsharing/hsadminng/service/dto/CustomerDTO.java @@ -8,6 +8,7 @@ import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import org.hostsharing.hsadminng.domain.enumeration.CustomerKind; import org.hostsharing.hsadminng.domain.enumeration.VatRegion; +import org.hostsharing.hsadminng.service.CustomerService; import org.hostsharing.hsadminng.service.accessfilter.*; import org.springframework.boot.jackson.JsonComponent; import org.springframework.context.ApplicationContext; @@ -21,9 +22,9 @@ import java.util.Objects; /** * A DTO for the Customer entity. */ -public class CustomerDTO implements Serializable { +public class CustomerDTO extends FluentBuilder implements Serializable { - @SelfId + @SelfId(resolver = CustomerService.class) @AccessFor(read = Role.ANY_CUSTOMER_USER) private Long id; @@ -41,31 +42,38 @@ public class CustomerDTO implements Serializable { @NotNull @Size(max = 80) - @AccessFor(init = Role.ADMIN, read = Role.ANY_CUSTOMER_USER) + @AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = Role.ANY_CUSTOMER_USER) private String name; @NotNull + @AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = Role.CONTRACTUAL_CONTACT) private CustomerKind kind; + @AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT}) private LocalDate birthDate; @Size(max = 80) + @AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT}) private String birthPlace; @Size(max = 80) + @AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT}) private String registrationCourt; @Size(max = 80) + @AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT}) private String registrationNumber; @NotNull + @AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT}) private VatRegion vatRegion; @Size(max = 40) + @AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT}) private String vatNumber; @Size(max = 80) - @AccessFor(init = Role.ADMIN, update = Role.CONTRACTUAL_CONTACT, read = Role.ANY_CUSTOMER_CONTACT) + @AccessFor(init = Role.ADMIN, update = Role.CONTRACTUAL_CONTACT, read = Role.CONTRACTUAL_CONTACT) private String contractualSalutation; @NotNull @@ -78,7 +86,7 @@ public class CustomerDTO implements Serializable { private String billingSalutation; @Size(max = 400) - @AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = Role.CONTRACTUAL_CONTACT) + @AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT}) private String billingAddress; @Size(max = 160) diff --git a/src/main/java/org/hostsharing/hsadminng/service/dto/FluentBuilder.java b/src/main/java/org/hostsharing/hsadminng/service/dto/FluentBuilder.java new file mode 100644 index 00000000..63cf70c6 --- /dev/null +++ b/src/main/java/org/hostsharing/hsadminng/service/dto/FluentBuilder.java @@ -0,0 +1,15 @@ +package org.hostsharing.hsadminng.service.dto; + +import java.util.function.Consumer; + +public class FluentBuilder { + + @SuppressWarnings("unchecked") + public T with( + Consumer builderFunction) { + builderFunction.accept((T) this); + return (T) this; + } + + +} diff --git a/src/main/java/org/hostsharing/hsadminng/service/dto/MembershipDTO.java b/src/main/java/org/hostsharing/hsadminng/service/dto/MembershipDTO.java index 17b9efb9..2286a064 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/dto/MembershipDTO.java +++ b/src/main/java/org/hostsharing/hsadminng/service/dto/MembershipDTO.java @@ -1,6 +1,7 @@ package org.hostsharing.hsadminng.service.dto; import org.hostsharing.hsadminng.service.CustomerService; +import org.hostsharing.hsadminng.service.MembershipService; import org.hostsharing.hsadminng.service.accessfilter.AccessFor; import org.hostsharing.hsadminng.service.accessfilter.ParentId; import org.hostsharing.hsadminng.service.accessfilter.Role; @@ -11,14 +12,13 @@ import javax.validation.constraints.Size; import java.io.Serializable; import java.time.LocalDate; import java.util.Objects; -import java.util.function.Consumer; /** * A DTO for the Membership entity. */ -public class MembershipDTO implements Serializable { +public class MembershipDTO extends FluentBuilder implements Serializable { - @SelfId + @SelfId(resolver = MembershipService.class) @AccessFor(read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT}) private Long id; @@ -47,12 +47,6 @@ public class MembershipDTO implements Serializable { @AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT}) private String customerPrefix; - public MembershipDTO with( - Consumer builderFunction) { - builderFunction.accept(this); - return this; - } - public Long getId() { return id; } diff --git a/src/main/java/org/hostsharing/hsadminng/service/dto/ShareDTO.java b/src/main/java/org/hostsharing/hsadminng/service/dto/ShareDTO.java index b7d8f54f..cb61e088 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/dto/ShareDTO.java +++ b/src/main/java/org/hostsharing/hsadminng/service/dto/ShareDTO.java @@ -1,5 +1,13 @@ package org.hostsharing.hsadminng.service.dto; +import org.hostsharing.hsadminng.domain.enumeration.ShareAction; +import org.hostsharing.hsadminng.service.MembershipService; +import org.hostsharing.hsadminng.service.ShareService; +import org.hostsharing.hsadminng.service.accessfilter.AccessFor; +import org.hostsharing.hsadminng.service.accessfilter.ParentId; +import org.hostsharing.hsadminng.service.accessfilter.Role; +import org.hostsharing.hsadminng.service.accessfilter.SelfId; + import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import java.io.Serializable; @@ -11,18 +19,16 @@ import java.util.Objects; */ public class ShareDTO implements Serializable { - @SelfId + @SelfId(resolver = ShareService.class) @AccessFor(read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT}) private Long id; @NotNull @AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT}) - @AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT}) private LocalDate documentDate; @NotNull @AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT}) - @AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT}) private LocalDate valueDate; @NotNull @@ -41,8 +47,8 @@ public class ShareDTO implements Serializable { @AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT}) private Long membershipId; - @AccessFor(init = Role.ADMIN, read = Role.SUPPORTER) - private String membershipAdmissionDocumentDate; + @AccessFor(read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT}) + private String membershipDisplayReference; public Long getId() { return id; @@ -100,12 +106,12 @@ public class ShareDTO implements Serializable { this.membershipId = membershipId; } - public String getMembershipAdmissionDocumentDate() { - return membershipAdmissionDocumentDate; + public String getMembershipDisplayReference() { + return membershipDisplayReference; } - public void setMembershipAdmissionDocumentDate(String membershipAdmissionDocumentDate) { - this.membershipAdmissionDocumentDate = membershipAdmissionDocumentDate; + public void setMembershipDisplayReference(String membershipDisplayReference) { + this.membershipDisplayReference = membershipDisplayReference; } @Override @@ -139,7 +145,7 @@ public class ShareDTO implements Serializable { ", quantity=" + getQuantity() + ", remark='" + getRemark() + "'" + ", membership=" + getMembershipId() + - ", membership='" + getMembershipAdmissionDocumentDate() + "'" + + ", membership='" + getMembershipDisplayReference() + "'" + "}"; } } diff --git a/src/main/java/org/hostsharing/hsadminng/service/mapper/AssetMapper.java b/src/main/java/org/hostsharing/hsadminng/service/mapper/AssetMapper.java index 1d686822..40399960 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/mapper/AssetMapper.java +++ b/src/main/java/org/hostsharing/hsadminng/service/mapper/AssetMapper.java @@ -12,7 +12,7 @@ import org.mapstruct.Mapping; public interface AssetMapper extends EntityMapper { @Mapping(source = "membership.id", target = "membershipId") - @Mapping(source = "membership.admissionDocumentDate", target = "membershipAdmissionDocumentDate") + @Mapping(source = "membership.admissionDocumentDate", target = "membershipDisplayReference") AssetDTO toDto(Asset asset); @Mapping(source = "membershipId", target = "membership") diff --git a/src/main/java/org/hostsharing/hsadminng/service/mapper/ShareMapper.java b/src/main/java/org/hostsharing/hsadminng/service/mapper/ShareMapper.java index 3f367ce6..775ca7be 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/mapper/ShareMapper.java +++ b/src/main/java/org/hostsharing/hsadminng/service/mapper/ShareMapper.java @@ -12,7 +12,7 @@ import org.mapstruct.Mapping; public interface ShareMapper extends EntityMapper { @Mapping(source = "membership.id", target = "membershipId") - @Mapping(source = "membership.admissionDocumentDate", target = "membershipAdmissionDocumentDate") + @Mapping(source = "membership.admissionDocumentDate", target = "membershipDisplayReference") ShareDTO toDto(Share share); @Mapping(source = "membershipId", target = "membership") diff --git a/src/main/java/org/hostsharing/hsadminng/web/rest/CustomerResource.java b/src/main/java/org/hostsharing/hsadminng/web/rest/CustomerResource.java index aa5e3710..b5a3b74e 100644 --- a/src/main/java/org/hostsharing/hsadminng/web/rest/CustomerResource.java +++ b/src/main/java/org/hostsharing/hsadminng/web/rest/CustomerResource.java @@ -1,25 +1,24 @@ package org.hostsharing.hsadminng.web.rest; + +import io.github.jhipster.web.util.ResponseUtil; +import org.hostsharing.hsadminng.service.CustomerQueryService; import org.hostsharing.hsadminng.service.CustomerService; +import org.hostsharing.hsadminng.service.dto.CustomerCriteria; +import org.hostsharing.hsadminng.service.dto.CustomerDTO; import org.hostsharing.hsadminng.web.rest.errors.BadRequestAlertException; import org.hostsharing.hsadminng.web.rest.util.HeaderUtil; import org.hostsharing.hsadminng.web.rest.util.PaginationUtil; -import org.hostsharing.hsadminng.service.dto.CustomerDTO; -import org.hostsharing.hsadminng.service.dto.CustomerCriteria; -import org.hostsharing.hsadminng.service.CustomerQueryService; -import io.github.jhipster.web.util.ResponseUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; import java.net.URI; import java.net.URISyntaxException; - import java.util.List; import java.util.Optional; @@ -72,7 +71,7 @@ public class CustomerResource { * @throws URISyntaxException if the Location URI syntax is incorrect */ @PutMapping("/customers") - public ResponseEntity updateCustomer(@Valid @RequestBody CustomerDTO customerDTO) throws URISyntaxException { + public ResponseEntity updateCustomer(@RequestBody CustomerDTO customerDTO) { log.debug("REST request to update Customer : {}", customerDTO); if (customerDTO.getId() == null) { throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); diff --git a/src/main/webapp/app/entities/asset/asset-detail.component.html b/src/main/webapp/app/entities/asset/asset-detail.component.html index 93f2e7f5..d31955d3 100644 --- a/src/main/webapp/app/entities/asset/asset-detail.component.html +++ b/src/main/webapp/app/entities/asset/asset-detail.component.html @@ -28,7 +28,7 @@
Membership
diff --git a/src/main/webapp/app/entities/asset/asset.component.html b/src/main/webapp/app/entities/asset/asset.component.html index 2b918714..29ac04a6 100644 --- a/src/main/webapp/app/entities/asset/asset.component.html +++ b/src/main/webapp/app/entities/asset/asset.component.html @@ -20,7 +20,7 @@ Action Amount Remark - Membership + Membership @@ -34,7 +34,7 @@ {{asset.remark}} diff --git a/src/main/webapp/app/entities/share/share-detail.component.html b/src/main/webapp/app/entities/share/share-detail.component.html index bd3df716..d64180ab 100644 --- a/src/main/webapp/app/entities/share/share-detail.component.html +++ b/src/main/webapp/app/entities/share/share-detail.component.html @@ -28,7 +28,7 @@
Membership
diff --git a/src/main/webapp/app/entities/share/share.component.html b/src/main/webapp/app/entities/share/share.component.html index d42d00e1..7a7ba8e6 100644 --- a/src/main/webapp/app/entities/share/share.component.html +++ b/src/main/webapp/app/entities/share/share.component.html @@ -20,7 +20,7 @@ Action Quantity Remark - Membership + Membership @@ -34,7 +34,7 @@ {{share.remark}} diff --git a/src/main/webapp/app/shared/model/asset.model.ts b/src/main/webapp/app/shared/model/asset.model.ts index f5b8f1d1..caac8b37 100644 --- a/src/main/webapp/app/shared/model/asset.model.ts +++ b/src/main/webapp/app/shared/model/asset.model.ts @@ -16,7 +16,7 @@ export interface IAsset { action?: AssetAction; amount?: number; remark?: string; - membershipAdmissionDocumentDate?: string; + membershipDisplayReference?: string; membershipId?: number; } @@ -28,7 +28,7 @@ export class Asset implements IAsset { public action?: AssetAction, public amount?: number, public remark?: string, - public membershipAdmissionDocumentDate?: string, + public membershipDisplayReference?: string, public membershipId?: number ) {} } diff --git a/src/main/webapp/app/shared/model/share.model.ts b/src/main/webapp/app/shared/model/share.model.ts index 215243a7..eade53c3 100644 --- a/src/main/webapp/app/shared/model/share.model.ts +++ b/src/main/webapp/app/shared/model/share.model.ts @@ -12,7 +12,7 @@ export interface IShare { action?: ShareAction; quantity?: number; remark?: string; - membershipAdmissionDocumentDate?: string; + membershipDisplayReference?: string; membershipId?: number; } @@ -24,7 +24,7 @@ export class Share implements IShare { public action?: ShareAction, public quantity?: number, public remark?: string, - public membershipAdmissionDocumentDate?: string, + public membershipDisplayReference?: string, public membershipId?: number ) {} } diff --git a/src/main/webapp/i18n/de/custom-error.json b/src/main/webapp/i18n/de/custom-error.json index 1a6870e2..b82d687c 100644 --- a/src/main/webapp/i18n/de/custom-error.json +++ b/src/main/webapp/i18n/de/custom-error.json @@ -1,5 +1,6 @@ { "error": { + "idNotFound": "Technische Datensatz-ID nicht gefunden", "shareSubscriptionPositiveQuantity": "Zeichnungen von Geschäftsanteilen erfordern eine positive Stückzahl", "shareCancellationNegativeQuantity": "Kündigungen von Geschäftsanteilen erfordern eine negative Stückzahl", "shareTransactionImmutable": "Transaktionen mit Geschäftsanteilen sind unveränderlich", diff --git a/src/main/webapp/i18n/en/custom-error.json b/src/main/webapp/i18n/en/custom-error.json index ee5daa7e..657e0361 100644 --- a/src/main/webapp/i18n/en/custom-error.json +++ b/src/main/webapp/i18n/en/custom-error.json @@ -1,5 +1,6 @@ { "error": { + "idNotFound": "Technical record-ID not found", "shareSubscriptionPositiveQuantity": "Share subscriptions require a positive quantity", "shareCancellationNegativeQuantity": "Share cancellations require a negative quantity", "shareTransactionImmutable": "Share transactions are immutable", diff --git a/src/test/java/org/hostsharing/hsadminng/service/accessfilter/JSonDeserializerWithAccessFilterUnitTest.java b/src/test/java/org/hostsharing/hsadminng/service/accessfilter/JSonDeserializerWithAccessFilterUnitTest.java index da59b241..af508886 100644 --- a/src/test/java/org/hostsharing/hsadminng/service/accessfilter/JSonDeserializerWithAccessFilterUnitTest.java +++ b/src/test/java/org/hostsharing/hsadminng/service/accessfilter/JSonDeserializerWithAccessFilterUnitTest.java @@ -6,6 +6,7 @@ import com.fasterxml.jackson.core.TreeNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.lang3.tuple.ImmutablePair; import org.hostsharing.hsadminng.service.IdToDtoResolver; +import org.hostsharing.hsadminng.service.dto.FluentBuilder; import org.hostsharing.hsadminng.web.rest.errors.BadRequestAlertException; import org.junit.Before; import org.junit.Rule; @@ -13,9 +14,11 @@ import org.junit.Test; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; +import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.context.ApplicationContext; import java.io.IOException; +import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.catchThrowable; @@ -31,22 +34,41 @@ public class JSonDeserializerWithAccessFilterUnitTest { public MockitoRule mockitoRule = MockitoJUnit.rule(); @Mock - public ApplicationContext ctx; + private ApplicationContext ctx; @Mock - public JsonParser jsonParser; + private AutowireCapableBeanFactory autowireCapableBeanFactory; @Mock - public ObjectCodec codec; + private JsonParser jsonParser; @Mock - public TreeNode treeNode; + private ObjectCodec codec; + + @Mock + private TreeNode treeNode; + + @Mock + private GivenService givenService; + + @Mock + private GivenChildService givenChildService; @Before public void init() { givenAuthenticatedUser(); givenUserHavingRole(GivenDto.class, 1234L, Role.ACTUAL_CUSTOMER_USER); + given (ctx.getAutowireCapableBeanFactory()).willReturn(autowireCapableBeanFactory); + given(autowireCapableBeanFactory.createBean(GivenService.class)).willReturn(givenService); + given(givenService.findOne(1234L)).willReturn(Optional.of(new GivenDto() + .with(dto -> dto.id = 1234L) + .with(dto -> dto.openIntegerField = 1) + .with(dto -> dto.openLongField = 2L) + .with(dto -> dto.openStringField = "3") + .with(dto -> dto.restrictedField = "initial value of restricted field") + )); + given(jsonParser.getCodec()).willReturn(codec); } @@ -99,21 +121,54 @@ public class JSonDeserializerWithAccessFilterUnitTest { givenUserHavingRole(GivenDto.class, 1234L, Role.FINANCIAL_CONTACT); givenJSonTree(asJSon( ImmutablePair.of("id", 1234L), - ImmutablePair.of("restrictedField", "Restricted String Value"))); + ImmutablePair.of("restrictedField", "update value of restricted field"))); // when GivenDto actualDto = new JSonDeserializerWithAccessFilter<>(ctx, jsonParser, null, GivenDto.class).deserialize(); // then - assertThat(actualDto.restrictedField).isEqualTo("Restricted String Value"); + assertThat(actualDto.restrictedField).isEqualTo("update value of restricted field"); + } + + @Test + public void shouldDeserializeUnchangedStringFieldIfRequiredRoleIsNotCoveredByUser() throws IOException { + // given + givenAuthenticatedUser(); + givenUserHavingRole(GivenDto.class, 1234L, Role.ANY_CUSTOMER_USER); + givenJSonTree(asJSon( + ImmutablePair.of("id", 1234L), + ImmutablePair.of("restrictedField", "initial value of restricted field"))); + + // when + GivenDto actualDto = new JSonDeserializerWithAccessFilter<>(ctx, jsonParser, null, GivenDto.class).deserialize(); + + // then + assertThat(actualDto.restrictedField).isEqualTo("initial value of restricted field"); + } + + @Test + public void shouldNotDeserializeUpatedStringFieldIfRequiredRoleIsNotCoveredByUser() throws IOException { + // given + givenAuthenticatedUser(); + givenUserHavingRole(GivenDto.class, 1L, Role.ANY_CUSTOMER_USER); + givenJSonTree(asJSon(ImmutablePair.of("restrictedField", "updated value of restricted field"))); + + // when + Throwable exception = catchThrowable(() -> new JSonDeserializerWithAccessFilter<>(ctx, jsonParser, null, GivenDto.class).deserialize()); + + // then + assertThat(exception).isInstanceOfSatisfying(BadRequestAlertException.class, badRequestAlertException -> { + assertThat(badRequestAlertException.getParam()).isEqualTo("GivenDto.restrictedField"); + assertThat(badRequestAlertException.getErrorKey()).isEqualTo("initializationProhibited"); + }); } @Test public void shouldInitializeFieldIfRequiredRoleIsNotCoveredByUser() throws IOException { // given givenAuthenticatedUser(); - givenUserHavingRole(null, null, Role.ANY_CUSTOMER_USER); - givenJSonTree(asJSon(ImmutablePair.of("restrictedField", "Restricted String Value"))); + givenUserHavingRole(GivenDto.class, 1L, Role.ANY_CUSTOMER_USER); + givenJSonTree(asJSon(ImmutablePair.of("restrictedField", "another value of restricted field"))); // when Throwable exception = catchThrowable(() -> new JSonDeserializerWithAccessFilter<>(ctx, jsonParser, null, GivenDto.class).deserialize()); @@ -130,7 +185,7 @@ public class JSonDeserializerWithAccessFilterUnitTest { // given givenAuthenticatedUser(); givenUserHavingRole(GivenDto.class, 9999L, Role.CONTRACTUAL_CONTACT); - givenJSonTree(asJSon(ImmutablePair.of("parentId", 1111L))); + givenJSonTree(asJSon(ImmutablePair.of("parentId", 1234L))); // when Throwable exception = catchThrowable(() -> new JSonDeserializerWithAccessFilter<>(ctx, jsonParser, null, GivenChildDto.class).deserialize()); @@ -146,14 +201,14 @@ public class JSonDeserializerWithAccessFilterUnitTest { public void shouldCreateIfRoleRequiredByReferencedEntityIsCoveredByUser() throws IOException { // given givenAuthenticatedUser(); - givenUserHavingRole(GivenDto.class, 1111L, Role.CONTRACTUAL_CONTACT); - givenJSonTree(asJSon(ImmutablePair.of("parentId", 1111L))); + givenUserHavingRole(GivenDto.class, 1234L, Role.CONTRACTUAL_CONTACT); + givenJSonTree(asJSon(ImmutablePair.of("parentId", 1234L))); // when final GivenChildDto actualDto = new JSonDeserializerWithAccessFilter<>(ctx, jsonParser, null, GivenChildDto.class).deserialize(); // then - assertThat(actualDto.parentId).isEqualTo(1111L); + assertThat(actualDto.parentId).isEqualTo(1234L); } @Test @@ -193,9 +248,12 @@ public class JSonDeserializerWithAccessFilterUnitTest { given(codec.readTree(jsonParser)).willReturn(new ObjectMapper().readTree(givenJSon)); } - public static class GivenDto { + abstract class GivenService implements IdToDtoResolver { + } - @SelfId + public static class GivenDto extends FluentBuilder { + + @SelfId(resolver = GivenService.class) @AccessFor(read = Role.ANY_CUSTOMER_USER) Long id; @@ -212,12 +270,12 @@ public class JSonDeserializerWithAccessFilterUnitTest { Long openLongField; } - abstract class GivenService implements IdToDtoResolver { + abstract class GivenChildService implements IdToDtoResolver { } - public static class GivenChildDto { + public static class GivenChildDto extends FluentBuilder { - @SelfId + @SelfId(resolver = GivenChildService.class) @AccessFor(read = Role.ANY_CUSTOMER_USER) Long id; @@ -231,11 +289,11 @@ public class JSonDeserializerWithAccessFilterUnitTest { public static class GivenDtoWithMultipleSelfId { - @SelfId + @SelfId(resolver = GivenChildService.class) @AccessFor(read = Role.ANY_CUSTOMER_USER) Long id; - @SelfId + @SelfId(resolver = GivenChildService.class) @AccessFor(read = Role.ANY_CUSTOMER_USER) Long id2; diff --git a/src/test/java/org/hostsharing/hsadminng/service/accessfilter/JSonSerializerWithAccessFilterUnitTest.java b/src/test/java/org/hostsharing/hsadminng/service/accessfilter/JSonSerializerWithAccessFilterUnitTest.java index f953bcf1..cff8cba4 100644 --- a/src/test/java/org/hostsharing/hsadminng/service/accessfilter/JSonSerializerWithAccessFilterUnitTest.java +++ b/src/test/java/org/hostsharing/hsadminng/service/accessfilter/JSonSerializerWithAccessFilterUnitTest.java @@ -5,18 +5,22 @@ import org.apache.commons.lang3.NotImplementedException; import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.RandomUtils; import org.hostsharing.hsadminng.service.IdToDtoResolver; +import org.hostsharing.hsadminng.service.dto.FluentBuilder; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; +import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.context.ApplicationContext; import java.io.IOException; +import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.catchThrowable; +import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @@ -26,10 +30,16 @@ public class JSonSerializerWithAccessFilterUnitTest { public MockitoRule mockitoRule = MockitoJUnit.rule(); @Mock - public ApplicationContext ctx; + private ApplicationContext ctx; @Mock - public JsonGenerator jsonGenerator; + private AutowireCapableBeanFactory autowireCapableBeanFactory; + + @Mock + private JsonGenerator jsonGenerator; + + @Mock + private GivenCustomerService givenCustomerService; private final GivenDto givenDTO = createSampleDto(); @@ -37,6 +47,12 @@ public class JSonSerializerWithAccessFilterUnitTest { public void init() { MockSecurityContext.givenAuthenticatedUser(); MockSecurityContext.givenUserHavingRole(GivenCustomerDto.class, 888L, Role.ANY_CUSTOMER_USER); + + given(ctx.getAutowireCapableBeanFactory()).willReturn(autowireCapableBeanFactory); + given(autowireCapableBeanFactory.createBean(GivenCustomerService.class)).willReturn(givenCustomerService); + given(givenCustomerService.findOne(888L)).willReturn(Optional.of(new GivenCustomerDto() + .with(dto -> dto.id = 888L) + )); } @Test @@ -84,7 +100,7 @@ public class JSonSerializerWithAccessFilterUnitTest { } class GivenDtoWithUnimplementedFieldType { @AccessFor(read = Role.ANYBODY) - Arbitrary fieldWithUnimplementedType; + Arbitrary fieldWithUnimplementedType = new Arbitrary(); } final GivenDtoWithUnimplementedFieldType givenDtoWithUnimplementedFieldType = new GivenDtoWithUnimplementedFieldType(); @@ -107,8 +123,10 @@ public class JSonSerializerWithAccessFilterUnitTest { return dto; } - private static class GivenCustomerDto { - + private static class GivenCustomerDto extends FluentBuilder { + @SelfId(resolver = GivenService.class) + @AccessFor(read = Role.ANYBODY) + Long id; } private abstract class GivenCustomerService implements IdToDtoResolver { @@ -116,7 +134,12 @@ public class JSonSerializerWithAccessFilterUnitTest { private static class GivenDto { + @SelfId(resolver = GivenService.class) + @AccessFor(read = Role.ANYBODY) + Long id; + @ParentId(resolver = GivenCustomerService.class) + @AccessFor(read = {Role.TECHNICAL_CONTACT, Role.FINANCIAL_CONTACT}) Long customerId; @AccessFor(read = {Role.TECHNICAL_CONTACT, Role.FINANCIAL_CONTACT}) @@ -131,4 +154,9 @@ public class JSonSerializerWithAccessFilterUnitTest { @AccessFor(read = Role.ANYBODY) Long openLongField; } + + private abstract class GivenService implements IdToDtoResolver { + } + + } diff --git a/src/test/java/org/hostsharing/hsadminng/service/accessfilter/MockSecurityContext.java b/src/test/java/org/hostsharing/hsadminng/service/accessfilter/MockSecurityContext.java index cfa66edf..dab9a8b6 100644 --- a/src/test/java/org/hostsharing/hsadminng/service/accessfilter/MockSecurityContext.java +++ b/src/test/java/org/hostsharing/hsadminng/service/accessfilter/MockSecurityContext.java @@ -20,8 +20,13 @@ public class MockSecurityContext { public static void givenUserHavingRole(final Class onClass, final Long onId, final Role role) { if ((onClass == null || onId == null) && !role.isIndependent()) { - throw new IllegalArgumentException("dependent roles like " + role + " depend on DtoClass and ID"); + throw new IllegalArgumentException("dependent roles like " + role + " missing DtoClass and ID"); } SecurityUtils.addUserRole(onClass, onId, role); } + + public static void givenUserHavingRole(final Role role) { + givenUserHavingRole(null, null, role); + } + } diff --git a/src/test/java/org/hostsharing/hsadminng/service/accessfilter/RoleUnitTest.java b/src/test/java/org/hostsharing/hsadminng/service/accessfilter/RoleUnitTest.java index d1fe7481..66944774 100644 --- a/src/test/java/org/hostsharing/hsadminng/service/accessfilter/RoleUnitTest.java +++ b/src/test/java/org/hostsharing/hsadminng/service/accessfilter/RoleUnitTest.java @@ -28,7 +28,7 @@ public class RoleUnitTest { assertThat(Role.SUPPORTER.covers(Role.ADMIN)).isFalse(); assertThat(Role.ANY_CUSTOMER_CONTACT.covers(Role.SUPPORTER)).isFalse(); - assertThat(Role.CONTRACTUAL_CONTACT.covers(Role.ANY_CUSTOMER_CONTACT)).isFalse(); + assertThat(Role.ANY_CUSTOMER_CONTACT.covers(Role.CONTRACTUAL_CONTACT)).isFalse(); assertThat(Role.FINANCIAL_CONTACT.covers(Role.CONTRACTUAL_CONTACT)).isFalse(); assertThat(Role.FINANCIAL_CONTACT.covers(Role.TECHNICAL_CONTACT)).isFalse(); assertThat(Role.TECHNICAL_CONTACT.covers(Role.CONTRACTUAL_CONTACT)).isFalse(); @@ -55,7 +55,7 @@ public class RoleUnitTest { assertThat(Role.SUPPORTER.covers(Role.ANY_CUSTOMER_CONTACT)).isTrue(); - assertThat(Role.ANY_CUSTOMER_CONTACT.covers(Role.CONTRACTUAL_CONTACT)).isTrue(); + assertThat(Role.CONTRACTUAL_CONTACT.covers(Role.ANY_CUSTOMER_CONTACT)).isTrue(); assertThat(Role.CONTRACTUAL_CONTACT.covers(Role.FINANCIAL_CONTACT)).isTrue(); assertThat(Role.CONTRACTUAL_CONTACT.covers(Role.TECHNICAL_CONTACT)).isTrue(); assertThat(Role.TECHNICAL_CONTACT.covers(Role.ANY_CUSTOMER_USER)).isTrue(); diff --git a/src/test/java/org/hostsharing/hsadminng/service/dto/CustomerDTOUnitTest.java b/src/test/java/org/hostsharing/hsadminng/service/dto/CustomerDTOUnitTest.java index 34a016ae..5d25cfea 100644 --- a/src/test/java/org/hostsharing/hsadminng/service/dto/CustomerDTOUnitTest.java +++ b/src/test/java/org/hostsharing/hsadminng/service/dto/CustomerDTOUnitTest.java @@ -2,54 +2,98 @@ package org.hostsharing.hsadminng.service.dto; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import org.hostsharing.hsadminng.domain.Customer; +import org.hostsharing.hsadminng.domain.enumeration.CustomerKind; +import org.hostsharing.hsadminng.domain.enumeration.VatRegion; +import org.hostsharing.hsadminng.repository.CustomerRepository; +import org.hostsharing.hsadminng.service.CustomerService; import org.hostsharing.hsadminng.service.accessfilter.Role; +import org.hostsharing.hsadminng.service.mapper.CustomerMapper; +import org.hostsharing.hsadminng.service.mapper.CustomerMapperImpl; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.json.JsonTest; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.context.junit4.SpringRunner; import java.io.IOException; +import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenAuthenticatedUser; import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenUserHavingRole; import static org.junit.Assert.assertEquals; +import static org.mockito.BDDMockito.given; @JsonTest +@SpringBootTest(classes = {CustomerMapperImpl.class, CustomerRepository.class, CustomerService.class, CustomerDTO.CustomerJsonSerializer.class, CustomerDTO.CustomerJsonDeserializer.class}) @RunWith(SpringRunner.class) public class CustomerDTOUnitTest { + @Rule + public MockitoRule mockito = MockitoJUnit.rule(); + @Autowired private ObjectMapper objectMapper; + @Autowired + private CustomerMapper customerMapper; + + @MockBean + private CustomerRepository customerRepository; + + @MockBean + private CustomerService customerService; + @Test public void testSerializationAsContractualCustomerContact() throws JsonProcessingException { // given givenAuthenticatedUser(); - givenUserHavingRole(CustomerDTO.class, null, Role.ANY_CUSTOMER_USER); - CustomerDTO given = createSomeCustomerDTO(); + givenUserHavingRole(CustomerDTO.class, 1234L, Role.CONTRACTUAL_CONTACT); + CustomerDTO given = createSomeCustomerDTO(1234L); // when String actual = objectMapper.writeValueAsString(given); // then - given.setContractualAddress(null); - given.setContractualSalutation(null); - given.setBillingAddress(null); - given.setBillingSalutation(null); given.setRemark(null); assertEquals(createExpectedJSon(given), actual); } + @Test + public void testSerializationAsTechnicalCustomerUser() throws JsonProcessingException { + + // given + givenAuthenticatedUser(); + givenUserHavingRole(CustomerDTO.class, 1234L, Role.TECHNICAL_CONTACT); + CustomerDTO given = createSomeCustomerDTO(1234L); + + // when + String actual = objectMapper.writeValueAsString(given); + + // then + final String expectedJSon = "{" + + toJSonFieldDefinition("id", given.getId()) + "," + + toJSonFieldDefinition("reference", given.getReference()) + "," + + toJSonFieldDefinition("prefix", given.getPrefix()) + "," + + toJSonFieldDefinition("name", given.getName()) + + "}"; + assertEquals(expectedJSon, actual); + } + @Test public void testSerializationAsSupporter() throws JsonProcessingException { // given givenAuthenticatedUser(); givenUserHavingRole(CustomerDTO.class, null, Role.SUPPORTER); - CustomerDTO given = createSomeCustomerDTO(); + CustomerDTO given = createSomeCustomerDTO(1234L); // when String actual = objectMapper.writeValueAsString(given); @@ -62,7 +106,8 @@ public class CustomerDTOUnitTest { public void testDeserializeAsContractualCustomerContact() throws IOException { // given givenAuthenticatedUser(); - givenUserHavingRole(CustomerDTO.class, null, Role.CONTRACTUAL_CONTACT); + givenUserHavingRole(CustomerDTO.class, 1234L, Role.CONTRACTUAL_CONTACT); + given(customerRepository.findById(1234L)).willReturn(Optional.of(new Customer().id(1234L))); String json = "{\"id\":1234,\"contractualSalutation\":\"Hallo Updated\",\"billingSalutation\":\"Moin Updated\"}"; // when @@ -84,14 +129,35 @@ public class CustomerDTOUnitTest { toJSonFieldDefinitionIfPresent("reference", dto.getReference()) + toJSonFieldDefinitionIfPresent("prefix", dto.getPrefix()) + toJSonFieldDefinitionIfPresent("name", dto.getName()) + + toJSonFieldDefinitionIfPresent("kind", "LEGAL") + + toJSonNullFieldDefinition("birthDate") + + toJSonNullFieldDefinition("birthPlace") + + toJSonFieldDefinitionIfPresent("registrationCourt", "Registergericht") + + toJSonFieldDefinitionIfPresent("registrationNumber", "Registernummer") + + toJSonFieldDefinitionIfPresent("vatRegion", "DOMESTIC") + + toJSonFieldDefinitionIfPresent("vatNumber", "DE1234") + toJSonFieldDefinitionIfPresent("contractualSalutation", dto.getContractualSalutation()) + toJSonFieldDefinitionIfPresent("contractualAddress", dto.getContractualAddress()) + toJSonFieldDefinitionIfPresent("billingSalutation", dto.getBillingSalutation()) + toJSonFieldDefinitionIfPresent("billingAddress", dto.getBillingAddress()) + - toJSonFieldDefinitionIfPresent("remark", dto.getRemark()) ; + toJSonFieldDefinitionIfPresent("remark", dto.getRemark()); return "{" + json.substring(0, json.length() - 1) + "}"; } + + + private String toJSonFieldDefinition(String name, String value) { + return inQuotes(name) + ":" + (value != null ? inQuotes(value) : "null"); + } + + private String toJSonFieldDefinition(String name, Number value) { + return inQuotes(name) + ":" + (value != null ? value : "null"); + } + + private String toJSonNullFieldDefinition(String name) { + return inQuotes(name) + ":null,"; + } + private String toJSonFieldDefinitionIfPresent(String name, String value) { return value != null ? inQuotes(name) + ":" + inQuotes(value) + "," : ""; } @@ -104,12 +170,17 @@ public class CustomerDTOUnitTest { return "\"" + value.toString() + "\""; } - private CustomerDTO createSomeCustomerDTO() { - CustomerDTO given = new CustomerDTO(); - given.setId(1234L); + private CustomerDTO createSomeCustomerDTO(final long id) { + final CustomerDTO given = new CustomerDTO(); + given.setId(id); given.setReference(10001); given.setPrefix("abc"); given.setName("Mein Name"); + given.setKind(CustomerKind.LEGAL); + given.setRegistrationCourt("Registergericht"); + given.setRegistrationNumber("Registernummer"); + given.setVatRegion(VatRegion.DOMESTIC); + given.setVatNumber("DE1234"); given.setContractualAddress("Eine Adresse"); given.setContractualSalutation("Hallo"); given.setBillingAddress("Noch eine Adresse"); diff --git a/src/test/java/org/hostsharing/hsadminng/service/dto/MembershipDTOUnitTest.java b/src/test/java/org/hostsharing/hsadminng/service/dto/MembershipDTOUnitTest.java index a4976186..90171bed 100644 --- a/src/test/java/org/hostsharing/hsadminng/service/dto/MembershipDTOUnitTest.java +++ b/src/test/java/org/hostsharing/hsadminng/service/dto/MembershipDTOUnitTest.java @@ -5,6 +5,8 @@ import com.fasterxml.jackson.core.ObjectCodec; import com.fasterxml.jackson.core.TreeNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.lang3.tuple.ImmutablePair; +import org.hostsharing.hsadminng.service.CustomerService; +import org.hostsharing.hsadminng.service.MembershipService; import org.hostsharing.hsadminng.service.accessfilter.JSonDeserializerWithAccessFilter; import org.hostsharing.hsadminng.service.accessfilter.Role; import org.hostsharing.hsadminng.web.rest.errors.BadRequestAlertException; @@ -14,9 +16,11 @@ import org.junit.Test; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; +import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.context.ApplicationContext; import java.io.IOException; +import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.catchThrowable; @@ -31,20 +35,36 @@ public class MembershipDTOUnitTest { public MockitoRule mockitoRule = MockitoJUnit.rule(); @Mock - public ApplicationContext ctx; + private ApplicationContext ctx; @Mock - public JsonParser jsonParser; + private AutowireCapableBeanFactory autowireCapableBeanFactory; @Mock - public ObjectCodec codec; + private JsonParser jsonParser; @Mock - public TreeNode treeNode; + private ObjectCodec codec; + + @Mock + private TreeNode treeNode; + + @Mock + private MembershipService membershipService; + + @Mock + private CustomerService customerService; @Before public void init() { given(jsonParser.getCodec()).willReturn(codec); + + given (ctx.getAutowireCapableBeanFactory()).willReturn(autowireCapableBeanFactory); + given(autowireCapableBeanFactory.createBean(MembershipService.class)).willReturn(membershipService); + given(autowireCapableBeanFactory.createBean(CustomerService.class)).willReturn(customerService); + given(customerService.findOne(1234L)).willReturn(Optional.of(new CustomerDTO() + .with(dto -> dto.setId(1234L)) + )); } @Test diff --git a/src/test/java/org/hostsharing/hsadminng/service/dto/ShareDTOUnitTest.java b/src/test/java/org/hostsharing/hsadminng/service/dto/ShareDTOUnitTest.java index b42e6ac6..b9346faf 100644 --- a/src/test/java/org/hostsharing/hsadminng/service/dto/ShareDTOUnitTest.java +++ b/src/test/java/org/hostsharing/hsadminng/service/dto/ShareDTOUnitTest.java @@ -154,7 +154,7 @@ public class ShareDTOUnitTest { givenDTO.setAction(ShareAction.SUBSCRIPTION); givenDTO.setQuantity(3); givenDTO.setDocumentDate(LocalDate.parse("2019-04-22")); - givenDTO.setMembershipDocumentDate("2019-04-21"); // TODO: why is this not a LocalDate? + givenDTO.setMembershipDisplayReference("2019-04-21"); // TODO: why is this not a LocalDate? givenDTO.setValueDate(LocalDate.parse("2019-04-30")); givenDTO.setRemark("Some Remark"); return givenDTO; diff --git a/src/test/java/org/hostsharing/hsadminng/web/rest/CustomerResourceIntTest.java b/src/test/java/org/hostsharing/hsadminng/web/rest/CustomerResourceIntTest.java index 01d0fa92..e63024a2 100644 --- a/src/test/java/org/hostsharing/hsadminng/web/rest/CustomerResourceIntTest.java +++ b/src/test/java/org/hostsharing/hsadminng/web/rest/CustomerResourceIntTest.java @@ -9,6 +9,7 @@ import org.hostsharing.hsadminng.domain.enumeration.VatRegion; import org.hostsharing.hsadminng.repository.CustomerRepository; import org.hostsharing.hsadminng.service.CustomerQueryService; import org.hostsharing.hsadminng.service.CustomerService; +import org.hostsharing.hsadminng.service.accessfilter.Role; import org.hostsharing.hsadminng.service.dto.CustomerDTO; import org.hostsharing.hsadminng.service.mapper.CustomerMapper; import org.hostsharing.hsadminng.web.rest.errors.ExceptionTranslator; @@ -34,9 +35,12 @@ import java.util.List; import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.Matchers.hasItem; +import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenAuthenticatedUser; +import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenUserHavingRole; import static org.hostsharing.hsadminng.web.rest.TestUtil.createFormattingConversionService; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + /** * Test class for the CustomerResource REST controller. * @@ -133,6 +137,10 @@ public class CustomerResourceIntTest { @Before public void setup() { MockitoAnnotations.initMocks(this); + + givenAuthenticatedUser(); + givenUserHavingRole(Role.ADMIN); + final CustomerResource customerResource = new CustomerResource(customerService, customerQueryService); this.restCustomerMockMvc = MockMvcBuilders.standaloneSetup(customerResource) .setCustomArgumentResolvers(pageableArgumentResolver) @@ -144,7 +152,7 @@ public class CustomerResourceIntTest { /** * Create an entity for this test. - * + *

* This is a static method, as tests for other entities might also need it, * if they test an entity which requires the current entity. */ @@ -170,7 +178,7 @@ public class CustomerResourceIntTest { /** * Create another entity for tests. - * + *

* This is a static method, as tests for other entities might also need it, * if they test an entity which requires the current entity. */ @@ -372,22 +380,22 @@ public class CustomerResourceIntTest { .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) .andExpect(jsonPath("$.[*].id").value(hasItem(customer.getId().intValue()))) .andExpect(jsonPath("$.[*].reference").value(hasItem(DEFAULT_REFERENCE))) - .andExpect(jsonPath("$.[*].prefix").value(hasItem(DEFAULT_PREFIX.toString()))) - .andExpect(jsonPath("$.[*].name").value(hasItem(DEFAULT_NAME.toString()))) + .andExpect(jsonPath("$.[*].prefix").value(hasItem(DEFAULT_PREFIX))) + .andExpect(jsonPath("$.[*].name").value(hasItem(DEFAULT_NAME))) .andExpect(jsonPath("$.[*].kind").value(hasItem(DEFAULT_KIND.toString()))) .andExpect(jsonPath("$.[*].birthDate").value(hasItem(DEFAULT_BIRTH_DATE.toString()))) - .andExpect(jsonPath("$.[*].birthPlace").value(hasItem(DEFAULT_BIRTH_PLACE.toString()))) - .andExpect(jsonPath("$.[*].registrationCourt").value(hasItem(DEFAULT_REGISTRATION_COURT.toString()))) - .andExpect(jsonPath("$.[*].registrationNumber").value(hasItem(DEFAULT_REGISTRATION_NUMBER.toString()))) + .andExpect(jsonPath("$.[*].birthPlace").value(hasItem(DEFAULT_BIRTH_PLACE))) + .andExpect(jsonPath("$.[*].registrationCourt").value(hasItem(DEFAULT_REGISTRATION_COURT))) + .andExpect(jsonPath("$.[*].registrationNumber").value(hasItem(DEFAULT_REGISTRATION_NUMBER))) .andExpect(jsonPath("$.[*].vatRegion").value(hasItem(DEFAULT_VAT_REGION.toString()))) - .andExpect(jsonPath("$.[*].vatNumber").value(hasItem(DEFAULT_VAT_NUMBER.toString()))) - .andExpect(jsonPath("$.[*].contractualSalutation").value(hasItem(DEFAULT_CONTRACTUAL_SALUTATION.toString()))) - .andExpect(jsonPath("$.[*].contractualAddress").value(hasItem(DEFAULT_CONTRACTUAL_ADDRESS.toString()))) - .andExpect(jsonPath("$.[*].billingSalutation").value(hasItem(DEFAULT_BILLING_SALUTATION.toString()))) - .andExpect(jsonPath("$.[*].billingAddress").value(hasItem(DEFAULT_BILLING_ADDRESS.toString()))) - .andExpect(jsonPath("$.[*].remark").value(hasItem(DEFAULT_REMARK.toString()))); + .andExpect(jsonPath("$.[*].vatNumber").value(hasItem(DEFAULT_VAT_NUMBER))) + .andExpect(jsonPath("$.[*].contractualSalutation").value(hasItem(DEFAULT_CONTRACTUAL_SALUTATION))) + .andExpect(jsonPath("$.[*].contractualAddress").value(hasItem(DEFAULT_CONTRACTUAL_ADDRESS))) + .andExpect(jsonPath("$.[*].billingSalutation").value(hasItem(DEFAULT_BILLING_SALUTATION))) + .andExpect(jsonPath("$.[*].billingAddress").value(hasItem(DEFAULT_BILLING_ADDRESS))) + .andExpect(jsonPath("$.[*].remark").value(hasItem(DEFAULT_REMARK))); } - + @Test @Transactional public void getCustomer() throws Exception { @@ -1162,8 +1170,8 @@ public class CustomerResourceIntTest { // Disconnect from session so that the updates on updatedCustomer are not directly saved in db em.detach(updatedCustomer); updatedCustomer - .reference(UPDATED_REFERENCE) - .prefix(UPDATED_PREFIX) + .reference(null) + .prefix(null) .name(UPDATED_NAME) .kind(UPDATED_KIND) .birthDate(UPDATED_BIRTH_DATE) @@ -1188,8 +1196,8 @@ public class CustomerResourceIntTest { List customerList = customerRepository.findAll(); assertThat(customerList).hasSize(databaseSizeBeforeUpdate); Customer testCustomer = customerList.get(customerList.size() - 1); - assertThat(testCustomer.getReference()).isEqualTo(UPDATED_REFERENCE); - assertThat(testCustomer.getPrefix()).isEqualTo(UPDATED_PREFIX); + assertThat(testCustomer.getReference()).isEqualTo(DEFAULT_REFERENCE); + assertThat(testCustomer.getPrefix()).isEqualTo(DEFAULT_PREFIX); assertThat(testCustomer.getName()).isEqualTo(UPDATED_NAME); assertThat(testCustomer.getKind()).isEqualTo(UPDATED_KIND); assertThat(testCustomer.getBirthDate()).isEqualTo(UPDATED_BIRTH_DATE);