fix memberhip integration tests

This commit is contained in:
Michael Hoennig 2024-03-21 17:14:14 +01:00
parent fa46f339a8
commit 9b8b50b065
7 changed files with 18 additions and 87 deletions

View File

@ -144,6 +144,7 @@ public class HsOfficeMembershipEntity implements HasUuid, Stringifyable {
with.permission(DELETE); with.permission(DELETE);
}) })
.createSubRole(ADMIN, (with) -> { .createSubRole(ADMIN, (with) -> {
with.incomingSuperRole("partnerRel", AGENT);
with.permission(UPDATE); with.permission(UPDATE);
}) })
.createSubRole(REFERRER, (with) -> { .createSubRole(REFERRER, (with) -> {

View File

@ -46,10 +46,6 @@ components:
HsOfficeMembershipPatch: HsOfficeMembershipPatch:
type: object type: object
properties: properties:
mainDebitorUuid:
type: string
format: uuid
nullable: true
validTo: validTo:
type: string type: string
format: date format: date
@ -69,10 +65,6 @@ components:
type: string type: string
format: uuid format: uuid
nullable: false nullable: false
mainDebitorUuid:
type: string
format: uuid
nullable: false
memberNumberSuffix: memberNumberSuffix:
type: string type: string
minLength: 2 minLength: 2
@ -95,7 +87,6 @@ components:
required: required:
- partnerUuid - partnerUuid
- memberNumberSuffix - memberNumberSuffix
- mainDebitorUuid
- validFrom - validFrom
- membershipFeeBillable - membershipFeeBillable
additionalProperties: false additionalProperties: false

View File

@ -1,6 +1,6 @@
### rbac membership ### rbac membership
This code generated was by RbacViewMermaidFlowchartGenerator at 2024-03-18T16:31:23.329131137. This code generated was by RbacViewMermaidFlowchartGenerator at 2024-03-21T17:09:08.826781619.
```mermaid ```mermaid
%%{init:{'flowchart':{'htmlLabels':false}}}%% %%{init:{'flowchart':{'htmlLabels':false}}}%%
@ -146,6 +146,7 @@ role:partnerRel:tenant -.-> role:partnerRel.holderPerson:referrer
role:partnerRel:tenant -.-> role:partnerRel.contact:referrer role:partnerRel:tenant -.-> role:partnerRel.contact:referrer
role:partnerRel:admin ==> role:membership:owner role:partnerRel:admin ==> role:membership:owner
role:membership:owner ==> role:membership:admin role:membership:owner ==> role:membership:admin
role:partnerRel:agent ==> role:membership:admin
role:membership:admin ==> role:membership:referrer role:membership:admin ==> role:membership:referrer
role:membership:referrer ==> role:partnerRel:tenant role:membership:referrer ==> role:partnerRel:tenant

View File

@ -1,5 +1,5 @@
--liquibase formatted sql --liquibase formatted sql
-- This code generated was by RbacViewPostgresGenerator at 2024-03-18T16:31:23.334581734. -- This code generated was by RbacViewPostgresGenerator at 2024-03-21T17:09:08.832004329.
-- ============================================================================ -- ============================================================================
@ -53,7 +53,9 @@ begin
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeMembershipAdmin(NEW), hsOfficeMembershipAdmin(NEW),
permissions => array['UPDATE'], permissions => array['UPDATE'],
incomingSuperRoles => array[hsOfficeMembershipOwner(NEW)] incomingSuperRoles => array[
hsOfficeMembershipOwner(NEW),
hsOfficeRelationshipAgent(newPartnerRel)]
); );
perform createRoleWithGrants( perform createRoleWithGrants(

View File

@ -2,7 +2,6 @@ package net.hostsharing.hsadminng.hs.office.membership;
import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.hs.office.coopassets.HsOfficeCoopAssetsTransactionRepository; import net.hostsharing.hsadminng.hs.office.coopassets.HsOfficeCoopAssetsTransactionRepository;
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity; import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
import net.hostsharing.hsadminng.mapper.Mapper; import net.hostsharing.hsadminng.mapper.Mapper;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
@ -28,7 +27,6 @@ import java.util.UUID;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ -76,7 +74,6 @@ public class HsOfficeMembershipControllerRestTest {
.content(""" .content("""
{ {
"partnerUuid": null, "partnerUuid": null,
"mainDebitorUuid": "%s",
"memberNumberSuffix": "01", "memberNumberSuffix": "01",
"validFrom": "2022-10-13", "validFrom": "2022-10-13",
"membershipFeeBillable": "true" "membershipFeeBillable": "true"
@ -91,40 +88,12 @@ public class HsOfficeMembershipControllerRestTest {
.andExpect(jsonPath("message", is("[partnerUuid must not be null but is \"null\"]"))); .andExpect(jsonPath("message", is("[partnerUuid must not be null but is \"null\"]")));
} }
@Test
void respondBadRequest_ifDebitorUuidIsMissing() throws Exception {
// when
mockMvc.perform(MockMvcRequestBuilders
.post("/api/hs/office/memberships")
.header("current-user", "superuser-alex@hostsharing.net")
.contentType(MediaType.APPLICATION_JSON)
.content("""
{
"partnerUuid": "%s",
"mainDebitorUuid": null,
"memberNumberSuffix": "01",
"validFrom": "2022-10-13",
"membershipFeeBillable": "true"
}
""".formatted(UUID.randomUUID()))
.accept(MediaType.APPLICATION_JSON))
// then
.andExpect(status().is4xxClientError())
.andExpect(jsonPath("statusCode", is(400)))
.andExpect(jsonPath("statusPhrase", is("Bad Request")))
.andExpect(jsonPath("message", is("[mainDebitorUuid must not be null but is \"null\"]")));
}
@Test @Test
void respondBadRequest_ifAnyGivenPartnerUuidCannotBeFound() throws Exception { void respondBadRequest_ifAnyGivenPartnerUuidCannotBeFound() throws Exception {
// given // given
final var givenPartnerUuid = UUID.randomUUID(); final var givenPartnerUuid = UUID.randomUUID();
final var givenMainDebitorUuid = UUID.randomUUID();
when(em.find(HsOfficePartnerEntity.class, givenPartnerUuid)).thenReturn(null); when(em.find(HsOfficePartnerEntity.class, givenPartnerUuid)).thenReturn(null);
when(em.find(HsOfficeDebitorEntity.class, givenMainDebitorUuid)).thenReturn(mock(HsOfficeDebitorEntity.class));
// when // when
mockMvc.perform(MockMvcRequestBuilders mockMvc.perform(MockMvcRequestBuilders
@ -134,12 +103,11 @@ public class HsOfficeMembershipControllerRestTest {
.content(""" .content("""
{ {
"partnerUuid": "%s", "partnerUuid": "%s",
"mainDebitorUuid": "%s",
"memberNumberSuffix": "01", "memberNumberSuffix": "01",
"validFrom": "2022-10-13", "validFrom": "2022-10-13",
"membershipFeeBillable": "true" "membershipFeeBillable": "true"
} }
""".formatted(givenPartnerUuid, givenMainDebitorUuid)) """.formatted(givenPartnerUuid))
.accept(MediaType.APPLICATION_JSON)) .accept(MediaType.APPLICATION_JSON))
// then // then
@ -149,38 +117,6 @@ public class HsOfficeMembershipControllerRestTest {
.andExpect(jsonPath("message", is("Unable to find Partner with uuid " + givenPartnerUuid))); .andExpect(jsonPath("message", is("Unable to find Partner with uuid " + givenPartnerUuid)));
} }
@Test
void respondBadRequest_ifAnyGivenDebitorUuidCannotBeFound() throws Exception {
// given
final var givenPartnerUuid = UUID.randomUUID();
final var givenMainDebitorUuid = UUID.randomUUID();
when(em.find(HsOfficePartnerEntity.class, givenPartnerUuid)).thenReturn(mock(HsOfficePartnerEntity.class));
when(em.find(HsOfficeDebitorEntity.class, givenMainDebitorUuid)).thenReturn(null);
// when
mockMvc.perform(MockMvcRequestBuilders
.post("/api/hs/office/memberships")
.header("current-user", "superuser-alex@hostsharing.net")
.contentType(MediaType.APPLICATION_JSON)
.content("""
{
"partnerUuid": "%s",
"mainDebitorUuid": "%s",
"memberNumberSuffix": "01",
"validFrom": "2022-10-13",
"membershipFeeBillable": "true"
}
""".formatted(givenPartnerUuid, givenMainDebitorUuid))
.accept(MediaType.APPLICATION_JSON))
// then
.andExpect(status().is4xxClientError())
.andExpect(jsonPath("statusCode", is(400)))
.andExpect(jsonPath("statusPhrase", is("Bad Request")))
.andExpect(jsonPath("message", is("Unable to find Debitor with uuid " + givenMainDebitorUuid)));
}
@ParameterizedTest @ParameterizedTest
@EnumSource(InvalidMemberSuffixVariants.class) @EnumSource(InvalidMemberSuffixVariants.class)
void respondBadRequest_ifMemberNumberSuffixIsInvalid(final InvalidMemberSuffixVariants testCase) throws Exception { void respondBadRequest_ifMemberNumberSuffixIsInvalid(final InvalidMemberSuffixVariants testCase) throws Exception {
@ -193,12 +129,11 @@ public class HsOfficeMembershipControllerRestTest {
.content(""" .content("""
{ {
"partnerUuid": "%s", "partnerUuid": "%s",
"mainDebitorUuid": "%s",
%s %s
"validFrom": "2022-10-13", "validFrom": "2022-10-13",
"membershipFeeBillable": "true" "membershipFeeBillable": "true"
} }
""".formatted(UUID.randomUUID(), UUID.randomUUID(), testCase.memberNumberSuffixEntry)) """.formatted(UUID.randomUUID(), testCase.memberNumberSuffixEntry))
.accept(MediaType.APPLICATION_JSON)) .accept(MediaType.APPLICATION_JSON))
// then // then

View File

@ -25,7 +25,7 @@ class HsOfficeMembershipEntityUnitTest {
@Test @Test
void toStringContainsAllProps() { void toStringContainsAllProps() {
final var result = givenMembership.toString(); final var result = givenMembership.toString();
assertThat(result).isEqualTo("Membership(M-1000101, LP Test Ltd., D-1000100, [2020-01-01,))"); assertThat(result).isEqualTo("Membership(M-1000101, P-10001, [2020-01-01,))");
} }
@Test @Test

View File

@ -25,7 +25,6 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import static net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantEntity.distinctGrantDisplaysOf; import static net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantEntity.distinctGrantDisplaysOf;
import static net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsDiagramService.Include.ALL_NON_TEST_ENTITY_RELATED;
import static net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleEntity.distinctRoleNamesOf; import static net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleEntity.distinctRoleNamesOf;
import static net.hostsharing.test.JpaAttempt.attempt; import static net.hostsharing.test.JpaAttempt.attempt;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -130,6 +129,9 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl
"{ grant role membership#M-1000117.owner to role relationship#HostsharingeG-with-PARTNER-FirstGmbH.admin by system and assume }", "{ grant role membership#M-1000117.owner to role relationship#HostsharingeG-with-PARTNER-FirstGmbH.admin by system and assume }",
"{ grant role membership#M-1000117.owner to user superuser-alex@hostsharing.net by membership#M-1000117.owner and assume }", "{ grant role membership#M-1000117.owner to user superuser-alex@hostsharing.net by membership#M-1000117.owner and assume }",
// agent
"{ grant role membership#M-1000117.admin to role relationship#HostsharingeG-with-PARTNER-FirstGmbH.agent by system and assume }",
// referrer // referrer
"{ grant perm SELECT on membership#M-1000117 to role membership#M-1000117.referrer by system and assume }", "{ grant perm SELECT on membership#M-1000117 to role membership#M-1000117.referrer by system and assume }",
"{ grant role membership#M-1000117.referrer to role membership#M-1000117.admin by system and assume }", "{ grant role membership#M-1000117.referrer to role membership#M-1000117.admin by system and assume }",
@ -221,20 +223,20 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl
} }
@Test @Test
public void membershipAdmin_canViewButNotUpdateRelatedMembership() { public void membershipReferrer_canViewButNotUpdateRelatedMembership() {
// given // given
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
final var givenMembership = givenSomeTemporaryMembership("First", "13"); final var givenMembership = givenSomeTemporaryMembership("First", "13");
assertThatMembershipExistsAndIsAccessibleToCurrentContext(givenMembership); assertThatMembershipExistsAndIsAccessibleToCurrentContext(givenMembership);
assertThatMembershipIsVisibleForRole( assertThatMembershipIsVisibleForRole(
givenMembership, givenMembership,
"s_office_membership#M-1000101.admin"); "hs_office_membership#M-1000113.referrer");
final var newValidityEnd = LocalDate.now(); final var newValidityEnd = LocalDate.now();
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
// TODO: we should test with debitor- and partner-admin as well // TODO: we should test with debitor- and partner-admin as well
context("superuser-alex@hostsharing.net", "hs_office_membership#M-1000101.admin"); context("superuser-alex@hostsharing.net", "hs_office_membership#M-1000113.referrer");
givenMembership.setValidity( givenMembership.setValidity(
Range.closedOpen(givenMembership.getValidity().lower(), newValidityEnd)); Range.closedOpen(givenMembership.getValidity().lower(), newValidityEnd));
return membershipRepo.save(givenMembership); return membershipRepo.save(givenMembership);
@ -256,7 +258,6 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl
final String assumedRoles) { final String assumedRoles) {
jpaAttempt.transacted(() -> { jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", assumedRoles); context("superuser-alex@hostsharing.net", assumedRoles);
generateRbacDiagramForCurrentSubjects(ALL_NON_TEST_ENTITY_RELATED);
assertThatMembershipExistsAndIsAccessibleToCurrentContext(entity); assertThatMembershipExistsAndIsAccessibleToCurrentContext(entity);
}).assertSuccessful(); }).assertSuccessful();
} }
@ -286,14 +287,14 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl
} }
@Test @Test
public void debitorRelationAgent_canNotDeleteTheirRelatedMembership() { public void partnerRelationAgent_canNotDeleteTheirRelatedMembership() {
// given // given
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
final var givenMembership = givenSomeTemporaryMembership("First", "14"); final var givenMembership = givenSomeTemporaryMembership("First", "14");
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", "hs_office_relationship#ThirdOHG-with-ACCOUNTING-ThirdOHG.agent"); context("superuser-alex@hostsharing.net", "hs_office_relationship#HostsharingeG-with-PARTNER-FirstGmbH.agent");
assertThat(membershipRepo.findByUuid(givenMembership.getUuid())).isPresent(); assertThat(membershipRepo.findByUuid(givenMembership.getUuid())).isPresent();
membershipRepo.deleteByUuid(givenMembership.getUuid()); membershipRepo.deleteByUuid(givenMembership.getUuid());