add partner business object at repo level (WIP)
This commit is contained in:
@@ -2,113 +2,272 @@ package net.hostsharing.hsadminng.hs.admin.partner;
|
||||
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.context.ContextBasedTest;
|
||||
import net.hostsharing.hsadminng.hs.admin.contact.HsAdminContactRepository;
|
||||
import net.hostsharing.hsadminng.hs.admin.person.HsAdminPersonEntity;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import net.hostsharing.hsadminng.hs.admin.person.HsAdminPersonRepository;
|
||||
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantRepository;
|
||||
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRepository;
|
||||
import net.hostsharing.test.JpaAttempt;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.orm.jpa.JpaSystemException;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.admin.partner.TestHsAdminPartner.testLtd;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantDisplayExtractor.grantDisplaysOf;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleNameExtractor.roleNamesOf;
|
||||
import static net.hostsharing.test.JpaAttempt.attempt;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assumptions.assumeThat;
|
||||
|
||||
@Disabled
|
||||
@DataJpaTest
|
||||
@ComponentScan(basePackageClasses = { Context.class, HsAdminPartnerRepository.class })
|
||||
@ComponentScan(basePackageClasses = { HsAdminPartnerRepository.class, Context.class, JpaAttempt.class })
|
||||
@DirtiesContext
|
||||
class HsAdminPartnerRepositoryIntegrationTest extends ContextBasedTest {
|
||||
|
||||
@Autowired
|
||||
HsAdminPartnerRepository partnerRepository;
|
||||
HsAdminPartnerRepository partnerRepo;
|
||||
|
||||
@Autowired
|
||||
HsAdminPersonRepository personRepo;
|
||||
|
||||
@Autowired
|
||||
HsAdminContactRepository contactRepo;
|
||||
|
||||
@Autowired
|
||||
RbacRoleRepository roleRepo;
|
||||
|
||||
@Autowired
|
||||
RbacGrantRepository grantRepo;
|
||||
|
||||
@Autowired
|
||||
EntityManager em;
|
||||
|
||||
@Autowired
|
||||
JpaAttempt jpaAttempt;
|
||||
|
||||
@MockBean
|
||||
HttpServletRequest request;
|
||||
|
||||
@Nested
|
||||
class CreateCustomer {
|
||||
class CreatePartner {
|
||||
|
||||
@Test
|
||||
public void testHostsharingAdmin_withoutAssumedRole_canCreateNewCustomer() {
|
||||
public void testHostsharingAdmin_withoutAssumedRole_canCreateNewPartner() {
|
||||
// given
|
||||
context("alex@hostsharing.net", null);
|
||||
final var count = partnerRepository.count();
|
||||
context("alex@hostsharing.net");
|
||||
final var count = partnerRepo.count();
|
||||
final var givenPerson = personRepo.findPersonByOptionalNameLike("First Impressions GmbH").get(0);
|
||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("first contact").get(0);
|
||||
|
||||
// when
|
||||
|
||||
final var result = attempt(em, () -> {
|
||||
return partnerRepository.save(testLtd);
|
||||
final var newPartner = HsAdminPartnerEntity.builder()
|
||||
.uuid(UUID.randomUUID())
|
||||
.person(givenPerson)
|
||||
.contact(givenContact)
|
||||
.build();
|
||||
return partnerRepo.save(newPartner);
|
||||
});
|
||||
|
||||
// then
|
||||
assertThat(result.wasSuccessful()).isTrue();
|
||||
result.assertSuccessful();
|
||||
assertThat(result.returnedValue()).isNotNull().extracting(HsAdminPartnerEntity::getUuid).isNotNull();
|
||||
assertThatPartnerIsPersisted(result.returnedValue());
|
||||
assertThat(partnerRepository.count()).isEqualTo(count + 1);
|
||||
assertThat(partnerRepo.count()).isEqualTo(count + 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createsAndGrantsRoles() {
|
||||
// given
|
||||
context("alex@hostsharing.net");
|
||||
final var initialRoleCount = roleRepo.findAll().size();
|
||||
final var initialGrantCount = grantRepo.findAll().size();
|
||||
|
||||
// when
|
||||
attempt(em, () -> {
|
||||
final var givenPerson = personRepo.findPersonByOptionalNameLike("Erbengemeinschaft Bessler").get(0);
|
||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0);
|
||||
final var newPartner = HsAdminPartnerEntity.builder()
|
||||
.uuid(UUID.randomUUID())
|
||||
.person(givenPerson)
|
||||
.contact(givenContact)
|
||||
.build();
|
||||
return partnerRepo.save(newPartner);
|
||||
});
|
||||
|
||||
// then
|
||||
final var roles = roleRepo.findAll();
|
||||
assertThat(roleNamesOf(roles)).containsAll(List.of(
|
||||
"hs_admin_partner#ErbengemeinschaftBesslerMelBessler-forthcontact.admin",
|
||||
"hs_admin_partner#ErbengemeinschaftBesslerMelBessler-forthcontact.owner",
|
||||
"hs_admin_partner#ErbengemeinschaftBesslerMelBessler-forthcontact.tenant"));
|
||||
assertThat(roles.size()).as("invalid number of roles created")
|
||||
.isEqualTo(initialRoleCount + 3);
|
||||
|
||||
context("customer-admin@forthcontact.example.com");
|
||||
assertThat(grantDisplaysOf(grantRepo.findAll())).containsAll(List.of(
|
||||
"{ grant assumed role hs_admin_contact#forthcontact.owner to user customer-admin@forthcontact.example.com by role global#global.admin }"));
|
||||
|
||||
context("person-ErbengemeinschaftBesslerMelBessl@example.com");
|
||||
assertThat(grantDisplaysOf(grantRepo.findAll())).containsAll(List.of(
|
||||
"{ grant assumed role hs_admin_person#ErbengemeinschaftBesslerMelBessler.owner to user person-ErbengemeinschaftBesslerMelBessl@example.com by role global#global.admin }"));
|
||||
}
|
||||
|
||||
private void assertThatPartnerIsPersisted(final HsAdminPartnerEntity saved) {
|
||||
final var found = partnerRepository.findByUuid(saved.getUuid());
|
||||
final var found = partnerRepo.findByUuid(saved.getUuid());
|
||||
assertThat(found).isNotEmpty().get().usingRecursiveComparison().isEqualTo(saved);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class FindAllCustomers {
|
||||
class FindAllPartners {
|
||||
|
||||
@Test
|
||||
public void globalAdmin_withoutAssumedRole_canViewAllCustomers() {
|
||||
public void globalAdmin_withoutAssumedRole_canViewAllPartners() {
|
||||
// given
|
||||
context("alex@hostsharing.net", null);
|
||||
context("alex@hostsharing.net");
|
||||
|
||||
// when
|
||||
final var result = partnerRepository.findPartnerByOptionalNameLike(null);
|
||||
final var result = partnerRepo.findPartnerByOptionalNameLike(null);
|
||||
|
||||
// then
|
||||
allThesePartnersAreReturned(result, "Ixx AG", "Ypsilon GmbH", "Zett OHG");
|
||||
allThesePartnersAreReturned(result, "First Impressions GmbH", "Ostfriesische Kuhhandel OHG", "Rockshop e.K.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void normalUser_canViewOnlyRelatedPartners() {
|
||||
// given:
|
||||
context("person-FirstImpressionsGmbH@example.com");
|
||||
|
||||
// when:
|
||||
final var result = partnerRepo.findPartnerByOptionalNameLike(null);
|
||||
|
||||
// then:
|
||||
exactlyThesePartnersAreReturned(result, "First Impressions GmbH");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class FindByPrefixLike {
|
||||
class FindByNameLike {
|
||||
|
||||
@Test
|
||||
public void globalAdmin_withoutAssumedRole_canViewAllCustomers() {
|
||||
public void globalAdmin_withoutAssumedRole_canViewAllPartners() {
|
||||
// given
|
||||
context("alex@hostsharing.net", null);
|
||||
context("alex@hostsharing.net");
|
||||
|
||||
// when
|
||||
final var result = partnerRepository.findPartnerByOptionalNameLike("Yps");
|
||||
final var result = partnerRepo.findPartnerByOptionalNameLike("Ostfriesische");
|
||||
|
||||
// then
|
||||
exactlyTheseCustomersAreReturned(result, "Ypsilon GmbH");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customerAdmin_withoutAssumedRole_canViewOnlyItsOwnCustomer() {
|
||||
// given:
|
||||
context("customer-admin@xxx.example.com", null);
|
||||
|
||||
// when:
|
||||
final var result = partnerRepository.findPartnerByOptionalNameLike("Yps");
|
||||
|
||||
// then:
|
||||
exactlyTheseCustomersAreReturned(result);
|
||||
exactlyThesePartnersAreReturned(result, "Ostfriesische Kuhhandel OHG");
|
||||
}
|
||||
}
|
||||
|
||||
void exactlyTheseCustomersAreReturned(final List<HsAdminPartnerEntity> actualResult, final String... partnerTradeNames) {
|
||||
@Nested
|
||||
class DeleteByUuid {
|
||||
|
||||
@Test
|
||||
public void globalAdmin_withoutAssumedRole_canDeleteAnyPartner() {
|
||||
// given
|
||||
context("alex@hostsharing.net", null);
|
||||
final var givenPartner = givenSomeTemporaryPartnerBessler();
|
||||
|
||||
// when
|
||||
final var result = jpaAttempt.transacted(() -> {
|
||||
context("alex@hostsharing.net");
|
||||
partnerRepo.deleteByUuid(givenPartner.getUuid());
|
||||
});
|
||||
|
||||
// then
|
||||
result.assertSuccessful();
|
||||
assertThat(jpaAttempt.transacted(() -> {
|
||||
context("fran@hostsharing.net", null);
|
||||
return partnerRepo.findByUuid(givenPartner.getUuid());
|
||||
}).assertSuccessful().returnedValue()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nonGlobalAdmin_canNotDeleteTheirRelatedPartner() {
|
||||
// given
|
||||
context("alex@hostsharing.net", null);
|
||||
final var givenPartner = givenSomeTemporaryPartnerBessler();
|
||||
|
||||
// when
|
||||
final var result = jpaAttempt.transacted(() -> {
|
||||
context("person-ErbengemeinschaftBesslerMelBessl@example.com");
|
||||
assertThat(partnerRepo.findByUuid(givenPartner.getUuid())).isPresent();
|
||||
|
||||
partnerRepo.deleteByUuid(givenPartner.getUuid());
|
||||
});
|
||||
|
||||
// then
|
||||
result.assertExceptionWithRootCauseMessage(JpaSystemException.class,
|
||||
"[403] User person-ErbengemeinschaftBesslerMelBessl@example.com not allowed to delete partner");
|
||||
assertThat(jpaAttempt.transacted(() -> {
|
||||
context("alex@hostsharing.net");
|
||||
return partnerRepo.findByUuid(givenPartner.getUuid());
|
||||
}).assertSuccessful().returnedValue()).isPresent(); // still there
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deletingAPartnerAlsoDeletesRelatedRolesAndGrants() {
|
||||
// given
|
||||
context("alex@hostsharing.net");
|
||||
final var initialRoleCount = roleRepo.findAll().size();
|
||||
final var givenPartner = givenSomeTemporaryPartnerBessler();
|
||||
assumeThat(roleRepo.findAll().size()).as("unexpected number of roles created")
|
||||
.isEqualTo(initialRoleCount + 3);;
|
||||
|
||||
// when
|
||||
final var result = jpaAttempt.transacted(() -> {
|
||||
context("alex@hostsharing.net");
|
||||
partnerRepo.deleteByUuid(givenPartner.getUuid());
|
||||
}).assertSuccessful();
|
||||
|
||||
// then
|
||||
final var roles = roleRepo.findAll();
|
||||
assertThat(roleNamesOf(roles)).doesNotContainAnyElementsOf(List.of(
|
||||
"hs_admin_partner#ErbengemeinschaftBesslerMelBessler-forthcontact.admin",
|
||||
"hs_admin_partner#ErbengemeinschaftBesslerMelBessler-forthcontact.owner",
|
||||
"hs_admin_partner#ErbengemeinschaftBesslerMelBessler-forthcontact.tenant"));
|
||||
assertThat(roles.size()).as("invalid number of roles created")
|
||||
.isEqualTo(initialRoleCount);
|
||||
|
||||
context("customer-admin@forthcontact.example.com");
|
||||
assertThat(grantDisplaysOf(grantRepo.findAll())).doesNotContain(
|
||||
"{ grant assumed role hs_admin_contact#forthcontact.owner to user customer-admin@forthcontact.example.com by role global#global.admin }");
|
||||
|
||||
context("person-ErbengemeinschaftBesslerMelBessl@example.com");
|
||||
assertThat(grantDisplaysOf(grantRepo.findAll())).doesNotContain(
|
||||
"{ grant assumed role hs_admin_person#ErbengemeinschaftBesslerMelBessler.owner to user person-ErbengemeinschaftBesslerMelBessl@example.com by role global#global.admin }");
|
||||
}
|
||||
}
|
||||
|
||||
private HsAdminPartnerEntity givenSomeTemporaryPartnerBessler() {
|
||||
return jpaAttempt.transacted(() -> {
|
||||
context("alex@hostsharing.net");
|
||||
final var givenPerson = personRepo.findPersonByOptionalNameLike("Erbengemeinschaft Bessler").get(0);
|
||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0);
|
||||
final var newPartner = HsAdminPartnerEntity.builder()
|
||||
.uuid(UUID.randomUUID())
|
||||
.person(givenPerson)
|
||||
.contact(givenContact)
|
||||
.build();
|
||||
|
||||
return partnerRepo.save(newPartner);
|
||||
}).assertSuccessful().returnedValue();
|
||||
}
|
||||
|
||||
void exactlyThesePartnersAreReturned(final List<HsAdminPartnerEntity> actualResult, final String... partnerTradeNames) {
|
||||
assertThat(actualResult)
|
||||
.hasSize(partnerTradeNames.length)
|
||||
.extracting(HsAdminPartnerEntity::getPerson)
|
||||
|
@@ -225,6 +225,8 @@ class HsAdminPersonRepositoryIntegrationTest extends ContextBasedTest {
|
||||
}).assertSuccessful().returnedValue()).hasSize(0);
|
||||
}
|
||||
|
||||
// TODO.test: can NOT delete test is missing
|
||||
|
||||
@Test
|
||||
public void deletingAPersonAlsoDeletesRelatedRolesAndGrants() {
|
||||
// given
|
||||
|
Reference in New Issue
Block a user