move Parter+Debitor person+contact to related Relationsship #20

Merged
hsh-michaelhoennig merged 101 commits from remove-direct-partner-person-and-contact into master 2024-03-28 12:15:14 +01:00
7 changed files with 18 additions and 87 deletions
Showing only changes of commit 9b8b50b065 - Show all commits

View File

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

View File

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

View File

@ -1,6 +1,6 @@
### 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
%%{init:{'flowchart':{'htmlLabels':false}}}%%
@ -146,6 +146,7 @@ role:partnerRel:tenant -.-> role:partnerRel.holderPerson:referrer
role:partnerRel:tenant -.-> role:partnerRel.contact:referrer
role:partnerRel:admin ==> role:membership:owner
role:membership:owner ==> role:membership:admin
role:partnerRel:agent ==> role:membership:admin
role:membership:admin ==> role:membership:referrer
role:membership:referrer ==> role:partnerRel:tenant

View File

@ -1,5 +1,5 @@
--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(
hsOfficeMembershipAdmin(NEW),
permissions => array['UPDATE'],
incomingSuperRoles => array[hsOfficeMembershipOwner(NEW)]
incomingSuperRoles => array[
hsOfficeMembershipOwner(NEW),
hsOfficeRelationshipAgent(newPartnerRel)]
);
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.hs.office.coopassets.HsOfficeCoopAssetsTransactionRepository;
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
import net.hostsharing.hsadminng.mapper.Mapper;
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.is;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
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.status;
@ -76,7 +74,6 @@ public class HsOfficeMembershipControllerRestTest {
.content("""
{
"partnerUuid": null,
"mainDebitorUuid": "%s",
"memberNumberSuffix": "01",
"validFrom": "2022-10-13",
"membershipFeeBillable": "true"
@ -91,40 +88,12 @@ public class HsOfficeMembershipControllerRestTest {
.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
void respondBadRequest_ifAnyGivenPartnerUuidCannotBeFound() throws Exception {
// given
final var givenPartnerUuid = UUID.randomUUID();
final var givenMainDebitorUuid = UUID.randomUUID();
when(em.find(HsOfficePartnerEntity.class, givenPartnerUuid)).thenReturn(null);
when(em.find(HsOfficeDebitorEntity.class, givenMainDebitorUuid)).thenReturn(mock(HsOfficeDebitorEntity.class));
// when
mockMvc.perform(MockMvcRequestBuilders
@ -134,12 +103,11 @@ public class HsOfficeMembershipControllerRestTest {
.content("""
{
"partnerUuid": "%s",
"mainDebitorUuid": "%s",
"memberNumberSuffix": "01",
"validFrom": "2022-10-13",
"membershipFeeBillable": "true"
}
""".formatted(givenPartnerUuid, givenMainDebitorUuid))
""".formatted(givenPartnerUuid))
.accept(MediaType.APPLICATION_JSON))
// then
@ -149,38 +117,6 @@ public class HsOfficeMembershipControllerRestTest {
.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
@EnumSource(InvalidMemberSuffixVariants.class)
void respondBadRequest_ifMemberNumberSuffixIsInvalid(final InvalidMemberSuffixVariants testCase) throws Exception {
@ -193,12 +129,11 @@ public class HsOfficeMembershipControllerRestTest {
.content("""
{
"partnerUuid": "%s",
"mainDebitorUuid": "%s",
%s
"validFrom": "2022-10-13",
"membershipFeeBillable": "true"
}
""".formatted(UUID.randomUUID(), UUID.randomUUID(), testCase.memberNumberSuffixEntry))
""".formatted(UUID.randomUUID(), testCase.memberNumberSuffixEntry))
.accept(MediaType.APPLICATION_JSON))
// then

View File

@ -25,7 +25,7 @@ class HsOfficeMembershipEntityUnitTest {
@Test
void toStringContainsAllProps() {
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

View File

@ -25,7 +25,6 @@ import java.util.Arrays;
import java.util.List;
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.test.JpaAttempt.attempt;
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 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
"{ 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 }",
@ -221,20 +223,20 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl
}
@Test
public void membershipAdmin_canViewButNotUpdateRelatedMembership() {
public void membershipReferrer_canViewButNotUpdateRelatedMembership() {
// given
context("superuser-alex@hostsharing.net");
final var givenMembership = givenSomeTemporaryMembership("First", "13");
assertThatMembershipExistsAndIsAccessibleToCurrentContext(givenMembership);
assertThatMembershipIsVisibleForRole(
givenMembership,
"s_office_membership#M-1000101.admin");
"hs_office_membership#M-1000113.referrer");
final var newValidityEnd = LocalDate.now();
// when
final var result = jpaAttempt.transacted(() -> {
// 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(
Range.closedOpen(givenMembership.getValidity().lower(), newValidityEnd));
return membershipRepo.save(givenMembership);
@ -256,7 +258,6 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl
final String assumedRoles) {
jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", assumedRoles);
generateRbacDiagramForCurrentSubjects(ALL_NON_TEST_ENTITY_RELATED);
assertThatMembershipExistsAndIsAccessibleToCurrentContext(entity);
}).assertSuccessful();
}
@ -286,14 +287,14 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl
}
@Test
public void debitorRelationAgent_canNotDeleteTheirRelatedMembership() {
public void partnerRelationAgent_canNotDeleteTheirRelatedMembership() {
// given
context("superuser-alex@hostsharing.net");
final var givenMembership = givenSomeTemporaryMembership("First", "14");
// when
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();
membershipRepo.deleteByUuid(givenMembership.getUuid());