1
0

adds HsOfficePartner

This commit is contained in:
Michael Hoennig
2022-10-03 11:09:36 +02:00
parent d3312c4444
commit c3195662dd
35 changed files with 2182 additions and 35 deletions

View File

@@ -132,7 +132,7 @@ public abstract class PatchUnitTestBase<R, E> {
protected abstract EntityPatcher<R> createPatcher(final E entity);
@SuppressWarnings("rawtypes")
@SuppressWarnings("types")
protected abstract Stream<Property> propertyTestDescriptors();
private Stream<Arguments> propertyTestCases() {

View File

@@ -17,10 +17,16 @@ public class ArchitectureTest {
public static final String NET_HOSTSHARING_HSADMINNG = "net.hostsharing.hsadminng";
@ArchTest
@SuppressWarnings("unused")
public static final ArchRule doNotUseJUnit4 = noClasses()
.should().accessClassesThat()
.resideInAPackage("org.junit");
@ArchTest
@SuppressWarnings("unused")
public static final ArchRule dontUseImplSuffix = noClasses()
.should().haveSimpleNameEndingWith("Impl");
@ArchTest
@SuppressWarnings("unused")
public static final ArchRule contextPackageRule = classes()
@@ -68,7 +74,7 @@ public class ArchitectureTest {
public static final ArchRule HsOfficePartnerPackageRule = classes()
.that().resideInAPackage("..hs.office.partner..")
.should().onlyBeAccessed().byClassesThat()
.resideInAnyPackage("..hs.office.partner..");
.resideInAnyPackage("..hs.office.partner..", "..hs.office.debitor..");
@ArchTest
@SuppressWarnings("unused")

View File

@@ -4,9 +4,14 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.orm.jpa.JpaObjectRetrievalFailureException;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.web.context.request.WebRequest;
import javax.persistence.EntityNotFoundException;
import java.util.NoSuchElementException;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
@@ -44,6 +49,75 @@ class RestResponseEntityExceptionHandlerUnitTest {
assertThat(errorResponse.getBody().getMessage()).isEqualTo("ERROR: [401] First Line");
}
@Test
void handleJpaObjectRetrievalFailureExceptionWithDisplayName() {
// given
final var givenException = new JpaObjectRetrievalFailureException(
new EntityNotFoundException(
"Unable to find net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity with id 12345-123454")
);
final var givenWebRequest = mock(WebRequest.class);
// when
final var errorResponse = exceptionHandler.handleJpaObjectRetrievalFailureException(givenException, givenWebRequest);
// then
assertThat(errorResponse.getStatusCodeValue()).isEqualTo(400);
assertThat(errorResponse.getBody().getMessage()).isEqualTo("Unable to find Partner with uuid 12345-123454");
}
@Test
void handleJpaObjectRetrievalFailureExceptionIfEntityClassCannotBeDetermined() {
// given
final var givenException = new JpaObjectRetrievalFailureException(
new EntityNotFoundException(
"Unable to find net.hostsharing.hsadminng.WhateverEntity with id 12345-123454")
);
final var givenWebRequest = mock(WebRequest.class);
// when
final var errorResponse = exceptionHandler.handleJpaObjectRetrievalFailureException(givenException, givenWebRequest);
// then
assertThat(errorResponse.getStatusCodeValue()).isEqualTo(400);
assertThat(errorResponse.getBody().getMessage()).isEqualTo(
"Unable to find net.hostsharing.hsadminng.WhateverEntity with id 12345-123454");
}
@Test
void handleJpaObjectRetrievalFailureExceptionIfPatternDoesNotMatch() {
// given
final var givenException = new JpaObjectRetrievalFailureException(
new EntityNotFoundException("whatever error message")
);
final var givenWebRequest = mock(WebRequest.class);
// when
final var errorResponse = exceptionHandler.handleJpaObjectRetrievalFailureException(givenException, givenWebRequest);
// then
assertThat(errorResponse.getStatusCodeValue()).isEqualTo(400);
assertThat(errorResponse.getBody().getMessage()).isEqualTo("whatever error message");
}
@Test
void handleJpaObjectRetrievalFailureExceptionWithEntityName() {
// given
final var givenException = new JpaObjectRetrievalFailureException(
new EntityNotFoundException("Unable to find "
+ NoDisplayNameEntity.class.getTypeName()
+ " with id 12345-123454")
);
final var givenWebRequest = mock(WebRequest.class);
// when
final var errorResponse = exceptionHandler.handleJpaObjectRetrievalFailureException(givenException, givenWebRequest);
// then
assertThat(errorResponse.getStatusCodeValue()).isEqualTo(400);
assertThat(errorResponse.getBody().getMessage()).isEqualTo("Unable to find NoDisplayNameEntity with uuid 12345-123454");
}
@Test
void jpaExceptionWithUnknownErrorCode() {
// given
@@ -59,6 +133,20 @@ class RestResponseEntityExceptionHandlerUnitTest {
assertThat(errorResponse.getBody().getMessage()).isEqualTo("ERROR: [999] First Line");
}
@Test
void handleNoSuchElementException() {
// given
final var givenException = new NoSuchElementException("some error message");
final var givenWebRequest = mock(WebRequest.class);
// when
final var errorResponse = exceptionHandler.handleNoSuchElementException(givenException, givenWebRequest);
// then
assertThat(errorResponse.getStatusCodeValue()).isEqualTo(404);
assertThat(errorResponse.getBody().getMessage()).isEqualTo("some error message");
}
@Test
void handleOtherExceptionsWithoutErrorCode() {
// given
@@ -87,4 +175,8 @@ class RestResponseEntityExceptionHandlerUnitTest {
assertThat(errorResponse.getBody().getMessage()).isEqualTo("ERROR: [418] First Line");
}
public static class NoDisplayNameEntity {
}
}

View File

@@ -0,0 +1,505 @@
package net.hostsharing.hsadminng.hs.office.debitor;
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import net.hostsharing.hsadminng.Accepts;
import net.hostsharing.hsadminng.HsadminNgApplication;
import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRepository;
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository;
import net.hostsharing.test.JpaAttempt;
import org.json.JSONException;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import static net.hostsharing.test.IsValidUuidMatcher.isUuidValid;
import static net.hostsharing.test.JsonMatcher.lenientlyEquals;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assumptions.assumeThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.startsWith;
@SpringBootTest(
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
classes = { HsadminNgApplication.class, JpaAttempt.class }
)
@Transactional
class HsOfficeDebitorControllerAcceptanceTest {
private static int nextDebitorNumber = 20001;
@LocalServerPort
private Integer port;
@Autowired
Context context;
@Autowired
Context contextMock;
@Autowired
HsOfficeDebitorRepository debitorRepo;
@Autowired
HsOfficePartnerRepository partnerRepo;
@Autowired
HsOfficeContactRepository contactRepo;
@Autowired
JpaAttempt jpaAttempt;
Set<UUID> tempDebitorUuids = new HashSet<>();
@Nested
@Accepts({ "Debitor:F(Find)" })
class ListDebitors {
@Test
void globalAdmin_withoutAssumedRoles_canViewAllDebitors_ifNoCriteriaGiven() throws JSONException {
RestAssured // @formatter:off
.given()
.header("current-user", "superuser-alex@hostsharing.net")
.port(port)
.when()
.get("http://localhost/api/hs/office/debitors")
.then().log().all().assertThat()
.statusCode(200)
.contentType("application/json")
.body("", lenientlyEquals("""
[
{
"debitorNumber": 10001,
"partner": { "person": { "personType": "LEGAL" } },
"billingContact": { "label": "first contact" },
"vatId": null,
"vatCountryCode": null,
"vatBusiness": true
},
{
"debitorNumber": 10002,
"partner": { "person": { "tradeName": "Second e.K." } },
"billingContact": { "label": "second contact" },
"vatId": null,
"vatCountryCode": null,
"vatBusiness": true
},
{
"debitorNumber": 10003,
"partner": { "person": { "tradeName": "Third OHG" } },
"billingContact": { "label": "third contact" },
"vatId": null,
"vatCountryCode": null,
"vatBusiness": true
}
]
"""));
// @formatter:on
}
@Test
void globalAdmin_withoutAssumedRoles_canFindDebitorDebitorByDebitorNumber() throws JSONException {
RestAssured // @formatter:off
.given()
.header("current-user", "superuser-alex@hostsharing.net")
.port(port)
.when()
.get("http://localhost/api/hs/office/debitors?debitorNumber=10002")
.then().log().all().assertThat()
.statusCode(200)
.contentType("application/json")
.body("", lenientlyEquals("""
[
{
"debitorNumber": 10002,
"partner": { "person": { "tradeName": "Second e.K." } },
"billingContact": { "label": "second contact" },
"vatId": null,
"vatCountryCode": null,
"vatBusiness": true
}
]
"""));
// @formatter:on
}
}
@Nested
@Accepts({ "Debitor:C(Create)" })
class AddDebitor {
@Test
void globalAdmin_withoutAssumedRole_canAddDebitor() {
context.define("superuser-alex@hostsharing.net");
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("Third").get(0);
final var givenContact = contactRepo.findContactByOptionalLabelLike("forth").get(0);
final var location = RestAssured // @formatter:off
.given()
.header("current-user", "superuser-alex@hostsharing.net")
.contentType(ContentType.JSON)
.body("""
{
"partnerUuid": "%s",
"billingContactUuid": "%s",
"debitorNumber": "%s",
"vatId": "VAT123456",
"vatCountryCode": "DE",
"vatBusiness": true
}
""".formatted( givenPartner.getUuid(), givenContact.getUuid(), nextDebitorNumber++))
.port(port)
.when()
.post("http://localhost/api/hs/office/debitors")
.then().log().all().assertThat()
.statusCode(201)
.contentType(ContentType.JSON)
.body("uuid", isUuidValid())
.body("vatId", is("VAT123456"))
.body("billingContact.label", is(givenContact.getLabel()))
.body("partner.person.tradeName", is(givenPartner.getPerson().getTradeName()))
.header("Location", startsWith("http://localhost"))
.extract().header("Location"); // @formatter:on
// finally, the new debitor can be accessed under the generated UUID
final var newUserUuid = toCleanup(UUID.fromString(
location.substring(location.lastIndexOf('/') + 1)));
assertThat(newUserUuid).isNotNull();
}
@Test
void globalAdmin_canNotAddDebitor_ifContactDoesNotExist() {
context.define("superuser-alex@hostsharing.net");
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("Third").get(0);
final var givenContactUuid = UUID.fromString("3fa85f64-5717-4562-b3fc-2c963f66afa6");
final var location = RestAssured // @formatter:off
.given()
.header("current-user", "superuser-alex@hostsharing.net")
.contentType(ContentType.JSON)
.body("""
{
"partnerUuid": "%s",
"billingContactUuid": "%s",
"debitorNumber": "%s",
"vatId": "VAT123456",
"vatCountryCode": "DE",
"vatBusiness": true
}
""".formatted( givenPartner.getUuid(), givenContactUuid, nextDebitorNumber++))
.port(port)
.when()
.post("http://localhost/api/hs/office/debitors")
.then().log().all().assertThat()
.statusCode(400)
.body("message", is("Unable to find Contact with uuid 3fa85f64-5717-4562-b3fc-2c963f66afa6"));
// @formatter:on
}
@Test
void globalAdmin_canNotAddDebitor_ifPartnerDoesNotExist() {
context.define("superuser-alex@hostsharing.net");
final var givenPartnerUuid = UUID.fromString("3fa85f64-5717-4562-b3fc-2c963f66afa6");
final var givenContact = contactRepo.findContactByOptionalLabelLike("forth").get(0);
final var location = RestAssured // @formatter:off
.given()
.header("current-user", "superuser-alex@hostsharing.net")
.contentType(ContentType.JSON)
.body("""
{
"partnerUuid": "%s",
"billingContactUuid": "%s",
"debitorNumber": "%s",
"vatId": "VAT123456",
"vatCountryCode": "DE",
"vatBusiness": true
}
""".formatted( givenPartnerUuid, givenContact.getUuid(), nextDebitorNumber++))
.port(port)
.when()
.post("http://localhost/api/hs/office/debitors")
.then().log().all().assertThat()
.statusCode(400)
.body("message", is("Unable to find Partner with uuid 3fa85f64-5717-4562-b3fc-2c963f66afa6"));
// @formatter:on
}
}
@Nested
@Accepts({ "Debitor:R(Read)" })
class GetDebitor {
@Test
void globalAdmin_withoutAssumedRole_canGetArbitraryDebitor() {
context.define("superuser-alex@hostsharing.net");
final var givenDebitorUuid = debitorRepo.findDebitorByOptionalNameLike("First").get(0).getUuid();
RestAssured // @formatter:off
.given()
.header("current-user", "superuser-alex@hostsharing.net")
.port(port)
.when()
.get("http://localhost/api/hs/office/debitors/" + givenDebitorUuid)
.then().log().body().assertThat()
.statusCode(200)
.contentType("application/json")
.body("", lenientlyEquals("""
{
"partner": { person: { "tradeName": "First GmbH" } },
"billingContact": { "label": "first contact" }
}
""")); // @formatter:on
}
@Test
@Accepts({ "Debitor:X(Access Control)" })
void normalUser_canNotGetUnrelatedDebitor() {
context.define("superuser-alex@hostsharing.net");
final var givenDebitorUuid = debitorRepo.findDebitorByOptionalNameLike("First").get(0).getUuid();
RestAssured // @formatter:off
.given()
.header("current-user", "selfregistered-user-drew@hostsharing.org")
.port(port)
.when()
.get("http://localhost/api/hs/office/debitors/" + givenDebitorUuid)
.then().log().body().assertThat()
.statusCode(404); // @formatter:on
}
@Test
@Accepts({ "Debitor:X(Access Control)" })
void contactAdminUser_canGetRelatedDebitor() {
context.define("superuser-alex@hostsharing.net");
final var givenDebitorUuid = debitorRepo.findDebitorByOptionalNameLike("first contact").get(0).getUuid();
RestAssured // @formatter:off
.given()
.header("current-user", "contact-admin@firstcontact.example.com")
.port(port)
.when()
.get("http://localhost/api/hs/office/debitors/" + givenDebitorUuid)
.then().log().body().assertThat()
.statusCode(200)
.contentType("application/json")
.body("", lenientlyEquals("""
{
"partner": { person: { "tradeName": "First GmbH" } },
"billingContact": { "label": "first contact" }
}
""")); // @formatter:on
}
}
@Nested
@Accepts({ "Debitor:U(Update)" })
class PatchDebitor {
@Test
void globalAdmin_withoutAssumedRole_canPatchAllPropertiesOfArbitraryDebitor() {
context.define("superuser-alex@hostsharing.net");
final var givenDebitor = givenSomeTemporaryDebitor();
final var givenContact = contactRepo.findContactByOptionalLabelLike("forth").get(0);
final var location = RestAssured // @formatter:off
.given()
.header("current-user", "superuser-alex@hostsharing.net")
.contentType(ContentType.JSON)
.body("""
{
"contactUuid": "%s",
"vatId": "VAT222222",
"vatCountryCode": "AA",
"vatBusiness": true
}
""".formatted(givenContact.getUuid()))
.port(port)
.when()
.patch("http://localhost/api/hs/office/debitors/" + givenDebitor.getUuid())
.then().assertThat()
.statusCode(200)
.contentType(ContentType.JSON)
.body("uuid", isUuidValid())
.body("vatId", is("VAT222222"))
.body("vatCountryCode", is("AA"))
.body("vatBusiness", is(true))
.body("billingContact.label", is(givenContact.getLabel()))
.body("partner.person.tradeName", is(givenDebitor.getPartner().getPerson().getTradeName()));
// @formatter:on
// finally, the debitor is actually updated
context.define("superuser-alex@hostsharing.net");
assertThat(debitorRepo.findByUuid(givenDebitor.getUuid())).isPresent().get()
.matches(partner -> {
assertThat(partner.getPartner().getPerson().getTradeName()).isEqualTo(givenDebitor.getPartner()
.getPerson()
.getTradeName());
assertThat(partner.getBillingContact().getLabel()).isEqualTo("forth contact");
assertThat(partner.getVatId()).isEqualTo("VAT222222");
assertThat(partner.getVatCountryCode()).isEqualTo("AA");
assertThat(partner.isVatBusiness()).isEqualTo(true);
return true;
});
}
@Test
void globalAdmin_withoutAssumedRole_canPatchPartialPropertiesOfArbitraryDebitor() {
context.define("superuser-alex@hostsharing.net");
final var givenDebitor = givenSomeTemporaryDebitor();
final var newBillingContact = contactRepo.findContactByOptionalLabelLike("sixth").get(0);
final var location = RestAssured // @formatter:off
.given()
.header("current-user", "superuser-alex@hostsharing.net")
.contentType(ContentType.JSON)
.body("""
{
"billingContactUuid": "%s",
"vatId": "VAT999999"
}
""".formatted(newBillingContact.getUuid()))
.port(port)
.when()
.patch("http://localhost/api/hs/office/debitors/" + givenDebitor.getUuid())
.then().assertThat()
.statusCode(200)
.contentType(ContentType.JSON)
.body("uuid", isUuidValid())
.body("billingContact.label", is("sixth contact"))
.body("vatId", is("VAT999999"))
.body("vatCountryCode", is(givenDebitor.getVatCountryCode()))
.body("vatBusiness", is(givenDebitor.isVatBusiness()));
// @formatter:on
// finally, the debitor is actually updated
assertThat(debitorRepo.findByUuid(givenDebitor.getUuid())).isPresent().get()
.matches(partner -> {
assertThat(partner.getPartner().getPerson().getTradeName()).isEqualTo(givenDebitor.getPartner()
.getPerson()
.getTradeName());
assertThat(partner.getBillingContact().getLabel()).isEqualTo("sixth contact");
assertThat(partner.getVatId()).isEqualTo("VAT999999");
assertThat(partner.getVatCountryCode()).isEqualTo(givenDebitor.getVatCountryCode());
assertThat(partner.isVatBusiness()).isEqualTo(givenDebitor.isVatBusiness());
return true;
});
}
}
@Nested
@Accepts({ "Debitor:D(Delete)" })
class DeleteDebitor {
@Test
void globalAdmin_withoutAssumedRole_canDeleteArbitraryDebitor() {
context.define("superuser-alex@hostsharing.net");
final var givenDebitor = givenSomeTemporaryDebitor();
RestAssured // @formatter:off
.given()
.header("current-user", "superuser-alex@hostsharing.net")
.port(port)
.when()
.delete("http://localhost/api/hs/office/debitors/" + givenDebitor.getUuid())
.then().log().body().assertThat()
.statusCode(204); // @formatter:on
// then the given debitor is gone
assertThat(debitorRepo.findByUuid(givenDebitor.getUuid())).isEmpty();
}
@Test
@Accepts({ "Debitor:X(Access Control)" })
void contactAdminUser_canNotDeleteRelatedDebitor() {
context.define("superuser-alex@hostsharing.net");
final var givenDebitor = givenSomeTemporaryDebitor();
assumeThat(givenDebitor.getBillingContact().getLabel()).isEqualTo("forth contact");
RestAssured // @formatter:off
.given()
.header("current-user", "contact-admin@forthcontact.example.com")
.port(port)
.when()
.delete("http://localhost/api/hs/office/debitors/" + givenDebitor.getUuid())
.then().log().body().assertThat()
.statusCode(403); // @formatter:on
// then the given debitor is still there
assertThat(debitorRepo.findByUuid(givenDebitor.getUuid())).isNotEmpty();
}
@Test
@Accepts({ "Debitor:X(Access Control)" })
void normalUser_canNotDeleteUnrelatedDebitor() {
context.define("superuser-alex@hostsharing.net");
final var givenDebitor = givenSomeTemporaryDebitor();
assumeThat(givenDebitor.getBillingContact().getLabel()).isEqualTo("forth contact");
RestAssured // @formatter:off
.given()
.header("current-user", "selfregistered-user-drew@hostsharing.org")
.port(port)
.when()
.delete("http://localhost/api/hs/office/debitors/" + givenDebitor.getUuid())
.then().log().body().assertThat()
.statusCode(404); // @formatter:on
// then the given debitor is still there
assertThat(debitorRepo.findByUuid(givenDebitor.getUuid())).isNotEmpty();
}
}
private HsOfficeDebitorEntity givenSomeTemporaryDebitor() {
return jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net");
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("Fourth").get(0);
final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0);
final var newDebitor = HsOfficeDebitorEntity.builder()
.uuid(UUID.randomUUID())
.debitorNumber(nextDebitorNumber++)
.partner(givenPartner)
.billingContact(givenContact)
.build();
toCleanup(newDebitor.getUuid());
return debitorRepo.save(newDebitor);
}).assertSuccessful().returnedValue();
}
private UUID toCleanup(final UUID tempDebitorUuid) {
tempDebitorUuids.add(tempDebitorUuid);
return tempDebitorUuid;
}
@AfterEach
void cleanup() {
tempDebitorUuids.forEach(uuid -> {
jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net", null);
System.out.println("DELETING temporary debitor: " + uuid);
final var count = debitorRepo.deleteByUuid(uuid);
System.out.println("DELETED temporary debitor: " + uuid + (count > 0 ? " successful" : " failed"));
});
});
}
}

View File

@@ -0,0 +1,112 @@
package net.hostsharing.hsadminng.hs.office.debitor;
import net.hostsharing.hsadminng.PatchUnitTestBase;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorPatchResource;
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import javax.persistence.EntityManager;
import java.util.UUID;
import java.util.stream.Stream;
import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.lenient;
@TestInstance(PER_CLASS)
@ExtendWith(MockitoExtension.class)
class HsOfficeDebitorEntityPatcherUnitTest extends PatchUnitTestBase<
HsOfficeDebitorPatchResource,
HsOfficeDebitorEntity
> {
private static final UUID INITIAL_DEBITOR_UUID = UUID.randomUUID();
private static final UUID INITIAL_PARTNER_UUID = UUID.randomUUID();
private static final UUID INITIAL_CONTACT_UUID = UUID.randomUUID();
private static final UUID PATCHED_CONTACT_UUID = UUID.randomUUID();
private static final String PATCHED_VAT_COUNTRY_CODE = "ZZ";
private static final boolean PATCHED_VAT_BUSINESS = false;
private final HsOfficePartnerEntity givenInitialPartner = HsOfficePartnerEntity.builder()
.uuid(INITIAL_PARTNER_UUID)
.build();
private final HsOfficeContactEntity givenInitialContact = HsOfficeContactEntity.builder()
.uuid(INITIAL_CONTACT_UUID)
.build();
@Mock
private EntityManager em;
@BeforeEach
void initMocks() {
lenient().when(em.getReference(eq(HsOfficeContactEntity.class), any())).thenAnswer(invocation ->
HsOfficeContactEntity.builder().uuid(invocation.getArgument(1)).build());
lenient().when(em.getReference(eq(HsOfficeContactEntity.class), any())).thenAnswer(invocation ->
HsOfficeContactEntity.builder().uuid(invocation.getArgument(1)).build());
}
@Override
protected HsOfficeDebitorEntity newInitialEntity() {
final var entity = new HsOfficeDebitorEntity();
entity.setUuid(INITIAL_DEBITOR_UUID);
entity.setPartner(givenInitialPartner);
entity.setBillingContact(givenInitialContact);
entity.setVatId("initial VAT-ID");
entity.setVatCountryCode("AA");
entity.setVatBusiness(true);
return entity;
}
@Override
protected HsOfficeDebitorPatchResource newPatchResource() {
return new HsOfficeDebitorPatchResource();
}
@Override
protected HsOfficeDebitorEntityPatcher createPatcher(final HsOfficeDebitorEntity debitor) {
return new HsOfficeDebitorEntityPatcher(em, debitor);
}
@Override
protected Stream<Property> propertyTestDescriptors() {
return Stream.of(
new JsonNullableProperty<>(
"billingContact",
HsOfficeDebitorPatchResource::setBillingContactUuid,
PATCHED_CONTACT_UUID,
HsOfficeDebitorEntity::setBillingContact,
newBillingContact(PATCHED_CONTACT_UUID))
.notNullable(),
new JsonNullableProperty<>(
"vatId",
HsOfficeDebitorPatchResource::setVatId,
"patched VAT-ID",
HsOfficeDebitorEntity::setVatId),
new JsonNullableProperty<>(
"vatCountryCode",
HsOfficeDebitorPatchResource::setVatCountryCode,
PATCHED_VAT_COUNTRY_CODE,
HsOfficeDebitorEntity::setVatCountryCode),
new JsonNullableProperty<>(
"vatBusiness",
HsOfficeDebitorPatchResource::setVatBusiness,
PATCHED_VAT_BUSINESS,
HsOfficeDebitorEntity::setVatBusiness)
.notNullable()
);
}
private HsOfficeContactEntity newBillingContact(final UUID uuid) {
final var newContact = new HsOfficeContactEntity();
newContact.setUuid(uuid);
return newContact;
}
}

View File

@@ -0,0 +1,40 @@
package net.hostsharing.hsadminng.hs.office.debitor;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class HsOfficeDebitorEntityTest {
@Test
void toStringContainsPartnerAndContact() {
final var given = HsOfficeDebitorEntity.builder()
.debitorNumber(123456)
.partner(HsOfficePartnerEntity.builder()
.person(HsOfficePersonEntity.builder()
.tradeName("some trade name")
.build())
.birthName("some birth name")
.build())
.billingContact(HsOfficeContactEntity.builder().label("some label").build())
.build();
final var result = given.toString();
assertThat(result).isEqualTo("debitor(123456: some trade name)");
}
@Test
void toShortStringContainsPartnerAndContact() {
final var given = HsOfficeDebitorEntity.builder()
.debitorNumber(123456)
.build();
final var result = given.toShortString();
assertThat(result).isEqualTo("123456");
}
}

View File

@@ -0,0 +1,464 @@
package net.hostsharing.hsadminng.hs.office.debitor;
import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.context.ContextBasedTest;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRepository;
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository;
import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository;
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
import net.hostsharing.test.Array;
import net.hostsharing.test.JpaAttempt;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
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.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import static net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantEntity.grantDisplaysOf;
import static net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleEntity.roleNamesOf;
import static net.hostsharing.test.JpaAttempt.attempt;
import static org.assertj.core.api.Assertions.assertThat;
@DataJpaTest
@ComponentScan(basePackageClasses = { HsOfficeDebitorRepository.class, Context.class, JpaAttempt.class })
@DirtiesContext
class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
@Autowired
HsOfficeDebitorRepository debitorRepo;
@Autowired
HsOfficePartnerRepository partnerRepo;
@Autowired
HsOfficeContactRepository contactRepo;
@Autowired
RawRbacRoleRepository rawRoleRepo;
@Autowired
RawRbacGrantRepository rawGrantRepo;
@Autowired
EntityManager em;
@Autowired
JpaAttempt jpaAttempt;
@MockBean
HttpServletRequest request;
Set<HsOfficeDebitorEntity> tempDebitors = new HashSet<>();
@Nested
class CreateDebitor {
@Test
public void testHostsharingAdmin_withoutAssumedRole_canCreateNewDebitor() {
// given
context("superuser-alex@hostsharing.net");
final var count = debitorRepo.count();
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("First GmbH").get(0);
final var givenContact = contactRepo.findContactByOptionalLabelLike("first contact").get(0);
// when
final var result = attempt(em, () -> {
final var newDebitor = toCleanup(HsOfficeDebitorEntity.builder()
.uuid(UUID.randomUUID())
.debitorNumber(20001)
.partner(rawReference(givenPartner))
.billingContact(rawReference(givenContact))
.build());
return debitorRepo.save(newDebitor);
});
// then
result.assertSuccessful();
assertThat(result.returnedValue()).isNotNull().extracting(HsOfficeDebitorEntity::getUuid).isNotNull();
assertThatDebitorIsPersisted(result.returnedValue());
assertThat(debitorRepo.count()).isEqualTo(count + 1);
}
@Test
public void createsAndGrantsRoles() {
// given
context("superuser-alex@hostsharing.net");
final var initialRoleNames = roleNamesOf(rawRoleRepo.findAll());
final var initialGrantNames = grantDisplaysOf(rawGrantRepo.findAll());
// when
attempt(em, () -> {
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("Fourth").get(0);
final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0);
final var newDebitor = toCleanup(HsOfficeDebitorEntity.builder()
.uuid(UUID.randomUUID())
.debitorNumber(20002)
.partner(rawReference(givenPartner))
.billingContact(rawReference(givenContact))
.build());
return debitorRepo.save(newDebitor);
}).assertSuccessful();
// then
assertThat(roleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from(
initialRoleNames,
"hs_office_debitor#20002Fourthe.G.-forthcontact.admin",
"hs_office_debitor#20002Fourthe.G.-forthcontact.owner",
"hs_office_debitor#20002Fourthe.G.-forthcontact.tenant"));
assertThat(grantDisplaysOf(rawGrantRepo.findAll())).containsExactlyInAnyOrder(Array.fromSkippingNull(
initialGrantNames,
"{ grant perm * on hs_office_debitor#20002Fourthe.G.-forthcontact to role hs_office_debitor#20002Fourthe.G.-forthcontact.owner by system and assume }",
"{ grant role hs_office_debitor#20002Fourthe.G.-forthcontact.owner to role global#global.admin by system and assume }",
"{ grant perm edit on hs_office_debitor#20002Fourthe.G.-forthcontact to role hs_office_debitor#20002Fourthe.G.-forthcontact.admin by system and assume }",
"{ grant role hs_office_debitor#20002Fourthe.G.-forthcontact.admin to role hs_office_debitor#20002Fourthe.G.-forthcontact.owner by system and assume }",
"{ grant perm view on hs_office_debitor#20002Fourthe.G.-forthcontact to role hs_office_debitor#20002Fourthe.G.-forthcontact.tenant by system and assume }",
"{ grant role hs_office_debitor#20002Fourthe.G.-forthcontact.tenant to role hs_office_contact#forthcontact.admin by system and assume }",
"{ grant role hs_office_debitor#20002Fourthe.G.-forthcontact.tenant to role hs_office_debitor#20002Fourthe.G.-forthcontact.admin by system and assume }",
"{ grant role hs_office_debitor#20002Fourthe.G.-forthcontact.tenant to role hs_office_partner#Fourthe.G.-forthcontact.admin by system and assume }",
"{ grant role hs_office_debitor#20002Fourthe.G.-forthcontact.tenant to role hs_office_person#Fourthe.G..admin by system and assume }",
"{ grant role hs_office_partner#Fourthe.G.-forthcontact.tenant to role hs_office_debitor#20002Fourthe.G.-forthcontact.tenant by system and assume }",
"{ grant role hs_office_contact#forthcontact.tenant to role hs_office_debitor#20002Fourthe.G.-forthcontact.tenant by system and assume }",
"{ grant role hs_office_person#Fourthe.G..tenant to role hs_office_debitor#20002Fourthe.G.-forthcontact.tenant by system and assume }",
null));
}
private void assertThatDebitorIsPersisted(final HsOfficeDebitorEntity saved) {
final var found = debitorRepo.findByUuid(saved.getUuid());
assertThat(found).isNotEmpty().get().usingRecursiveComparison().isEqualTo(saved);
}
}
@Nested
class FindByOptionalName {
@Test
public void globalAdmin_withoutAssumedRole_canViewAllDebitors() {
// given
context("superuser-alex@hostsharing.net");
// when
final var result = debitorRepo.findDebitorByOptionalNameLike(null);
// then
allTheseDebitorsAreReturned(
result,
"debitor(10001: First GmbH)",
"debitor(10002: Second e.K.)",
"debitor(10003: Third OHG)");
}
@ParameterizedTest
@ValueSource(strings = {
"hs_office_partner#FirstGmbH-firstcontact.admin",
"hs_office_person#FirstGmbH.admin",
"hs_office_contact#firstcontact.admin",
})
public void relatedPersonAdmin_canViewRelatedDebitors(final String assumedRole) {
// given:
context("superuser-alex@hostsharing.net", assumedRole);
// when:
final var result = debitorRepo.findDebitorByOptionalNameLike(null);
// then:
exactlyTheseDebitorsAreReturned(result, "debitor(10001: First GmbH)");
}
@Test
public void unrelatedUser_canNotViewAnyDebitor() {
// given:
context("selfregistered-test-user@hostsharing.org");
// when:
final var result = debitorRepo.findDebitorByOptionalNameLike(null);
// then:
assertThat(result).isEmpty();
}
}
@Nested
class FindByDebitorNumberLike {
@Test
public void globalAdmin_withoutAssumedRole_canViewAllDebitors() {
// given
context("superuser-alex@hostsharing.net");
// when
final var result = debitorRepo.findDebitorByDebitorNumber(10003);
// then
exactlyTheseDebitorsAreReturned(result, "debitor(10003: Third OHG)");
}
}
@Nested
class FindByNameLike {
@Test
public void globalAdmin_withoutAssumedRole_canViewAllDebitors() {
// given
context("superuser-alex@hostsharing.net");
// when
final var result = debitorRepo.findDebitorByOptionalNameLike("third contact");
// then
exactlyTheseDebitorsAreReturned(result, "debitor(10003: Third OHG)");
}
}
@Nested
class UpdateDebitor {
@Test
public void hostsharingAdmin_withoutAssumedRole_canUpdateArbitraryDebitor() {
// given
context("superuser-alex@hostsharing.net");
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "fifth contact");
assertThatDebitorIsVisibleForUserWithRole(
givenDebitor,
"hs_office_partner#Fourthe.G.-forthcontact.admin");
assertThatDebitorActuallyInDatabase(givenDebitor);
final var givenNewContact = contactRepo.findContactByOptionalLabelLike("sixth contact").get(0);
final String givenNewVatId = "NEW-VAT-ID";
final String givenNewVatCountryCode = "NC";
final boolean givenNewVatBusiness = !givenDebitor.isVatBusiness();
// when
final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
givenDebitor.setBillingContact(rawReference(givenNewContact));
givenDebitor.setVatId(givenNewVatId);
givenDebitor.setVatCountryCode(givenNewVatCountryCode);
givenDebitor.setVatBusiness(givenNewVatBusiness);
return toCleanup(debitorRepo.save(givenDebitor));
});
// then
result.assertSuccessful();
assertThatDebitorIsVisibleForUserWithRole(
result.returnedValue(),
"global#global.admin");
assertThatDebitorIsVisibleForUserWithRole(
result.returnedValue(),
"hs_office_contact#sixthcontact.admin");
assertThatDebitorIsNotVisibleForUserWithRole(
result.returnedValue(),
"hs_office_contact#fifthcontact.admin");
}
@Test
public void partnerAdmin_canNotUpdateRelatedDebitor() {
// given
context("superuser-alex@hostsharing.net");
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "eighth");
assertThatDebitorIsVisibleForUserWithRole(
givenDebitor,
"hs_office_partner#Fourthe.G.-forthcontact.admin");
assertThatDebitorActuallyInDatabase(givenDebitor);
// when
final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", "hs_office_partner#Fourthe.G.-forthcontact.admin");
givenDebitor.setVatId("NEW-VAT-ID");
return debitorRepo.save(givenDebitor);
});
// then
result.assertExceptionWithRootCauseMessage(JpaSystemException.class,
"[403] Subject ", " is not allowed to update hs_office_debitor uuid");
}
@Test
public void contactAdmin_canNotUpdateRelatedDebitor() {
// given
context("superuser-alex@hostsharing.net");
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "ninth");
assertThatDebitorIsVisibleForUserWithRole(
givenDebitor,
"hs_office_contact#ninthcontact.admin");
assertThatDebitorActuallyInDatabase(givenDebitor);
// when
final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", "hs_office_contact#ninthcontact.admin");
givenDebitor.setVatId("NEW-VAT-ID");
return debitorRepo.save(givenDebitor);
});
// then
result.assertExceptionWithRootCauseMessage(JpaSystemException.class,
"[403] Subject ", " is not allowed to update hs_office_debitor uuid");
}
private void assertThatDebitorActuallyInDatabase(final HsOfficeDebitorEntity saved) {
final var found = debitorRepo.findByUuid(saved.getUuid());
assertThat(found).isNotEmpty().get().isNotSameAs(saved).usingRecursiveComparison().isEqualTo(saved);
}
private void assertThatDebitorIsVisibleForUserWithRole(
final HsOfficeDebitorEntity entity,
final String assumedRoles) {
jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", assumedRoles);
assertThatDebitorActuallyInDatabase(entity);
}).assertSuccessful();
}
private void assertThatDebitorIsNotVisibleForUserWithRole(
final HsOfficeDebitorEntity entity,
final String assumedRoles) {
jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", assumedRoles);
final var found = debitorRepo.findByUuid(entity.getUuid());
assertThat(found).isEmpty();
}).assertSuccessful();
}
}
@Nested
class DeleteByUuid {
@Test
public void globalAdmin_withoutAssumedRole_canDeleteAnyDebitor() {
// given
context("superuser-alex@hostsharing.net", null);
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "tenth");
// when
final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
debitorRepo.deleteByUuid(givenDebitor.getUuid());
});
// then
result.assertSuccessful();
assertThat(jpaAttempt.transacted(() -> {
context("superuser-fran@hostsharing.net", null);
return debitorRepo.findByUuid(givenDebitor.getUuid());
}).assertSuccessful().returnedValue()).isEmpty();
}
@Test
public void relatedPerson_canNotDeleteTheirRelatedDebitor() {
// given
context("superuser-alex@hostsharing.net", null);
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "eleventh");
// when
final var result = jpaAttempt.transacted(() -> {
context("person-Fourthe.G.@example.com");
assertThat(debitorRepo.findByUuid(givenDebitor.getUuid())).isPresent();
debitorRepo.deleteByUuid(givenDebitor.getUuid());
});
// then
result.assertExceptionWithRootCauseMessage(
JpaSystemException.class,
"[403] Subject ", " not allowed to delete hs_office_debitor");
assertThat(jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
return debitorRepo.findByUuid(givenDebitor.getUuid());
}).assertSuccessful().returnedValue()).isPresent(); // still there
}
@Test
public void deletingADebitorAlsoDeletesRelatedRolesAndGrants() {
// given
context("superuser-alex@hostsharing.net");
final var initialRoleNames = Array.from(roleNamesOf(rawRoleRepo.findAll()));
final var initialGrantNames = Array.from(grantDisplaysOf(rawGrantRepo.findAll()));
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "twelfth");
assertThat(rawRoleRepo.findAll().size()).as("precondition failed: unexpected number of roles created")
.isEqualTo(initialRoleNames.length + 3);
assertThat(rawGrantRepo.findAll().size()).as("precondition failed: unexpected number of grants created")
.isEqualTo(initialGrantNames.length + 12);
// when
final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
return debitorRepo.deleteByUuid(givenDebitor.getUuid());
});
// then
result.assertSuccessful();
assertThat(result.returnedValue()).isEqualTo(1);
assertThat(roleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(initialRoleNames);
assertThat(grantDisplaysOf(rawGrantRepo.findAll())).containsExactlyInAnyOrder(initialGrantNames);
}
}
private HsOfficePartnerEntity rawReference(final HsOfficePartnerEntity givenPartner) {
return em.getReference(HsOfficePartnerEntity.class, givenPartner.getUuid());
}
private HsOfficeContactEntity rawReference(final HsOfficeContactEntity givenContact) {
return em.getReference(HsOfficeContactEntity.class, givenContact.getUuid());
}
private HsOfficeDebitorEntity givenSomeTemporaryDebitor(final String partner, final String contact) {
return jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike(partner).get(0);
final var givenContact = contactRepo.findContactByOptionalLabelLike(contact).get(0);
final var newDebitor = HsOfficeDebitorEntity.builder()
.uuid(UUID.randomUUID())
.debitorNumber(20000)
.partner(rawReference(givenPartner))
.billingContact(rawReference(givenContact))
.build();
toCleanup(newDebitor);
return debitorRepo.save(newDebitor);
}).assertSuccessful().returnedValue();
}
private HsOfficeDebitorEntity toCleanup(final HsOfficeDebitorEntity tempDebitor) {
tempDebitors.add(tempDebitor);
return tempDebitor;
}
@AfterEach
void cleanup() {
context("superuser-alex@hostsharing.net", null);
tempDebitors.forEach(tempDebitor -> {
System.out.println("DELETING temporary debitor: " + tempDebitor.toString());
debitorRepo.deleteByUuid(tempDebitor.getUuid());
});
}
void exactlyTheseDebitorsAreReturned(final List<HsOfficeDebitorEntity> actualResult, final String... debitorNames) {
assertThat(actualResult)
.extracting(HsOfficeDebitorEntity::toString)
.containsExactlyInAnyOrder(debitorNames);
}
void allTheseDebitorsAreReturned(final List<HsOfficeDebitorEntity> actualResult, final String... debitorNames) {
assertThat(actualResult)
.extracting(HsOfficeDebitorEntity::toString)
.contains(debitorNames);
}
}

View File

@@ -87,6 +87,10 @@ class HsOfficePartnerControllerAcceptanceTest {
{
"person": { "tradeName": "Second e.K." },
"contact": { "label": "second contact" }
},
{
"person": { "personType": "SOLE_REPRESENTATION" },
"contact": { "label": "forth contact" }
}
]
"""));

View File

@@ -70,6 +70,30 @@ class HsOfficePersonControllerAcceptanceTest {
.body("", lenientlyEquals("""
[
{
"personType": "LEGAL",
"tradeName": "First GmbH",
"givenName": null,
"familyName": null
},
{
"personType": "LEGAL",
"tradeName": "Second e.K.",
"givenName": "Miller",
"familyName": "Sandra"
},
{
"personType": "SOLE_REPRESENTATION",
"tradeName": "Third OHG",
"givenName": null,
"familyName": null
},
{
"personType": "SOLE_REPRESENTATION",
"tradeName": "Fourth e.G.",
"givenName": null,
"familyName": null
},
{
"personType": "NATURAL",
"tradeName": null,
"givenName": "Anita",
@@ -81,24 +105,6 @@ class HsOfficePersonControllerAcceptanceTest {
"givenName": "Bessler",
"familyName": "Mel"
},
{
"personType": "LEGAL",
"tradeName": "First GmbH",
"givenName": null,
"familyName": null
},
{
"personType": "SOLE_REPRESENTATION",
"tradeName": "Third OHG",
"givenName": null,
"familyName": null
},
{
"personType": "LEGAL",
"tradeName": "Second e.K.",
"givenName": "Miller",
"familyName": "Sandra"
},
{
"personType": "NATURAL",
"tradeName": null,
@@ -406,7 +412,7 @@ class HsOfficePersonControllerAcceptanceTest {
final var entity = personRepo.findByUuid(uuid);
final var count = personRepo.deleteByUuid(uuid);
System.out.println("DELETED temporary person: " + uuid + (count > 0 ? " successful" : " failed") +
(" (" + entity.map(HsOfficePersonEntity::getDisplayName).orElse("null") + ")"));
(" (" + entity.map(hsOfficePersonEntity -> hsOfficePersonEntity.toShortString()).orElse("null") + ")"));
}).assertSuccessful();
});
}

View File

@@ -14,7 +14,7 @@ class HsOfficePersonEntityUnitTest {
.tradeName("some trade name")
.build();
final var actualDisplay = givenPersonEntity.getDisplayName();
final var actualDisplay = givenPersonEntity.toShortString();
assertThat(actualDisplay).isEqualTo("some trade name");
}
@@ -26,7 +26,7 @@ class HsOfficePersonEntityUnitTest {
.givenName("some given name")
.build();
final var actualDisplay = givenPersonEntity.getDisplayName();
final var actualDisplay = givenPersonEntity.toShortString();
assertThat(actualDisplay).isEqualTo("some family name, some given name");
}

View File

@@ -3,7 +3,9 @@ package net.hostsharing.hsadminng.hs.office.person;
import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.context.ContextBasedTest;
import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository;
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantRepository;
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRepository;
import net.hostsharing.test.Array;
import net.hostsharing.test.JpaAttempt;
import org.junit.jupiter.api.AfterEach;
@@ -266,7 +268,7 @@ class HsOfficePersonRepositoryIntegrationTest extends ContextBasedTest {
context("superuser-alex@hostsharing.net", null);
final var result = personRepo.findPersonByOptionalNameLike("some temporary person");
result.forEach(tempPerson -> {
System.out.println("DELETING temporary person: " + tempPerson.getDisplayName());
System.out.println("DELETING temporary person: " + tempPerson.toShortString());
personRepo.deleteByUuid(tempPerson.getUuid());
});
}
@@ -293,7 +295,7 @@ class HsOfficePersonRepositoryIntegrationTest extends ContextBasedTest {
void allThesePersonsAreReturned(final List<HsOfficePersonEntity> actualResult, final String... personLabels) {
assertThat(actualResult)
.extracting(HsOfficePersonEntity::getDisplayName)
.extracting(hsOfficePersonEntity -> hsOfficePersonEntity.toShortString())
.contains(personLabels);
}
}