generalized AccessMappingsUnitTestBase
This commit is contained in:
parent
0257c83fa5
commit
2cd92d4e2c
@ -1,14 +1,19 @@
|
||||
package org.hostsharing.hsadminng.service.dto;
|
||||
|
||||
import org.apache.commons.lang3.RandomUtils;
|
||||
import org.hostsharing.hsadminng.service.accessfilter.AccessFor;
|
||||
import org.hostsharing.hsadminng.service.accessfilter.Role;
|
||||
import org.hostsharing.hsadminng.service.util.ReflectionUtil;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.removeEnd;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
@ -16,28 +21,71 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* DTOs which implement AccessMapping are more like a DSL,
|
||||
* this base class should be used to enforce its required structure.
|
||||
*/
|
||||
public abstract class AccessMappingsUnitTestBase {
|
||||
public abstract class AccessMappingsUnitTestBase<D> {
|
||||
|
||||
protected AccessRightsMatcher initAccesFor(final Class<AssetDTO> dtoClass, final Role role) {
|
||||
@Test
|
||||
public void shouldConvertToString() {
|
||||
final D sampleDto = createSampleDto(1234L);
|
||||
final String dtoAsString = dtoToString(sampleDto);
|
||||
assertThat(sampleDto.toString()).isEqualTo(dtoAsString);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("all")
|
||||
public void shouldImplementEqualsJustUsingClassAndId() {
|
||||
final D dto = createSampleDto(1234L);
|
||||
assertThat(dto.equals(dto)).isTrue();
|
||||
|
||||
final D dtoWithSameId = createRandomDto(1234L);
|
||||
assertThat(dto.equals(dtoWithSameId)).isTrue();
|
||||
|
||||
final D dtoWithAnotherId = createRandomDto(RandomUtils.nextLong(2000, 9999));
|
||||
assertThat(dtoWithAnotherId.equals(dtoWithSameId)).isFalse();
|
||||
|
||||
final D dtoWithoutId = createRandomDto(null);
|
||||
assertThat(dto.equals(dtoWithoutId)).isFalse();
|
||||
assertThat(dtoWithoutId.equals(dto)).isFalse();
|
||||
|
||||
assertThat(dto.equals(null)).isFalse();
|
||||
assertThat(dto.equals("")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldImplementHashCodeJustUsingClassAndId() {
|
||||
final long randomId = RandomUtils.nextLong();
|
||||
final D dto = createSampleDto(randomId);
|
||||
assertThat(dto.hashCode()).isEqualTo(Objects.hashCode(randomId));
|
||||
|
||||
final D dtoWithoutId = createRandomDto(null);
|
||||
assertThat(dtoWithoutId.hashCode()).isEqualTo(Objects.hashCode(null));
|
||||
}
|
||||
|
||||
protected abstract D createSampleDto(final Long id);
|
||||
|
||||
protected abstract D createRandomDto(final Long id);
|
||||
|
||||
protected AccessRightsMatcher initAccessFor(final Class<D> dtoClass, final Role role) {
|
||||
return new AccessRightsMatcher(dtoClass, role, AccessFor::init);
|
||||
}
|
||||
|
||||
protected AccessRightsMatcher updateAccesFor(final Class<AssetDTO> dtoClass, final Role role) {
|
||||
protected AccessRightsMatcher updateAccessFor(final Class<D> dtoClass, final Role role) {
|
||||
return new AccessRightsMatcher(dtoClass, role, AccessFor::update);
|
||||
}
|
||||
|
||||
protected AccessRightsMatcher readAccesFor(final Class<AssetDTO> dtoClass, final Role role) {
|
||||
protected AccessRightsMatcher readAccessFor(final Class<D> dtoClass, final Role role) {
|
||||
return new AccessRightsMatcher(dtoClass, role, AccessFor::read);
|
||||
}
|
||||
|
||||
// This class should have the same generics as the outer class, but then the
|
||||
// method references (AccessFor::*) can't be resolved anymore by the Java compiler.
|
||||
protected static class AccessRightsMatcher {
|
||||
private final Class<AssetDTO> dtoClass;
|
||||
private final Object dtoClass;
|
||||
private final Role role;
|
||||
|
||||
private final String[] namesOfFieldsWithAccessForAnnotation;
|
||||
private final String[] namesOfAccessibleFields;
|
||||
|
||||
AccessRightsMatcher(final Class<AssetDTO> dtoClass, final Role role, final Function<AccessFor, Role[]> access) {
|
||||
AccessRightsMatcher(final Class dtoClass, final Role role, final Function<AccessFor, Role[]> access) {
|
||||
this.dtoClass = dtoClass;
|
||||
this.role = role;
|
||||
|
||||
@ -61,7 +109,7 @@ public abstract class AccessMappingsUnitTestBase {
|
||||
}
|
||||
|
||||
|
||||
private static Set<Field> determineFieldsWithAccessForAnnotation(final Class<AssetDTO> dtoClass) {
|
||||
private static Set<Field> determineFieldsWithAccessForAnnotation(final Class<?> dtoClass) {
|
||||
|
||||
final Set<Field> fieldsWithAccessForAnnotation = new HashSet<>();
|
||||
|
||||
@ -83,4 +131,47 @@ public abstract class AccessMappingsUnitTestBase {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private String dtoToString(final D dto) {
|
||||
final StringBuilder fieldValues = new StringBuilder();
|
||||
boolean firstField = true;
|
||||
for (Field field : dto.getClass().getDeclaredFields()) {
|
||||
if (field.isAnnotationPresent(AccessFor.class)) {
|
||||
firstField = appendCommaOptionally(fieldValues, firstField);
|
||||
appendFieldName(fieldValues, field);
|
||||
appendFieldValue(dto, fieldValues, field);
|
||||
}
|
||||
}
|
||||
return dto.getClass().getSimpleName() + "{" + fieldValues + "}";
|
||||
}
|
||||
|
||||
private void appendFieldValue(final D dto, final StringBuilder fieldValues, final Field field) {
|
||||
final Object value = ReflectionUtil.getValue(dto, field);
|
||||
final boolean inQuotes = isJHipsterToStringUsingQuotes(field);
|
||||
if (inQuotes) {
|
||||
fieldValues.append("'");
|
||||
}
|
||||
fieldValues.append(value);
|
||||
if (inQuotes) {
|
||||
fieldValues.append("'");
|
||||
}
|
||||
}
|
||||
|
||||
private void appendFieldName(final StringBuilder fieldValues, final Field field) {
|
||||
fieldValues.append(removeEnd(field.getName(), "Id"));
|
||||
fieldValues.append("=");
|
||||
}
|
||||
|
||||
private boolean appendCommaOptionally(final StringBuilder fieldValues, boolean firstField) {
|
||||
if (firstField) {
|
||||
firstField = false;
|
||||
} else {
|
||||
fieldValues.append(", ");
|
||||
}
|
||||
return firstField;
|
||||
}
|
||||
|
||||
private boolean isJHipsterToStringUsingQuotes(final Field field) {
|
||||
return !Number.class.isAssignableFrom(field.getType()) && !Boolean.class.isAssignableFrom(field.getType());
|
||||
}
|
||||
}
|
||||
|
@ -9,82 +9,59 @@ import org.junit.Test;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class AssetDTOUnitTest extends AccessMappingsUnitTestBase {
|
||||
public class AssetDTOUnitTest extends AccessMappingsUnitTestBase<AssetDTO> {
|
||||
|
||||
@Test
|
||||
public void shouldHaveProperAccessForAdmin() {
|
||||
initAccesFor(AssetDTO.class, Role.ADMIN).shouldBeExactlyFor(
|
||||
initAccessFor(AssetDTO.class, Role.ADMIN).shouldBeExactlyFor(
|
||||
"membershipId", "documentDate", "amount", "action", "valueDate", "remark");
|
||||
updateAccesFor(AssetDTO.class, Role.ADMIN).shouldBeExactlyFor("remark");
|
||||
readAccesFor(AssetDTO.class, Role.ADMIN).shouldBeForAllFields();
|
||||
updateAccessFor(AssetDTO.class, Role.ADMIN).shouldBeExactlyFor("remark");
|
||||
readAccessFor(AssetDTO.class, Role.ADMIN).shouldBeForAllFields();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHaveProperAccessForContractualContact() {
|
||||
initAccesFor(AssetDTO.class, Role.CONTRACTUAL_CONTACT).shouldBeForNothing();
|
||||
updateAccesFor(AssetDTO.class, Role.CONTRACTUAL_CONTACT).shouldBeForNothing();
|
||||
readAccesFor(AssetDTO.class, Role.CONTRACTUAL_CONTACT).shouldBeExactlyFor(
|
||||
initAccessFor(AssetDTO.class, Role.CONTRACTUAL_CONTACT).shouldBeForNothing();
|
||||
updateAccessFor(AssetDTO.class, Role.CONTRACTUAL_CONTACT).shouldBeForNothing();
|
||||
readAccessFor(AssetDTO.class, Role.CONTRACTUAL_CONTACT).shouldBeExactlyFor(
|
||||
"id", "membershipId", "documentDate", "amount", "action", "valueDate", "membershipDisplayLabel");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHaveNoAccessForTechnicalContact() {
|
||||
initAccesFor(AssetDTO.class, Role.TECHNICAL_CONTACT).shouldBeForNothing();
|
||||
updateAccesFor(AssetDTO.class, Role.TECHNICAL_CONTACT).shouldBeForNothing();
|
||||
readAccesFor(AssetDTO.class, Role.TECHNICAL_CONTACT).shouldBeForNothing();
|
||||
initAccessFor(AssetDTO.class, Role.TECHNICAL_CONTACT).shouldBeForNothing();
|
||||
updateAccessFor(AssetDTO.class, Role.TECHNICAL_CONTACT).shouldBeForNothing();
|
||||
readAccessFor(AssetDTO.class, Role.TECHNICAL_CONTACT).shouldBeForNothing();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHaveNoAccessForNormalUsersWithinCustomerRealm() {
|
||||
initAccesFor(AssetDTO.class, Role.ANY_CUSTOMER_USER).shouldBeForNothing();
|
||||
updateAccesFor(AssetDTO.class, Role.ANY_CUSTOMER_USER).shouldBeForNothing();
|
||||
readAccesFor(AssetDTO.class, Role.ANY_CUSTOMER_USER).shouldBeForNothing();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldConvertToString() {
|
||||
final AssetDTO dto = createDto(1234L);
|
||||
assertThat(dto.toString()).isEqualTo("AssetDTO{id=1234, documentDate='2000-12-07', valueDate='2000-12-18', action='PAYMENT', amount=512.01, remark='Some Remark', membership=888, membershipDisplayLabel='Some Membership'}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldImplementEqualsJustUsingClassAndId() {
|
||||
final AssetDTO dto = createDto(1234L);
|
||||
assertThat(dto.equals(dto)).isTrue();
|
||||
|
||||
final AssetDTO dtoWithSameId = createRandomDto(1234L);
|
||||
assertThat(dto.equals(dtoWithSameId)).isTrue();
|
||||
|
||||
final AssetDTO dtoWithAnotherId = createRandomDto(RandomUtils.nextLong(2000, 9999));
|
||||
assertThat(dtoWithAnotherId.equals(dtoWithSameId)).isFalse();
|
||||
|
||||
final AssetDTO dtoWithoutId = createRandomDto(null);
|
||||
assertThat(dto.equals(dtoWithoutId)).isFalse();
|
||||
assertThat(dtoWithoutId.equals(dto)).isFalse();
|
||||
|
||||
assertThat(dto.equals(null)).isFalse();
|
||||
assertThat(dto.equals("")).isFalse();
|
||||
initAccessFor(AssetDTO.class, Role.ANY_CUSTOMER_USER).shouldBeForNothing();
|
||||
updateAccessFor(AssetDTO.class, Role.ANY_CUSTOMER_USER).shouldBeForNothing();
|
||||
readAccessFor(AssetDTO.class, Role.ANY_CUSTOMER_USER).shouldBeForNothing();
|
||||
}
|
||||
|
||||
// --- only test fixture below ---
|
||||
|
||||
private AssetDTO createDto(final Long id) {
|
||||
@Override
|
||||
public AssetDTO createSampleDto(final Long id) {
|
||||
final AssetDTO dto = new AssetDTO();
|
||||
dto.setId(id);
|
||||
dto.setDocumentDate(LocalDate.parse("2000-12-07"));
|
||||
dto.setAmount(new BigDecimal("512.01"));
|
||||
dto.setAction(AssetAction.PAYMENT);
|
||||
dto.setRemark("Some Remark");
|
||||
dto.setRemark(null);
|
||||
dto.setValueDate(LocalDate.parse("2000-12-18"));
|
||||
dto.setMembershipId(888L);
|
||||
dto.setMembershipId(null);
|
||||
dto.setMembershipDisplayLabel("Some Membership");
|
||||
return dto;
|
||||
}
|
||||
|
||||
|
||||
private AssetDTO createRandomDto(final Long id) {
|
||||
@Override
|
||||
public AssetDTO createRandomDto(final Long id) {
|
||||
final AssetDTO dto = new AssetDTO();
|
||||
dto.setId(id);
|
||||
final LocalDate randomDate = LocalDate.parse("2000-12-07").plusDays(RandomUtils.nextInt(1, 999));
|
||||
@ -97,5 +74,4 @@ public class AssetDTOUnitTest extends AccessMappingsUnitTestBase {
|
||||
dto.setMembershipDisplayLabel(RandomStringUtils.randomAlphabetic(20));
|
||||
return dto;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user