diff --git a/src/main/java/org/hostsharing/hsadminng/domain/Share.java b/src/main/java/org/hostsharing/hsadminng/domain/Share.java index 76923dd2..4c3c8ab1 100644 --- a/src/main/java/org/hostsharing/hsadminng/domain/Share.java +++ b/src/main/java/org/hostsharing/hsadminng/domain/Share.java @@ -58,6 +58,11 @@ public class Share implements Serializable { return id; } + public Share id(final Long id) { + this.id = id; + return this; + } + public void setId(Long id) { this.id = id; } 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 143497ce..f80e0486 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/dto/AssetDTO.java +++ b/src/main/java/org/hostsharing/hsadminng/service/dto/AssetDTO.java @@ -150,17 +150,17 @@ public class AssetDTO implements Serializable, AccessMappings { } @JsonComponent - public static class AssetJsonSerializer extends JsonSerializerWithAccessFilter { + public static class JsonSerializer extends JsonSerializerWithAccessFilter { - public AssetJsonSerializer(final ApplicationContext ctx) { + public JsonSerializer(final ApplicationContext ctx) { super(ctx); } } @JsonComponent - public static class AssetJsonDeserializer extends JsonDeserializerWithAccessFilter { + public static class JsonDeserializer extends JsonDeserializerWithAccessFilter { - public AssetJsonDeserializer(final ApplicationContext ctx) { + public JsonDeserializer(final ApplicationContext ctx) { super(ctx); } } 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 8bd1daa4..7889d067 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/dto/ShareDTO.java +++ b/src/main/java/org/hostsharing/hsadminng/service/dto/ShareDTO.java @@ -3,10 +3,9 @@ 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 org.hostsharing.hsadminng.service.accessfilter.*; +import org.springframework.boot.jackson.JsonComponent; +import org.springframework.context.ApplicationContext; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; @@ -17,7 +16,7 @@ import java.util.Objects; /** * A DTO for the Share entity. */ -public class ShareDTO implements Serializable { +public class ShareDTO implements Serializable, AccessMappings { @SelfId(resolver = ShareService.class) @AccessFor(read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT}) @@ -40,14 +39,14 @@ public class ShareDTO implements Serializable { private Integer quantity; @Size(max = 160) - @AccessFor(init = Role.ADMIN, read = Role.SUPPORTER) + @AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = Role.SUPPORTER) private String remark; @ParentId(resolver = MembershipService.class) @AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT}) private Long membershipId; - @AccessFor(read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT}) + @AccessFor(update = Role.IGNORED, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT}) private String membershipDisplayLabel; public Long getId() { @@ -145,7 +144,23 @@ public class ShareDTO implements Serializable { ", quantity=" + getQuantity() + ", remark='" + getRemark() + "'" + ", membership=" + getMembershipId() + - ", membership='" + getMembershipDisplayLabel() + "'" + + ", membershipDisplayLabel='" + getMembershipDisplayLabel() + "'" + "}"; } + + @JsonComponent + public static class JsonSerializer extends JsonSerializerWithAccessFilter { + + public JsonSerializer(final ApplicationContext ctx) { + super(ctx); + } + } + + @JsonComponent + public static class JsonDeserializer extends JsonDeserializerWithAccessFilter { + + public JsonDeserializer(final ApplicationContext ctx) { + super(ctx); + } + } } diff --git a/src/main/java/org/hostsharing/hsadminng/service/util/RandomUtil.java b/src/main/java/org/hostsharing/hsadminng/service/util/RandomUtil.java index d69806f7..122a5cd1 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/util/RandomUtil.java +++ b/src/main/java/org/hostsharing/hsadminng/service/util/RandomUtil.java @@ -1,9 +1,10 @@ package org.hostsharing.hsadminng.service.util; import org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.RandomUtils; /** - * Utility class for generating random Strings. + * Utility class for generating random Values. */ public final class RandomUtil { @@ -38,4 +39,14 @@ public final class RandomUtil { public static String generateResetKey() { return RandomStringUtils.randomNumeric(DEF_COUNT); } + + /** + * Generate a random enum value for a given enum type. + * + * @return the generated enum value + */ + public static > E generateEnumValue(final Class enumType) { + final E[] enumValues = enumType.getEnumConstants(); + return enumValues[RandomUtils.nextInt(0, enumValues.length-1)]; + } } diff --git a/src/test/java/org/hostsharing/hsadminng/service/dto/AccessMappingsUnitTestBase.java b/src/test/java/org/hostsharing/hsadminng/service/dto/AccessMappingsUnitTestBase.java index 3ee82187..bcc0b169 100644 --- a/src/test/java/org/hostsharing/hsadminng/service/dto/AccessMappingsUnitTestBase.java +++ b/src/test/java/org/hostsharing/hsadminng/service/dto/AccessMappingsUnitTestBase.java @@ -1,12 +1,13 @@ 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.accessfilter.*; import org.hostsharing.hsadminng.service.util.ReflectionUtil; import org.junit.Test; +import org.springframework.boot.jackson.JsonComponent; import java.lang.reflect.Field; +import java.lang.reflect.Modifier; import java.util.HashSet; import java.util.Objects; import java.util.Set; @@ -15,6 +16,7 @@ import java.util.stream.Collectors; import static org.apache.commons.lang3.StringUtils.removeEnd; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.fail; /** * Usually base classes for unit tests are not a good idea, but because @@ -60,6 +62,23 @@ public abstract class AccessMappingsUnitTestBase { assertThat(dtoWithoutId.hashCode()).isEqualTo(Objects.hashCode(null)); } + @Test + public void shouldImplementAccessMappings() { + assertThat(getDtoClass().getInterfaces()).as("must implement " + AccessMappings.class).contains(AccessMappings.class); + } + + @Test + public void shouldImplementSerializer() { + shouldImplementJsonComponent(JsonSerializerWithAccessFilter.class); + } + + @Test + public void shouldImplementDeserializer() { + shouldImplementJsonComponent(JsonDeserializerWithAccessFilter.class); + } + + // --- only test fixture below --- + protected abstract D createSampleDto(final Long id); protected abstract D createRandomDto(final Long id); @@ -174,4 +193,26 @@ public abstract class AccessMappingsUnitTestBase { private boolean isJHipsterToStringUsingQuotes(final Field field) { return !Number.class.isAssignableFrom(field.getType()) && !Boolean.class.isAssignableFrom(field.getType()); } + + private void shouldImplementJsonComponent(final Class expectedSuperclass) { + final Class dtoClass = getDtoClass(); + for (Class declaredClass: dtoClass.getDeclaredClasses()) { + if (expectedSuperclass.isAssignableFrom(declaredClass) ) { + assertThat( declaredClass.isAnnotationPresent(JsonComponent.class) ) + .as(declaredClass + " requires @" + JsonComponent.class.getSimpleName()).isTrue(); + assertThat( ReflectionUtil.determineGenericClassParameter(declaredClass, expectedSuperclass, 0)) + .as(declaredClass + " must resolve generic parameter of " + expectedSuperclass + " to type of DTO").isEqualTo(dtoClass); + assertThat(Modifier.isPublic(declaredClass.getModifiers()) ).as(declaredClass + " must be public").isTrue(); + assertThat(Modifier.isStatic(declaredClass.getModifiers()) ).as(declaredClass + " must be static").isTrue(); + assertThat(Modifier.isFinal(declaredClass.getModifiers()) ).as(declaredClass + " must not be final").isFalse(); + assertThat(Modifier.isAbstract(declaredClass.getModifiers()) ).as(declaredClass + " must not be abstract").isFalse(); + return; + } + } + fail("no " + expectedSuperclass + " defined for " + dtoClass); + } + + private Class getDtoClass() { + return ReflectionUtil.determineGenericClassParameter(this.getClass(), AccessMappingsUnitTestBase.class, 0); + } } diff --git a/src/test/java/org/hostsharing/hsadminng/service/dto/AssetDTOIntTest.java b/src/test/java/org/hostsharing/hsadminng/service/dto/AssetDTOIntTest.java index 49f4f390..b0c1f6f9 100644 --- a/src/test/java/org/hostsharing/hsadminng/service/dto/AssetDTOIntTest.java +++ b/src/test/java/org/hostsharing/hsadminng/service/dto/AssetDTOIntTest.java @@ -50,8 +50,8 @@ import static org.mockito.BDDMockito.given; CustomerMapperImpl.class, MembershipMapperImpl.class, AssetMapperImpl.class, - AssetDTO.AssetJsonSerializer.class, - AssetDTO.AssetJsonDeserializer.class + AssetDTO.JsonSerializer.class, + AssetDTO.JsonDeserializer.class }) @RunWith(SpringRunner.class) public class AssetDTOIntTest { diff --git a/src/test/java/org/hostsharing/hsadminng/service/dto/AssetDTOUnitTest.java b/src/test/java/org/hostsharing/hsadminng/service/dto/AssetDTOUnitTest.java index 06d7604c..31d7912a 100644 --- a/src/test/java/org/hostsharing/hsadminng/service/dto/AssetDTOUnitTest.java +++ b/src/test/java/org/hostsharing/hsadminng/service/dto/AssetDTOUnitTest.java @@ -4,6 +4,7 @@ import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.RandomUtils; import org.hostsharing.hsadminng.domain.enumeration.AssetAction; import org.hostsharing.hsadminng.service.accessfilter.Role; +import org.hostsharing.hsadminng.service.util.RandomUtil; import org.junit.Test; import java.math.BigDecimal; @@ -59,19 +60,18 @@ public class AssetDTOUnitTest extends AccessMappingsUnitTestBase { return dto; } - @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)); dto.setDocumentDate(randomDate); - dto.setAmount(new BigDecimal("512.01")); - dto.setAction(AssetAction.PAYMENT); - dto.setRemark("Some Remark"); + dto.setAmount(new BigDecimal(RandomUtils.nextDouble())); + dto.setAction(RandomUtil.generateEnumValue(AssetAction.class)); + dto.setRemark(RandomStringUtils.randomAlphanumeric(20)); dto.setValueDate(randomDate.plusDays(RandomUtils.nextInt(1, 99))); dto.setMembershipId(RandomUtils.nextLong()); - dto.setMembershipDisplayLabel(RandomStringUtils.randomAlphabetic(20)); + dto.setMembershipDisplayLabel("The Membership #" + dto.getMembershipId()); return dto; } } diff --git a/src/test/java/org/hostsharing/hsadminng/service/dto/ShareDTOIntTest.java b/src/test/java/org/hostsharing/hsadminng/service/dto/ShareDTOIntTest.java new file mode 100644 index 00000000..9f350529 --- /dev/null +++ b/src/test/java/org/hostsharing/hsadminng/service/dto/ShareDTOIntTest.java @@ -0,0 +1,210 @@ +package org.hostsharing.hsadminng.service.dto; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.commons.lang3.RandomUtils; +import org.hostsharing.hsadminng.domain.Customer; +import org.hostsharing.hsadminng.domain.Membership; +import org.hostsharing.hsadminng.domain.Share; +import org.hostsharing.hsadminng.domain.enumeration.ShareAction; +import org.hostsharing.hsadminng.repository.CustomerRepository; +import org.hostsharing.hsadminng.repository.MembershipRepository; +import org.hostsharing.hsadminng.repository.ShareRepository; +import org.hostsharing.hsadminng.service.MembershipValidator; +import org.hostsharing.hsadminng.service.ShareService; +import org.hostsharing.hsadminng.service.ShareValidator; +import org.hostsharing.hsadminng.service.accessfilter.JSonBuilder; +import org.hostsharing.hsadminng.service.accessfilter.Role; +import org.hostsharing.hsadminng.service.mapper.CustomerMapperImpl; +import org.hostsharing.hsadminng.service.mapper.MembershipMapperImpl; +import org.hostsharing.hsadminng.service.mapper.ShareMapper; +import org.hostsharing.hsadminng.service.mapper.ShareMapperImpl; +import org.hostsharing.hsadminng.web.rest.errors.BadRequestAlertException; +import org.junit.Before; +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 javax.persistence.EntityManager; +import java.io.IOException; +import java.time.LocalDate; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.catchThrowable; +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, + MembershipMapperImpl.class, + ShareMapperImpl.class, + ShareDTO.JsonSerializer.class, + ShareDTO.JsonDeserializer.class +}) +@RunWith(SpringRunner.class) +public class ShareDTOIntTest { + + private static final Long SOME_CUSTOMER_ID = RandomUtils.nextLong(100, 199); + private static final Integer SOME_CUSTOMER_REFERENCE = 10001; + private static final String SOME_CUSTOMER_PREFIX = "abc"; + private static final String SOME_CUSTOMER_NAME = "Some Customer Name"; + private static final Customer SOME_CUSTOMER = new Customer().id(SOME_CUSTOMER_ID) + .reference(SOME_CUSTOMER_REFERENCE).prefix(SOME_CUSTOMER_PREFIX).name(SOME_CUSTOMER_NAME); + + private static final Long SOME_MEMBERSHIP_ID = RandomUtils.nextLong(200, 299); + private static final LocalDate SOME_MEMBER_FROM_DATE = LocalDate.parse("2000-12-06"); + private static final Membership SOME_MEMBERSHIP = new Membership().id(SOME_MEMBERSHIP_ID) + .customer(SOME_CUSTOMER).memberFromDate(SOME_MEMBER_FROM_DATE); + private static final String SOME_MEMBERSHIP_DISPLAY_LABEL = "Some Customer Name [10001:abc] 2000-12-06 - ..."; + + private static final Long SOME_SHARE_ID = RandomUtils.nextLong(300, 399); + private static final Share SOME_SHARE = new Share().id(SOME_SHARE_ID).membership(SOME_MEMBERSHIP); + + @Rule + public MockitoRule mockito = MockitoJUnit.rule(); + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private ShareMapper shareMapper; + + @MockBean + private ShareRepository shareRepository; + + @MockBean + private ShareValidator shareValidator; + + @MockBean + private CustomerRepository customerRepository; + + @MockBean + private MembershipRepository membershipRepository; + + @MockBean + private MembershipValidator membershipValidator; + + @MockBean + private ShareService shareService; + + @MockBean + private EntityManager em; + + @Before + public void init() { + given(customerRepository.findById(SOME_CUSTOMER_ID)).willReturn(Optional.of(SOME_CUSTOMER)); + given(membershipRepository.findById(SOME_MEMBERSHIP_ID)).willReturn(Optional.of(SOME_MEMBERSHIP)); + given(shareRepository.findById(SOME_SHARE_ID)).willReturn((Optional.of(SOME_SHARE))); + } + + @Test + public void shouldSerializePartiallyForFinancialCustomerContact() throws JsonProcessingException { + + // given + givenAuthenticatedUser(); + givenUserHavingRole(CustomerDTO.class, SOME_CUSTOMER_ID, Role.FINANCIAL_CONTACT); + final ShareDTO given = createSomeShareDTO(SOME_SHARE_ID); + + // when + final String actual = objectMapper.writeValueAsString(given); + + // then + given.setRemark(null); + assertEquals(createExpectedJSon(given), actual); + } + + @Test + public void shouldSerializeCompletelyForSupporter() throws JsonProcessingException { + + // given + givenAuthenticatedUser(); + givenUserHavingRole(Role.SUPPORTER); + final ShareDTO given = createSomeShareDTO(SOME_SHARE_ID); + + // when + final String actual = objectMapper.writeValueAsString(given); + + // then + assertEquals(createExpectedJSon(given), actual); + } + + @Test + public void shouldNotDeserializeForContractualCustomerContact() { + // given + givenAuthenticatedUser(); + givenUserHavingRole(CustomerDTO.class, SOME_CUSTOMER_ID, Role.CONTRACTUAL_CONTACT); + final String json = new JSonBuilder() + .withFieldValue("id", SOME_SHARE_ID) + .withFieldValue("remark", "Updated Remark") + .toString(); + + // when + final Throwable actual = catchThrowable(() -> objectMapper.readValue(json, ShareDTO.class)); + + // then + assertThat(actual).isInstanceOfSatisfying(BadRequestAlertException.class, bre -> + assertThat(bre.getMessage()).isEqualTo("Update of field ShareDTO.remark prohibited for current user role CONTRACTUAL_CONTACT") + ); + } + + @Test + public void shouldDeserializeForAdminIfRemarkIsChanged() throws IOException { + // given + givenAuthenticatedUser(); + givenUserHavingRole(Role.ADMIN); + final String json = new JSonBuilder() + .withFieldValue("id", SOME_SHARE_ID) + .withFieldValue("remark", "Updated Remark") + .toString(); + + // when + final ShareDTO actual = objectMapper.readValue(json, ShareDTO.class); + + // then + final ShareDTO expected = new ShareDTO(); + expected.setId(SOME_SHARE_ID); + expected.setMembershipId(SOME_MEMBERSHIP_ID); + expected.setRemark("Updated Remark"); + expected.setMembershipDisplayLabel(SOME_MEMBERSHIP_DISPLAY_LABEL); + assertThat(actual).isEqualToIgnoringGivenFields(expected, "displayLabel"); + } + + // --- only test fixture below --- + + private String createExpectedJSon(ShareDTO dto) { + return new JSonBuilder() + .withFieldValueIfPresent("id", dto.getId()) + .withFieldValueIfPresent("documentDate", dto.getDocumentDate().toString()) + .withFieldValueIfPresent("valueDate", dto.getValueDate().toString()) + .withFieldValueIfPresent("action", dto.getAction().name()) + .withFieldValueIfPresent("quantity", dto.getQuantity()) + .withFieldValueIfPresent("remark", dto.getRemark()) + .withFieldValueIfPresent("membershipId", dto.getMembershipId()) + .withFieldValue("membershipDisplayLabel", dto.getMembershipDisplayLabel()) + .toString(); + } + + private ShareDTO createSomeShareDTO(final long id) { + final ShareDTO given = new ShareDTO(); + given.setId(id); + given.setAction(ShareAction.SUBSCRIPTION); + given.setQuantity(16); + given.setDocumentDate(LocalDate.parse("2019-04-27")); + given.setValueDate(LocalDate.parse("2019-04-28")); + given.setMembershipId(SOME_MEMBERSHIP_ID); + given.setRemark("Some Remark"); + given.setMembershipDisplayLabel("Display Label for Membership #" + SOME_MEMBERSHIP_ID); + return given; + } +} 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 2652f139..73a442ae 100644 --- a/src/test/java/org/hostsharing/hsadminng/service/dto/ShareDTOUnitTest.java +++ b/src/test/java/org/hostsharing/hsadminng/service/dto/ShareDTOUnitTest.java @@ -1,162 +1,75 @@ package org.hostsharing.hsadminng.service.dto; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -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.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.RandomUtils; import org.hostsharing.hsadminng.domain.enumeration.ShareAction; -import org.hostsharing.hsadminng.service.CustomerService; -import org.hostsharing.hsadminng.service.MembershipService; -import org.hostsharing.hsadminng.service.accessfilter.JSonDeserializationWithAccessFilter; -import org.hostsharing.hsadminng.service.accessfilter.JSonSerializationWithAccessFilter; import org.hostsharing.hsadminng.service.accessfilter.Role; -import org.hostsharing.hsadminng.web.rest.errors.BadRequestAlertException; -import org.junit.Before; -import org.junit.Rule; +import org.hostsharing.hsadminng.service.util.RandomUtil; 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.time.LocalDate; -import java.util.Optional; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.catchThrowable; -import static org.hostsharing.hsadminng.service.accessfilter.JSonBuilder.asJSon; -import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenAuthenticatedUser; -import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenUserHavingRole; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; +public class ShareDTOUnitTest extends AccessMappingsUnitTestBase { -public class ShareDTOUnitTest { - - private static final long SOME_MEMBERSHIP_ID = 12345L; - private static final long SOME_CUSTOMER_ID = 1234L; - - @Rule - public MockitoRule mockitoRule = MockitoJUnit.rule(); - - @Mock - private ApplicationContext ctx; - - @Mock - private AutowireCapableBeanFactory autowireCapableBeanFactory; - - @Mock - private JsonParser jsonParser; - - @Mock - private JsonGenerator jsonGenerator; - - @Mock - private ObjectCodec codec; - - @Mock - private TreeNode treeNode; - - @Mock - private CustomerService customerService; - - @Mock - private MembershipService membershipService; - - @Before - public void init() { - given(jsonParser.getCodec()).willReturn(codec); - - given(ctx.getAutowireCapableBeanFactory()).willReturn(autowireCapableBeanFactory); - given(autowireCapableBeanFactory.createBean(CustomerService.class)).willReturn(customerService); - given(autowireCapableBeanFactory.createBean(MembershipService.class)).willReturn(membershipService); - - given(customerService.findOne(SOME_CUSTOMER_ID)).willReturn(Optional.of(new CustomerDTO())); - given(membershipService.findOne(SOME_MEMBERSHIP_ID)).willReturn(Optional.of(new MembershipDTO().with(dto -> dto.setCustomerId(SOME_CUSTOMER_ID)))); + @Test + public void shouldHaveProperAccessForAdmin() { + initAccessFor(ShareDTO.class, Role.ADMIN).shouldBeExactlyFor( + "membershipId", "documentDate", "quantity", "action", "valueDate", "remark"); + updateAccessFor(ShareDTO.class, Role.ADMIN).shouldBeExactlyFor("remark"); + readAccessFor(ShareDTO.class, Role.ADMIN).shouldBeForAllFields(); } @Test - public void adminShouldHaveRightToCreate() throws IOException { - givenAuthenticatedUser(); - givenUserHavingRole(null, null, Role.ADMIN); - givenJSonTree(asJSon(ImmutablePair.of("membershipId", SOME_MEMBERSHIP_ID))); - - // when - final ShareDTO actualDto = new JSonDeserializationWithAccessFilter<>(ctx, jsonParser, null, ShareDTO.class).deserialize(); - - // then - assertThat(actualDto.getMembershipId()).isEqualTo(SOME_MEMBERSHIP_ID); + public void shouldHaveProperAccessForContractualContact() { + initAccessFor(ShareDTO.class, Role.CONTRACTUAL_CONTACT).shouldBeForNothing(); + updateAccessFor(ShareDTO.class, Role.CONTRACTUAL_CONTACT).shouldBeForNothing(); + readAccessFor(ShareDTO.class, Role.CONTRACTUAL_CONTACT).shouldBeExactlyFor( + "id", "membershipId", "documentDate", "quantity", "action", "valueDate", "membershipDisplayLabel"); } @Test - public void contractualContactShouldNotHaveRightToCreate() throws IOException { - givenAuthenticatedUser(); - givenUserHavingRole(CustomerDTO.class, SOME_CUSTOMER_ID, Role.CONTRACTUAL_CONTACT); - givenJSonTree(asJSon(ImmutablePair.of("membershipId", ShareDTOUnitTest.SOME_MEMBERSHIP_ID))); - - // when - Throwable exception = catchThrowable(() -> new JSonDeserializationWithAccessFilter<>(ctx, jsonParser, null, ShareDTO.class).deserialize()); - - // then - assertThat(exception).isInstanceOfSatisfying(BadRequestAlertException.class, badRequestAlertException -> { - assertThat(badRequestAlertException.getParam()).isEqualTo("ShareDTO.membershipId"); - assertThat(badRequestAlertException.getErrorKey()).isEqualTo("referencingProhibited"); - }); + public void shouldHaveNoAccessForTechnicalContact() { + initAccessFor(ShareDTO.class, Role.TECHNICAL_CONTACT).shouldBeForNothing(); + updateAccessFor(ShareDTO.class, Role.TECHNICAL_CONTACT).shouldBeForNothing(); + readAccessFor(ShareDTO.class, Role.TECHNICAL_CONTACT).shouldBeForNothing(); } @Test - public void financialContactShouldHaveRightToReadAllButRemark() throws IOException { - givenAuthenticatedUser(); - givenUserHavingRole(CustomerDTO.class, SOME_CUSTOMER_ID, Role.FINANCIAL_CONTACT); - final ShareDTO givenDTO = createShareDto(); - - // when - new JSonSerializationWithAccessFilter<>(ctx, jsonGenerator, null, givenDTO).serialize(); - - // then - verify(jsonGenerator).writeNumberField("id", givenDTO.getId()); - verify(jsonGenerator).writeNumberField("membershipId", givenDTO.getMembershipId()); - verify(jsonGenerator, never()).writeStringField(eq("remark"), anyString()); + public void shouldHaveNoAccessForNormalUsersWithinCustomerRealm() { + initAccessFor(ShareDTO.class, Role.ANY_CUSTOMER_USER).shouldBeForNothing(); + updateAccessFor(ShareDTO.class, Role.ANY_CUSTOMER_USER).shouldBeForNothing(); + readAccessFor(ShareDTO.class, Role.ANY_CUSTOMER_USER).shouldBeForNothing(); } - @Test - public void supporterShouldHaveRightToRead() throws IOException { - givenAuthenticatedUser(); - givenUserHavingRole(null, null, Role.SUPPORTER); - final ShareDTO givenDTO = createShareDto(); + // --- only test fixture below --- - // when - new JSonSerializationWithAccessFilter<>(ctx, jsonGenerator, null, givenDTO).serialize(); - - // then - verify(jsonGenerator).writeNumberField("id", givenDTO.getId()); - verify(jsonGenerator).writeNumberField("membershipId", givenDTO.getMembershipId()); - verify(jsonGenerator).writeStringField("remark", givenDTO.getRemark()); + @Override + public ShareDTO createSampleDto(final Long id) { + final ShareDTO dto = new ShareDTO(); + dto.setId(id); + dto.setMembershipId(888L); + dto.setAction(ShareAction.SUBSCRIPTION); + dto.setQuantity(3); + dto.setDocumentDate(LocalDate.parse("2019-04-22")); + dto.setValueDate(LocalDate.parse("2019-04-30")); + dto.setRemark("Some Remark"); + dto.setMembershipDisplayLabel("The Membership #888"); + return dto; } - // --- only fixture code below --- - - private void givenJSonTree(String givenJSon) throws IOException { - given(codec.readTree(jsonParser)).willReturn(new ObjectMapper().readTree(givenJSon)); + @Override + public ShareDTO createRandomDto(final Long id) { + final ShareDTO dto = new ShareDTO(); + dto.setId(id); + dto.setMembershipId(RandomUtils.nextLong()); + dto.setAction(RandomUtil.generateEnumValue(ShareAction.class)); + dto.setQuantity(RandomUtils.nextInt()); + final LocalDate randomDate = LocalDate.parse("2000-12-07").plusDays(RandomUtils.nextInt(1, 999)); + dto.setDocumentDate(randomDate); + dto.setValueDate(randomDate.plusDays(RandomUtils.nextInt(1, 99))); + dto.setRemark(RandomStringUtils.randomAlphanumeric(20)); + dto.setMembershipDisplayLabel("The Membership #" + dto.getMembershipId()); + return dto; } - - private ShareDTO createShareDto() { - final ShareDTO givenDTO = new ShareDTO(); - givenDTO.setId(1234567L); - givenDTO.setMembershipId(SOME_MEMBERSHIP_ID); - givenDTO.setAction(ShareAction.SUBSCRIPTION); - givenDTO.setQuantity(3); - givenDTO.setDocumentDate(LocalDate.parse("2019-04-22")); - givenDTO.setMembershipDisplayLabel("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/ShareResourceIntTest.java b/src/test/java/org/hostsharing/hsadminng/web/rest/ShareResourceIntTest.java index 60804d8b..261aba5a 100644 --- a/src/test/java/org/hostsharing/hsadminng/web/rest/ShareResourceIntTest.java +++ b/src/test/java/org/hostsharing/hsadminng/web/rest/ShareResourceIntTest.java @@ -161,6 +161,7 @@ public class ShareResourceIntTest { // Create the Share ShareDTO shareDTO = shareMapper.toDto(share); + shareDTO.setMembershipDisplayLabel(null); restShareMockMvc.perform(post("/api/shares") .contentType(TestUtil.APPLICATION_JSON_UTF8) .content(TestUtil.convertObjectToJsonBytes(shareDTO)))