avoid select before insert and map sub-entities in mapper
| | |
| | | |
| | | static String firstMessageLine(final Throwable exception) { |
| | | if (exception.getMessage() != null) { |
| | | return firstLine(exception.getMessage()); |
| | | return line(exception.getMessage(), 0); |
| | | } |
| | | return "ERROR: [500] " + exception.getClass().getName(); |
| | | } |
| | | |
| | | static String firstLine(final String message) { |
| | | return message.split("\\r|\\n|\\r\\n", 0)[0]; |
| | | static String line(final String message, final int lineNo) { |
| | | return message.split("\\r|\\n|\\r\\n", 0)[lineNo]; |
| | | } |
| | | |
| | | @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss") |
| | |
| | | protected ResponseEntity<CustomErrorResponse> handleConflict( |
| | | final RuntimeException exc, final WebRequest request) { |
| | | |
| | | final var message = firstLine(NestedExceptionUtils.getMostSpecificCause(exc).getMessage()); |
| | | final var rawMessage = NestedExceptionUtils.getMostSpecificCause(exc).getMessage(); |
| | | var message = line(rawMessage, 0); |
| | | if (message.contains("violates foreign key constraint")) { |
| | | return errorResponse(request, HttpStatus.BAD_REQUEST, line(rawMessage, 1).replaceAll(" *Detail: *", "")); |
| | | } |
| | | return errorResponse(request, HttpStatus.CONFLICT, message); |
| | | } |
| | | |
| | | @ExceptionHandler(JpaSystemException.class) |
| | | protected ResponseEntity<CustomErrorResponse> handleJpaExceptions( |
| | | final RuntimeException exc, final WebRequest request) { |
| | | final var message = firstLine(NestedExceptionUtils.getMostSpecificCause(exc).getMessage()); |
| | | final var message = line(NestedExceptionUtils.getMostSpecificCause(exc).getMessage(), 0); |
| | | return errorResponse(request, httpStatus(message).orElse(HttpStatus.INTERNAL_SERVER_ERROR), message); |
| | | } |
| | | |
| | | @ExceptionHandler(NoSuchElementException.class) |
| | | protected ResponseEntity<CustomErrorResponse> handleNoSuchElementException( |
| | | final RuntimeException exc, final WebRequest request) { |
| | | final var message = firstLine(NestedExceptionUtils.getMostSpecificCause(exc).getMessage()); |
| | | final var message = line(NestedExceptionUtils.getMostSpecificCause(exc).getMessage(), 0); |
| | | return errorResponse(request, HttpStatus.NOT_FOUND, message); |
| | | } |
| | | |
| | |
| | | final RuntimeException exc, final WebRequest request) { |
| | | final var message = |
| | | userReadableEntityClassName( |
| | | firstLine(NestedExceptionUtils.getMostSpecificCause(exc).getMessage())); |
| | | line(NestedExceptionUtils.getMostSpecificCause(exc).getMessage(), 0)); |
| | | return errorResponse(request, HttpStatus.BAD_REQUEST, message); |
| | | } |
| | | |
| | | @ExceptionHandler({ Iban4jException.class, ValidationException.class }) |
| | | protected ResponseEntity<CustomErrorResponse> handleIbanAndBicExceptions( |
| | | final Throwable exc, final WebRequest request) { |
| | | final var message = firstLine(NestedExceptionUtils.getMostSpecificCause(exc).getMessage()); |
| | | final var message = line(NestedExceptionUtils.getMostSpecificCause(exc).getMessage(), 0); |
| | | return errorResponse(request, HttpStatus.BAD_REQUEST, message); |
| | | } |
| | | |
| | |
| | | BicUtil.validate(body.getBic()); |
| | | |
| | | final var entityToSave = mapper.map(body, HsOfficeBankAccountEntity.class); |
| | | entityToSave.setUuid(UUID.randomUUID()); |
| | | |
| | | final var saved = bankAccountRepo.save(entityToSave); |
| | | |
| | | final var uri = |
| | | MvcUriComponentsBuilder.fromController(getClass()) |
| | | .path("/api/hs/office/BankAccounts/{id}") |
| | | .buildAndExpand(entityToSave.getUuid()) |
| | | .path("/api/hs/office/bankaccounts/{id}") |
| | | .buildAndExpand(saved.getUuid()) |
| | | .toUri(); |
| | | final var mapped = mapper.map(saved, HsOfficeBankAccountResource.class); |
| | | return ResponseEntity.created(uri).body(mapped); |
| | |
| | | |
| | | import lombok.*; |
| | | import lombok.experimental.FieldNameConstants; |
| | | import net.hostsharing.hsadminng.errors.DisplayName; |
| | | import net.hostsharing.hsadminng.stringify.Stringify; |
| | | import net.hostsharing.hsadminng.stringify.Stringifyable; |
| | | import net.hostsharing.hsadminng.errors.DisplayName; |
| | | import org.hibernate.annotations.GenericGenerator; |
| | | |
| | | import javax.persistence.Entity; |
| | | import javax.persistence.GeneratedValue; |
| | | import javax.persistence.Id; |
| | | import javax.persistence.Table; |
| | | import java.util.UUID; |
| | |
| | | .withProp(Fields.iban, HsOfficeBankAccountEntity::getIban) |
| | | .withProp(Fields.bic, HsOfficeBankAccountEntity::getBic); |
| | | |
| | | private @Id UUID uuid; |
| | | @Id |
| | | @GeneratedValue(generator = "UUID") |
| | | @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") |
| | | private UUID uuid; |
| | | private String holder; |
| | | |
| | | private String iban; |
| | |
| | | context.define(currentUser, assumedRoles); |
| | | |
| | | final var entityToSave = mapper.map(body, HsOfficeContactEntity.class); |
| | | entityToSave.setUuid(UUID.randomUUID()); |
| | | |
| | | final var saved = contactRepo.save(entityToSave); |
| | | |
| | | final var uri = |
| | | MvcUriComponentsBuilder.fromController(getClass()) |
| | | .path("/api/hs/office/contacts/{id}") |
| | | .buildAndExpand(entityToSave.getUuid()) |
| | | .buildAndExpand(saved.getUuid()) |
| | | .toUri(); |
| | | final var mapped = mapper.map(saved, HsOfficeContactResource.class); |
| | | return ResponseEntity.created(uri).body(mapped); |
| | |
| | | import net.hostsharing.hsadminng.errors.DisplayName; |
| | | import net.hostsharing.hsadminng.stringify.Stringify; |
| | | import net.hostsharing.hsadminng.stringify.Stringifyable; |
| | | import org.hibernate.annotations.GenericGenerator; |
| | | |
| | | import javax.persistence.Column; |
| | | import javax.persistence.Entity; |
| | | import javax.persistence.Id; |
| | | import javax.persistence.Table; |
| | | import javax.persistence.*; |
| | | import java.util.UUID; |
| | | |
| | | import static net.hostsharing.hsadminng.stringify.Stringify.stringify; |
| | |
| | | .withProp(Fields.label, HsOfficeContactEntity::getLabel) |
| | | .withProp(Fields.emailAddresses, HsOfficeContactEntity::getEmailAddresses); |
| | | |
| | | private @Id UUID uuid; |
| | | |
| | | @Id |
| | | @GeneratedValue(generator = "UUID") |
| | | @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") |
| | | private UUID uuid; |
| | | private String label; |
| | | |
| | | @Column(name = "postaladdress") |
| | |
| | | validate(requestBody); |
| | | |
| | | final var entityToSave = mapper.map(requestBody, HsOfficeCoopAssetsTransactionEntity.class); |
| | | entityToSave.setUuid(UUID.randomUUID()); |
| | | |
| | | final var saved = coopAssetsTransactionRepo.save(entityToSave); |
| | | |
| | | final var uri = |
| | | MvcUriComponentsBuilder.fromController(getClass()) |
| | | .path("/api/hs/office/coopassetstransactions/{id}") |
| | | .buildAndExpand(entityToSave.getUuid()) |
| | | .buildAndExpand(saved.getUuid()) |
| | | .toUri(); |
| | | final var mapped = mapper.map(saved, HsOfficeCoopAssetsTransactionResource.class); |
| | | return ResponseEntity.created(uri).body(mapped); |
| | |
| | | import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity; |
| | | import net.hostsharing.hsadminng.stringify.Stringify; |
| | | import net.hostsharing.hsadminng.stringify.Stringifyable; |
| | | import org.hibernate.annotations.GenericGenerator; |
| | | import org.hibernate.annotations.Type; |
| | | import org.hibernate.annotations.TypeDef; |
| | | |
| | |
| | | .withSeparator(", ") |
| | | .quotedValues(false); |
| | | |
| | | private @Id UUID uuid; |
| | | @Id |
| | | @GeneratedValue(generator = "UUID") |
| | | @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") |
| | | private UUID uuid; |
| | | |
| | | @ManyToOne |
| | | @JoinColumn(name = "membershipuuid") |
| | |
| | | validate(requestBody); |
| | | |
| | | final var entityToSave = mapper.map(requestBody, HsOfficeCoopSharesTransactionEntity.class); |
| | | entityToSave.setUuid(UUID.randomUUID()); |
| | | |
| | | final var saved = coopSharesTransactionRepo.save(entityToSave); |
| | | |
| | | final var uri = |
| | | MvcUriComponentsBuilder.fromController(getClass()) |
| | | .path("/api/hs/office/coopsharestransactions/{id}") |
| | | .buildAndExpand(entityToSave.getUuid()) |
| | | .buildAndExpand(saved.getUuid()) |
| | | .toUri(); |
| | | final var mapped = mapper.map(saved, HsOfficeCoopSharesTransactionResource.class); |
| | | return ResponseEntity.created(uri).body(mapped); |
| | |
| | | import net.hostsharing.hsadminng.stringify.Stringifyable; |
| | | import net.hostsharing.hsadminng.errors.DisplayName; |
| | | import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity; |
| | | import org.hibernate.annotations.GenericGenerator; |
| | | import org.hibernate.annotations.Type; |
| | | import org.hibernate.annotations.TypeDef; |
| | | |
| | |
| | | .withSeparator(", ") |
| | | .quotedValues(false); |
| | | |
| | | private @Id UUID uuid; |
| | | @Id |
| | | @GeneratedValue(generator = "UUID") |
| | | @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") |
| | | private UUID uuid; |
| | | |
| | | @ManyToOne |
| | | @JoinColumn(name = "membershipuuid") |
| | |
| | | context.define(currentUser, assumedRoles); |
| | | |
| | | final var entityToSave = mapper.map(body, HsOfficeDebitorEntity.class); |
| | | entityToSave.setUuid(UUID.randomUUID()); |
| | | |
| | | final var saved = debitorRepo.save(entityToSave); |
| | | |
| | | final var uri = |
| | | MvcUriComponentsBuilder.fromController(getClass()) |
| | | .path("/api/hs/office/debitors/{id}") |
| | | .buildAndExpand(entityToSave.getUuid()) |
| | | .buildAndExpand(saved.getUuid()) |
| | | .toUri(); |
| | | final var mapped = mapper.map(saved, HsOfficeDebitorResource.class); |
| | | return ResponseEntity.created(uri).body(mapped); |
| | |
| | | import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity; |
| | | import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity; |
| | | import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity; |
| | | import org.hibernate.annotations.GenericGenerator; |
| | | |
| | | import javax.persistence.*; |
| | | import java.util.UUID; |
| | |
| | | .withSeparator(": ") |
| | | .quotedValues(false); |
| | | |
| | | private @Id UUID uuid; |
| | | @Id |
| | | @GeneratedValue(generator = "UUID") |
| | | @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") |
| | | private UUID uuid; |
| | | |
| | | @ManyToOne |
| | | @JoinColumn(name = "partneruuid") |
| | | private HsOfficePartnerEntity partner; |
| | | |
| | | private @Column(name = "debitornumber") Integer debitorNumber; |
| | | @Column(name = "debitornumber") |
| | | private Integer debitorNumber; |
| | | |
| | | @ManyToOne |
| | | @JoinColumn(name = "billingcontactuuid") |
| | | private HsOfficeContactEntity billingContact; |
| | | |
| | | private @Column(name = "vatid") String vatId; |
| | | private @Column(name = "vatcountrycode") String vatCountryCode; |
| | | private @Column(name = "vatbusiness") boolean vatBusiness; |
| | | @Column(name = "vatid") |
| | | private String vatId; |
| | | |
| | | @Column(name = "vatcountrycode") |
| | | private String vatCountryCode; |
| | | |
| | | @Column(name = "vatbusiness") |
| | | private boolean vatBusiness; |
| | | |
| | | @ManyToOne |
| | | @JoinColumn(name = "refundbankaccountuuid") |
| | | private HsOfficeBankAccountEntity refundBankAccount; |
| | | |
| | | |
| | | @Override |
| | | public String toString() { |
| | |
| | | context.define(currentUser, assumedRoles); |
| | | |
| | | final var entityToSave = mapper.map(body, HsOfficeMembershipEntity.class); |
| | | entityToSave.setUuid(UUID.randomUUID()); |
| | | |
| | | final var saved = membershipRepo.save(entityToSave); |
| | | |
| | | final var uri = |
| | | MvcUriComponentsBuilder.fromController(getClass()) |
| | | .path("/api/hs/office/Memberships/{id}") |
| | | .buildAndExpand(entityToSave.getUuid()) |
| | | .path("/api/hs/office/memberships/{id}") |
| | | .buildAndExpand(saved.getUuid()) |
| | | .toUri(); |
| | | final var mapped = mapper.map(saved, HsOfficeMembershipResource.class, |
| | | SEPA_MANDATE_ENTITY_TO_RESOURCE_POSTMAPPER); |
| | |
| | | import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity; |
| | | import net.hostsharing.hsadminng.stringify.Stringify; |
| | | import net.hostsharing.hsadminng.stringify.Stringifyable; |
| | | import org.hibernate.annotations.Fetch; |
| | | import org.hibernate.annotations.FetchMode; |
| | | import org.hibernate.annotations.Type; |
| | | import org.hibernate.annotations.TypeDef; |
| | | import org.hibernate.annotations.*; |
| | | |
| | | import javax.persistence.*; |
| | | import javax.persistence.Entity; |
| | | import javax.persistence.Table; |
| | | import java.time.LocalDate; |
| | | import java.util.UUID; |
| | | |
| | |
| | | .withSeparator(", ") |
| | | .quotedValues(false); |
| | | |
| | | private @Id UUID uuid; |
| | | @Id |
| | | @GeneratedValue(generator = "UUID") |
| | | @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") |
| | | private UUID uuid; |
| | | |
| | | @ManyToOne |
| | | @JoinColumn(name = "partneruuid") |
| | |
| | | private int memberNumber; |
| | | |
| | | @Column(name = "validity", columnDefinition = "daterange") |
| | | private Range<LocalDate> validity = Range.infinite(LocalDate.class); |
| | | private Range<LocalDate> validity; |
| | | |
| | | @Column(name = "reasonfortermination") |
| | | @Enumerated(EnumType.STRING) |
| | |
| | | validity = toPostgresDateRange(getValidity().lower(), validTo); |
| | | } |
| | | |
| | | public Range<LocalDate> getValidity() { |
| | | if ( validity == null ) { |
| | | validity = Range.infinite(LocalDate.class); |
| | | }; |
| | | return validity; |
| | | } |
| | | |
| | | @Override |
| | | public String toString() { |
| | | return stringify.apply(this); |
| | |
| | | package net.hostsharing.hsadminng.hs.office.partner; |
| | | |
| | | import net.hostsharing.hsadminng.context.Context; |
| | | import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity; |
| | | import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficePartnersApi; |
| | | import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerInsertResource; |
| | | import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerPatchResource; |
| | |
| | | context.define(currentUser, assumedRoles); |
| | | |
| | | final var entityToSave = mapper.map(body, HsOfficePartnerEntity.class); |
| | | entityToSave.setUuid(UUID.randomUUID()); |
| | | entityToSave.setDetails(mapper.map(body.getDetails(), HsOfficePartnerDetailsEntity.class)); |
| | | entityToSave.getDetails().setUuid(UUID.randomUUID()); |
| | | |
| | | final var saved = partnerRepo.save(entityToSave); |
| | | |
| | | final var uri = |
| | | MvcUriComponentsBuilder.fromController(getClass()) |
| | | .path("/api/hs/office/partners/{id}") |
| | | .buildAndExpand(entityToSave.getUuid()) |
| | | .buildAndExpand(saved.getUuid()) |
| | | .toUri(); |
| | | final var mapped = mapper.map(saved, HsOfficePartnerResource.class); |
| | | return ResponseEntity.created(uri).body(mapped); |
| | |
| | | import net.hostsharing.hsadminng.stringify.Stringify; |
| | | import net.hostsharing.hsadminng.stringify.Stringifyable; |
| | | import net.hostsharing.hsadminng.errors.DisplayName; |
| | | import org.hibernate.annotations.GenericGenerator; |
| | | |
| | | import javax.persistence.Column; |
| | | import javax.persistence.Entity; |
| | | import javax.persistence.Id; |
| | | import javax.persistence.Table; |
| | | import javax.persistence.*; |
| | | import java.time.LocalDate; |
| | | import java.util.UUID; |
| | | |
| | |
| | | .withSeparator(", ") |
| | | .quotedValues(false); |
| | | |
| | | private @Id UUID uuid; |
| | | @Id |
| | | @GeneratedValue(generator = "UUID") |
| | | @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") |
| | | private UUID uuid; |
| | | |
| | | private @Column(name = "registrationoffice") String registrationOffice; |
| | | private @Column(name = "registrationnumber") String registrationNumber; |
| | |
| | | import net.hostsharing.hsadminng.stringify.Stringifyable; |
| | | import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity; |
| | | import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity; |
| | | import org.hibernate.annotations.GenericGenerator; |
| | | import org.hibernate.annotations.NotFound; |
| | | import org.hibernate.annotations.NotFoundAction; |
| | | |
| | |
| | | .withSeparator(": ") |
| | | .quotedValues(false); |
| | | |
| | | private @Id UUID uuid; |
| | | @Id |
| | | @GeneratedValue(generator = "UUID") |
| | | @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") |
| | | private UUID uuid; |
| | | |
| | | @ManyToOne |
| | | @JoinColumn(name = "personuuid", nullable = false) |
| | |
| | | context.define(currentUser, assumedRoles); |
| | | |
| | | final var entityToSave = mapper.map(body, HsOfficePersonEntity.class); |
| | | entityToSave.setUuid(UUID.randomUUID()); |
| | | |
| | | final var saved = personRepo.save(entityToSave); |
| | | |
| | | final var uri = |
| | | MvcUriComponentsBuilder.fromController(getClass()) |
| | | .path("/api/hs/office/persons/{id}") |
| | | .buildAndExpand(entityToSave.getUuid()) |
| | | .buildAndExpand(saved.getUuid()) |
| | | .toUri(); |
| | | final var mapped = mapper.map(saved, HsOfficePersonResource.class); |
| | | return ResponseEntity.created(uri).body(mapped); |
| | |
| | | import net.hostsharing.hsadminng.stringify.Stringify; |
| | | import net.hostsharing.hsadminng.stringify.Stringifyable; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.hibernate.annotations.GenericGenerator; |
| | | import org.hibernate.annotations.Type; |
| | | import org.hibernate.annotations.TypeDef; |
| | | |
| | |
| | | .withProp(Fields.familyName, HsOfficePersonEntity::getFamilyName) |
| | | .withProp(Fields.givenName, HsOfficePersonEntity::getGivenName); |
| | | |
| | | private @Id UUID uuid; |
| | | @Id |
| | | @GeneratedValue(generator = "UUID") |
| | | @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") |
| | | private UUID uuid; |
| | | |
| | | @Column(name = "persontype") |
| | | @Enumerated(EnumType.STRING) |
| | |
| | | |
| | | final var entityToSave = new HsOfficeRelationshipEntity(); |
| | | entityToSave.setRelType(HsOfficeRelationshipType.valueOf(body.getRelType())); |
| | | entityToSave.setUuid(UUID.randomUUID()); |
| | | entityToSave.setRelAnchor(relHolderRepo.findByUuid(body.getRelAnchorUuid()).orElseThrow( |
| | | () -> new NoSuchElementException("cannot find relAnchorUuid " + body.getRelAnchorUuid()) |
| | | )); |
| | |
| | | final var uri = |
| | | MvcUriComponentsBuilder.fromController(getClass()) |
| | | .path("/api/hs/office/relationships/{id}") |
| | | .buildAndExpand(entityToSave.getUuid()) |
| | | .buildAndExpand(saved.getUuid()) |
| | | .toUri(); |
| | | final var mapped = mapper.map(saved, HsOfficeRelationshipResource.class, |
| | | RELATIONSHIP_ENTITY_TO_RESOURCE_POSTMAPPER); |
| | |
| | | import net.hostsharing.hsadminng.stringify.Stringify; |
| | | import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity; |
| | | import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity; |
| | | import org.hibernate.annotations.GenericGenerator; |
| | | import org.hibernate.annotations.Type; |
| | | import org.hibernate.annotations.TypeDef; |
| | | |
| | |
| | | .withProp(Fields.relHolder, HsOfficeRelationshipEntity::getRelHolder) |
| | | .withProp(Fields.contact, HsOfficeRelationshipEntity::getContact); |
| | | |
| | | private @Id UUID uuid; |
| | | @Id |
| | | @GeneratedValue(generator = "UUID") |
| | | @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") |
| | | private UUID uuid; |
| | | |
| | | @ManyToOne |
| | | @JoinColumn(name = "relanchoruuid") |
| | |
| | | package net.hostsharing.hsadminng.hs.office.sepamandate; |
| | | |
| | | import com.vladmihalcea.hibernate.type.range.Range; |
| | | import net.hostsharing.hsadminng.mapper.Mapper; |
| | | import net.hostsharing.hsadminng.context.Context; |
| | | import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeSepaMandatesApi; |
| | | import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeSepaMandateInsertResource; |
| | | import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeSepaMandatePatchResource; |
| | | import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeSepaMandateResource; |
| | | import net.hostsharing.hsadminng.mapper.Mapper; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | |
| | | context.define(currentUser, assumedRoles); |
| | | |
| | | final var entityToSave = mapper.map(body, HsOfficeSepaMandateEntity.class, SEPA_MANDATE_RESOURCE_TO_ENTITY_POSTMAPPER); |
| | | entityToSave.setUuid(UUID.randomUUID()); |
| | | |
| | | final var saved = SepaMandateRepo.save(entityToSave); |
| | | |
| | | final var uri = |
| | | MvcUriComponentsBuilder.fromController(getClass()) |
| | | .path("/api/hs/office/SepaMandates/{id}") |
| | | .buildAndExpand(entityToSave.getUuid()) |
| | | .path("/api/hs/office/sepamandates/{id}") |
| | | .buildAndExpand(saved.getUuid()) |
| | | .toUri(); |
| | | final var mapped = mapper.map(saved, HsOfficeSepaMandateResource.class, |
| | | SEPA_MANDATE_ENTITY_TO_RESOURCE_POSTMAPPER); |
| | |
| | | import net.hostsharing.hsadminng.stringify.Stringifyable; |
| | | import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity; |
| | | import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity; |
| | | import org.hibernate.annotations.GenericGenerator; |
| | | import org.hibernate.annotations.TypeDef; |
| | | |
| | | import javax.persistence.*; |
| | |
| | | .withSeparator(", ") |
| | | .quotedValues(false); |
| | | |
| | | private @Id UUID uuid; |
| | | @Id |
| | | @GeneratedValue(generator = "UUID") |
| | | @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") |
| | | private UUID uuid; |
| | | |
| | | @ManyToOne |
| | | @JoinColumn(name = "debitoruuid") |
| | |
| | | package net.hostsharing.hsadminng.mapper; |
| | | |
| | | import net.hostsharing.hsadminng.errors.DisplayName; |
| | | import org.modelmapper.ModelMapper; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.util.ReflectionUtils; |
| | | |
| | | import javax.persistence.EntityManager; |
| | | import javax.persistence.ManyToOne; |
| | | import javax.validation.ValidationException; |
| | | import java.lang.reflect.Field; |
| | | import java.util.List; |
| | | import java.util.function.BiConsumer; |
| | | import java.util.stream.Collectors; |
| | |
| | | * A nicer API for ModelMapper. |
| | | */ |
| | | public class Mapper extends ModelMapper { |
| | | |
| | | @Autowired |
| | | EntityManager em; |
| | | |
| | | public Mapper() { |
| | | getConfiguration().setAmbiguityIgnored(true); |
| | |
| | | .collect(Collectors.toList()); |
| | | } |
| | | |
| | | @Override |
| | | public <D> D map(final Object source, final Class<D> destinationType) { |
| | | final var target = super.map(source, destinationType); |
| | | for (Field f : destinationType.getDeclaredFields()) { |
| | | if (f.getAnnotation(ManyToOne.class) == null) { |
| | | continue; |
| | | } |
| | | ReflectionUtils.makeAccessible(f); |
| | | final var subEntity = ReflectionUtils.getField(f, target); |
| | | if (subEntity == null) { |
| | | continue; |
| | | } |
| | | final var subEntityUuidField = ReflectionUtils.findField(f.getType(), "uuid"); |
| | | if (subEntityUuidField == null) { |
| | | continue; |
| | | } |
| | | ReflectionUtils.makeAccessible(subEntityUuidField); |
| | | final var subEntityUuid = ReflectionUtils.getField(subEntityUuidField, subEntity); |
| | | if (subEntityUuid == null) { |
| | | continue; |
| | | } |
| | | ReflectionUtils.setField(f, target, findEntityById(f.getType(), subEntityUuid)); |
| | | } |
| | | return target; |
| | | } |
| | | |
| | | private Object findEntityById(final Class<?> entityClass, final Object subEntityUuid) { |
| | | // using getReference would be more efficent, but results in very technical error messages |
| | | final var entity = em.find(entityClass, subEntityUuid); |
| | | if (entity != null) { |
| | | return entity; |
| | | } |
| | | final var displayNameAnnot = entityClass.getAnnotation(DisplayName.class); |
| | | final var displayName = displayNameAnnot != null ? displayNameAnnot.value() : entityClass.getSimpleName(); |
| | | throw new ValidationException("Unable to find %s with uuid %s".formatted( |
| | | displayName, subEntityUuid |
| | | )); |
| | | } |
| | | |
| | | public <S, T> T map(final S source, final Class<T> targetClass, final BiConsumer<S, T> postMapper) { |
| | | if (source == null) { |
| | | return null; |
| | |
| | | |
| | | import lombok.*; |
| | | import org.hibernate.annotations.Formula; |
| | | import org.hibernate.annotations.GenericGenerator; |
| | | import org.springframework.data.annotation.Immutable; |
| | | |
| | | import javax.persistence.*; |
| | |
| | | public class RbacRoleEntity { |
| | | |
| | | @Id |
| | | @GeneratedValue(generator = "UUID") |
| | | @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") |
| | | private UUID uuid; |
| | | |
| | | @Column(name = "objectuuid") |
| | |
| | | package net.hostsharing.hsadminng.rbac.rbacuser; |
| | | |
| | | import lombok.*; |
| | | import org.hibernate.annotations.GenericGenerator; |
| | | import org.springframework.data.annotation.Immutable; |
| | | |
| | | import javax.persistence.Entity; |
| | | import javax.persistence.GeneratedValue; |
| | | import javax.persistence.Id; |
| | | import javax.persistence.Table; |
| | | import java.time.LocalDateTime; |
| | |
| | | private static DateTimeFormatter DATE_FORMAT_WITH_FULLHOUR = DateTimeFormatter.ofPattern("MM-dd-yyyy HH"); |
| | | |
| | | @Id |
| | | @GeneratedValue(generator = "UUID") |
| | | @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") |
| | | private UUID uuid; |
| | | |
| | | private String name; |
| | |
| | | |
| | | context.define(currentUser, assumedRoles); |
| | | |
| | | if (customer.getUuid() == null) { |
| | | customer.setUuid(UUID.randomUUID()); |
| | | } |
| | | |
| | | final var saved = testCustomerRepository.save(mapper.map(customer, TestCustomerEntity.class)); |
| | | |
| | | final var uri = |
| | | MvcUriComponentsBuilder.fromController(getClass()) |
| | | .path("/api/test/customers/{id}") |
| | | .buildAndExpand(customer.getUuid()) |
| | | .buildAndExpand(saved.getUuid()) |
| | | .toUri(); |
| | | return ResponseEntity.created(uri).body(mapper.map(saved, TestCustomerResource.class)); |
| | | } |
| | |
| | | import lombok.Getter; |
| | | import lombok.NoArgsConstructor; |
| | | import lombok.Setter; |
| | | import org.hibernate.annotations.GenericGenerator; |
| | | |
| | | import javax.persistence.*; |
| | | import java.util.UUID; |
| | |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class TestCustomerEntity { |
| | | private @Id UUID uuid; |
| | | @Id |
| | | @GeneratedValue(generator = "UUID") |
| | | @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") |
| | | private UUID uuid; |
| | | |
| | | private String prefix; |
| | | private int reference; |
| | | private @Column(name="adminusername")String adminUserName; |
| | | |
| | | @Column(name="adminusername") |
| | | private String adminUserName; |
| | | } |
| | |
| | | import lombok.NoArgsConstructor; |
| | | import lombok.Setter; |
| | | import net.hostsharing.hsadminng.test.cust.TestCustomerEntity; |
| | | import org.hibernate.annotations.GenericGenerator; |
| | | |
| | | import javax.persistence.*; |
| | | import java.util.UUID; |
| | |
| | | @AllArgsConstructor |
| | | public class TestPackageEntity { |
| | | |
| | | private @Id UUID uuid; |
| | | @Id |
| | | @GeneratedValue(generator = "UUID") |
| | | @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") |
| | | private UUID uuid; |
| | | |
| | | @Version |
| | | private int version; |
| | |
| | | import org.springframework.dao.DataIntegrityViolationException; |
| | | import org.springframework.http.HttpHeaders; |
| | | import org.springframework.http.HttpStatus; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.orm.jpa.JpaObjectRetrievalFailureException; |
| | | import org.springframework.orm.jpa.JpaSystemException; |
| | | import org.springframework.validation.BindingResult; |
| | |
| | | } |
| | | |
| | | @Test |
| | | void handleForeignKeyViolation() { |
| | | // given |
| | | final var givenException = new DataIntegrityViolationException(""" |
| | | ... violates foreign key constraint ... |
| | | Detail: Second Line |
| | | Third Line |
| | | """); |
| | | final var givenWebRequest = mock(WebRequest.class); |
| | | |
| | | // when |
| | | final var errorResponse = exceptionHandler.handleConflict(givenException, givenWebRequest); |
| | | |
| | | // then |
| | | assertThat(errorResponse.getStatusCodeValue()).isEqualTo(400); |
| | | assertThat(errorResponse.getBody()).isNotNull() |
| | | .extracting(CustomErrorResponse::getMessage).isEqualTo("Second Line"); |
| | | } |
| | | |
| | | @Test |
| | | void jpaExceptionWithKnownErrorCode() { |
| | | // given |
| | | final var givenException = new JpaSystemException(new RuntimeException( |
| | |
| | | |
| | | static public HsOfficeBankAccountEntity hsOfficeBankAccount(final String holder, final String iban, final String bic) { |
| | | return HsOfficeBankAccountEntity.builder() |
| | | .uuid(UUID.randomUUID()) |
| | | .holder(holder) |
| | | .iban(iban) |
| | | .bic(bic) |
| | |
| | | import org.springframework.boot.test.web.server.LocalServerPort; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.HashSet; |
| | | import java.util.Set; |
| | | import javax.persistence.EntityManager; |
| | | import java.util.UUID; |
| | | |
| | | import static net.hostsharing.test.IsValidUuidMatcher.isUuidValid; |
| | |
| | | @Autowired |
| | | JpaAttempt jpaAttempt; |
| | | |
| | | Set<UUID> tempContactUuids = new HashSet<>(); |
| | | @Autowired |
| | | EntityManager em; |
| | | |
| | | @Nested |
| | | @Accepts({ "Contact:F(Find)" }) |
| | |
| | | .contentType(ContentType.JSON) |
| | | .body(""" |
| | | { |
| | | "label": "Test Contact", |
| | | "label": "Temp Contact", |
| | | "emailAddresses": "test@example.org" |
| | | } |
| | | """) |
| | |
| | | .statusCode(201) |
| | | .contentType(ContentType.JSON) |
| | | .body("uuid", isUuidValid()) |
| | | .body("label", is("Test Contact")) |
| | | .body("label", is("Temp Contact")) |
| | | .body("emailAddresses", is("test@example.org")) |
| | | .header("Location", startsWith("http://localhost")) |
| | | .extract().header("Location"); // @formatter:on |
| | | |
| | | // finally, the new contact can be accessed under the generated UUID |
| | | final var newUserUuid = toCleanup(UUID.fromString( |
| | | location.substring(location.lastIndexOf('/') + 1))); |
| | | final var newUserUuid = UUID.fromString( |
| | | location.substring(location.lastIndexOf('/') + 1)); |
| | | assertThat(newUserUuid).isNotNull(); |
| | | } |
| | | } |
| | |
| | | .contentType(ContentType.JSON) |
| | | .body(""" |
| | | { |
| | | "label": "patched contact", |
| | | "label": "Temp patched contact", |
| | | "emailAddresses": "patched@example.org", |
| | | "postalAddress": "Patched Address", |
| | | "phoneNumbers": "+01 100 123456" |
| | |
| | | .statusCode(200) |
| | | .contentType(ContentType.JSON) |
| | | .body("uuid", isUuidValid()) |
| | | .body("label", is("patched contact")) |
| | | .body("label", is("Temp patched contact")) |
| | | .body("emailAddresses", is("patched@example.org")) |
| | | .body("postalAddress", is("Patched Address")) |
| | | .body("phoneNumbers", is("+01 100 123456")); |
| | |
| | | context.define("superuser-alex@hostsharing.net"); |
| | | assertThat(contactRepo.findByUuid(givenContact.getUuid())).isPresent().get() |
| | | .matches(person -> { |
| | | assertThat(person.getLabel()).isEqualTo("patched contact"); |
| | | assertThat(person.getLabel()).isEqualTo("Temp patched contact"); |
| | | assertThat(person.getEmailAddresses()).isEqualTo("patched@example.org"); |
| | | assertThat(person.getPostalAddress()).isEqualTo("Patched Address"); |
| | | assertThat(person.getPhoneNumbers()).isEqualTo("+01 100 123456"); |
| | |
| | | .phoneNumbers("+01 200 " + RandomStringUtils.randomNumeric(8)) |
| | | .build(); |
| | | |
| | | toCleanup(newContact.getUuid()); |
| | | |
| | | return contactRepo.save(newContact); |
| | | }).assertSuccessful().returnedValue(); |
| | | } |
| | | |
| | | private UUID toCleanup(final UUID tempContactUuid) { |
| | | tempContactUuids.add(tempContactUuid); |
| | | return tempContactUuid; |
| | | } |
| | | |
| | | @BeforeEach |
| | | @AfterEach |
| | | void cleanup() { |
| | | tempContactUuids.forEach(uuid -> { |
| | | jpaAttempt.transacted(() -> { |
| | | context.define("superuser-alex@hostsharing.net", null); |
| | | System.out.println("DELETING temporary contact: " + uuid); |
| | | final var count = contactRepo.deleteByUuid(uuid); |
| | | System.out.println("DELETED temporary contact: " + uuid + (count > 0 ? " successful" : " failed")); |
| | | }).assertSuccessful(); |
| | | }); |
| | | jpaAttempt.transacted(() -> { |
| | | context.define("superuser-alex@hostsharing.net", null); |
| | | em.createQuery("DELETE FROM HsOfficeContactEntity c WHERE c.label LIKE 'Temp %'").executeUpdate(); |
| | | }).assertSuccessful(); |
| | | } |
| | | |
| | | } |
| | |
| | | @MockBean |
| | | HttpServletRequest request; |
| | | |
| | | @Container |
| | | Container postgres; |
| | | |
| | | @Nested |
| | | class CreateContact { |
| | | |
| | |
| | | |
| | | static public HsOfficeContactEntity hsOfficeContact(final String label, final String emailAddr) { |
| | | return HsOfficeContactEntity.builder() |
| | | .uuid(UUID.randomUUID()) |
| | | .label(label) |
| | | .postalAddress("address of " + label) |
| | | .emailAddresses(emailAddr) |
| | |
| | | // when |
| | | final var result = attempt(em, () -> { |
| | | final var newCoopAssetsTransaction = HsOfficeCoopAssetsTransactionEntity.builder() |
| | | .uuid(UUID.randomUUID()) |
| | | .membership(givenMembership) |
| | | .transactionType(HsOfficeCoopAssetsTransactionType.DEPOSIT) |
| | | .assetValue(new BigDecimal("128.00")) |
| | |
| | | null, |
| | | 10001).get(0); |
| | | final var newCoopAssetsTransaction = HsOfficeCoopAssetsTransactionEntity.builder() |
| | | .uuid(UUID.randomUUID()) |
| | | .membership(givenMembership) |
| | | .transactionType(HsOfficeCoopAssetsTransactionType.DEPOSIT) |
| | | .assetValue(new BigDecimal("128.00")) |
| | |
| | | // when |
| | | final var result = attempt(em, () -> { |
| | | final var newCoopSharesTransaction = HsOfficeCoopSharesTransactionEntity.builder() |
| | | .uuid(UUID.randomUUID()) |
| | | .membership(givenMembership) |
| | | .transactionType(HsOfficeCoopSharesTransactionType.SUBSCRIPTION) |
| | | .shareCount(4) |
| | |
| | | null, |
| | | 10001).get(0); |
| | | final var newCoopSharesTransaction = HsOfficeCoopSharesTransactionEntity.builder() |
| | | .uuid(UUID.randomUUID()) |
| | | .membership(givenMembership) |
| | | .transactionType(HsOfficeCoopSharesTransactionType.SUBSCRIPTION) |
| | | .shareCount(4) |
| | |
| | | |
| | | import io.restassured.RestAssured; |
| | | import io.restassured.http.ContentType; |
| | | import net.hostsharing.test.Accepts; |
| | | import net.hostsharing.hsadminng.HsadminNgApplication; |
| | | import net.hostsharing.hsadminng.context.Context; |
| | | import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountRepository; |
| | | import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRepository; |
| | | import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository; |
| | | import net.hostsharing.test.Accepts; |
| | | import net.hostsharing.test.JpaAttempt; |
| | | import org.json.JSONException; |
| | | import org.junit.jupiter.api.AfterEach; |
| | | import org.junit.jupiter.api.BeforeEach; |
| | | import org.junit.jupiter.api.Nested; |
| | | import org.junit.jupiter.api.Test; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | |
| | | import org.springframework.boot.test.web.server.LocalServerPort; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.HashSet; |
| | | import java.util.Set; |
| | | import javax.persistence.EntityManager; |
| | | import java.util.UUID; |
| | | |
| | | import static net.hostsharing.test.IsValidUuidMatcher.isUuidValid; |
| | |
| | | @Transactional |
| | | class HsOfficeDebitorControllerAcceptanceTest { |
| | | |
| | | private static int nextDebitorNumber = 20001; |
| | | private static final int LOWEST_TEMP_DEBITOR_NUMBER = 20000; |
| | | private static int nextDebitorNumber = LOWEST_TEMP_DEBITOR_NUMBER; |
| | | |
| | | @LocalServerPort |
| | | private Integer port; |
| | |
| | | @Autowired |
| | | JpaAttempt jpaAttempt; |
| | | |
| | | Set<UUID> tempDebitorUuids = new HashSet<>(); |
| | | @Autowired |
| | | EntityManager em; |
| | | |
| | | @Nested |
| | | @Accepts({ "Debitor:F(Find)" }) |
| | |
| | | "vatBusiness": true, |
| | | "refundBankAccountUuid": "%s" |
| | | } |
| | | """.formatted( givenPartner.getUuid(), givenContact.getUuid(), nextDebitorNumber++, givenBankAccount.getUuid())) |
| | | """.formatted( givenPartner.getUuid(), givenContact.getUuid(), ++nextDebitorNumber, givenBankAccount.getUuid())) |
| | | .port(port) |
| | | .when() |
| | | .post("http://localhost/api/hs/office/debitors") |
| | |
| | | .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))); |
| | | final var newUserUuid = UUID.fromString( |
| | | location.substring(location.lastIndexOf('/') + 1)); |
| | | assertThat(newUserUuid).isNotNull(); |
| | | } |
| | | |
| | |
| | | "billingContactUuid": "%s", |
| | | "debitorNumber": "%s" |
| | | } |
| | | """.formatted( givenPartner.getUuid(), givenContact.getUuid(), nextDebitorNumber++)) |
| | | """.formatted( givenPartner.getUuid(), givenContact.getUuid(), ++nextDebitorNumber)) |
| | | .port(port) |
| | | .when() |
| | | .post("http://localhost/api/hs/office/debitors") |
| | |
| | | .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))); |
| | | final var newUserUuid = UUID.fromString( |
| | | location.substring(location.lastIndexOf('/') + 1)); |
| | | assertThat(newUserUuid).isNotNull(); |
| | | } |
| | | |
| | |
| | | "vatCountryCode": "DE", |
| | | "vatBusiness": true |
| | | } |
| | | """.formatted( givenPartner.getUuid(), givenContactUuid, nextDebitorNumber++)) |
| | | """.formatted( givenPartner.getUuid(), givenContactUuid, ++nextDebitorNumber)) |
| | | .port(port) |
| | | .when() |
| | | .post("http://localhost/api/hs/office/debitors") |
| | |
| | | "vatCountryCode": "DE", |
| | | "vatBusiness": true |
| | | } |
| | | """.formatted( givenPartnerUuid, givenContact.getUuid(), nextDebitorNumber++)) |
| | | """.formatted( givenPartnerUuid, givenContact.getUuid(), ++nextDebitorNumber)) |
| | | .port(port) |
| | | .when() |
| | | .post("http://localhost/api/hs/office/debitors") |
| | |
| | | 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++) |
| | | .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; |
| | | } |
| | | |
| | | @BeforeEach |
| | | @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")); |
| | | }); |
| | | jpaAttempt.transacted(() -> { |
| | | context.define("superuser-alex@hostsharing.net"); |
| | | final var count = em.createQuery( |
| | | "DELETE FROM HsOfficeDebitorEntity d WHERE d.debitorNumber > " + LOWEST_TEMP_DEBITOR_NUMBER) |
| | | .executeUpdate(); |
| | | System.out.printf("deleted %d entities%n", count); |
| | | }); |
| | | } |
| | | |
| | | } |
| | |
| | | // when |
| | | final var result = attempt(em, () -> { |
| | | final var newDebitor = HsOfficeDebitorEntity.builder() |
| | | .uuid(UUID.randomUUID()) |
| | | .debitorNumber(20001) |
| | | .partner(givenPartner) |
| | | .billingContact(givenContact) |
| | |
| | | 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(20002) |
| | | .partner(givenPartner) |
| | | .billingContact(givenContact) |
| | |
| | | final var givenBankAccount = |
| | | bankAccount != null ? bankAccountRepo.findByOptionalHolderLike(bankAccount).get(0) : null; |
| | | final var newDebitor = HsOfficeDebitorEntity.builder() |
| | | .uuid(UUID.randomUUID()) |
| | | .debitorNumber(20000) |
| | | .partner(givenPartner) |
| | | .billingContact(givenContact) |
| | |
| | | public class TestHsOfficeDebitor { |
| | | |
| | | public static final HsOfficeDebitorEntity TEST_DEBITOR = HsOfficeDebitorEntity.builder() |
| | | .uuid(UUID.randomUUID()) |
| | | .debitorNumber(10001) |
| | | .partner(TEST_PARTNER) |
| | | .billingContact(TEST_CONTACT) |
| | |
| | | |
| | | 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.Test; |
| | | import org.junit.runner.RunWith; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; |
| | | import org.springframework.boot.test.mock.mockito.MockBean; |
| | | import org.springframework.boot.test.mock.mockito.SpyBean; |
| | | import org.springframework.context.annotation.Import; |
| | | import org.springframework.http.MediaType; |
| | | import org.springframework.orm.jpa.JpaObjectRetrievalFailureException; |
| | | import org.springframework.test.context.junit4.SpringRunner; |
| | | import org.springframework.test.web.servlet.MockMvc; |
| | | import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; |
| | | |
| | | import javax.persistence.EntityManager; |
| | | import javax.persistence.EntityNotFoundException; |
| | | import java.util.UUID; |
| | | |
| | | 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; |
| | |
| | | } |
| | | |
| | | @Test |
| | | void respondBadRequest_ifAnyGivenUuidCannotBeResolved() throws Exception { |
| | | void respondBadRequest_ifAnyGivenPartnerUuidCannotBeFound() throws Exception { |
| | | |
| | | // given |
| | | when(membershipRepo.save(any())).thenThrow( |
| | | new JpaObjectRetrievalFailureException( |
| | | new EntityNotFoundException( |
| | | // same would happen with HsOfficePartnerEntity which could not be resolved |
| | | "Unable to find net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity with id ..."))); |
| | | 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 |
| | |
| | | "memberNumber": 20001, |
| | | "validFrom": "2022-10-13" |
| | | } |
| | | """.formatted(UUID.randomUUID(), UUID.randomUUID())) |
| | | """.formatted(givenPartnerUuid, givenMainDebitorUuid)) |
| | | .accept(MediaType.APPLICATION_JSON)) |
| | | |
| | | // then |
| | | .andExpect(status().is4xxClientError()) |
| | | .andExpect(jsonPath("status", is(400))) |
| | | .andExpect(jsonPath("error", is("Bad Request"))) |
| | | .andExpect(jsonPath("message", is("Unable to find Debitor with uuid ..."))); |
| | | .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", |
| | | "memberNumber": 20001, |
| | | "validFrom": "2022-10-13" |
| | | } |
| | | """.formatted(givenPartnerUuid, givenMainDebitorUuid)) |
| | | .accept(MediaType.APPLICATION_JSON)) |
| | | |
| | | // then |
| | | .andExpect(status().is4xxClientError()) |
| | | .andExpect(jsonPath("status", is(400))) |
| | | .andExpect(jsonPath("error", is("Bad Request"))) |
| | | .andExpect(jsonPath("message", is("Unable to find Debitor with uuid " + givenMainDebitorUuid))); |
| | | } |
| | | } |
| | |
| | | // when |
| | | final var result = attempt(em, () -> { |
| | | final var newMembership = toCleanup(HsOfficeMembershipEntity.builder() |
| | | .uuid(UUID.randomUUID()) |
| | | .memberNumber(20001) |
| | | .partner(givenPartner) |
| | | .mainDebitor(givenDebitor) |
| | |
| | | final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("First").get(0); |
| | | final var givenDebitor = debitorRepo.findDebitorByOptionalNameLike("First").get(0); |
| | | final var newMembership = toCleanup(HsOfficeMembershipEntity.builder() |
| | | .uuid(UUID.randomUUID()) |
| | | .memberNumber(20002) |
| | | .partner(givenPartner) |
| | | .mainDebitor(givenDebitor) |
| | |
| | | final var givenPartner = partnerRepo.findPartnerByOptionalNameLike(partnerTradeName).get(0); |
| | | final var givenDebitor = debitorRepo.findDebitorByOptionalNameLike(debitorName).get(0); |
| | | final var newMembership = HsOfficeMembershipEntity.builder() |
| | | .uuid(UUID.randomUUID()) |
| | | .memberNumber(20002) |
| | | .partner(givenPartner) |
| | | .mainDebitor(givenDebitor) |
| | |
| | | |
| | | public static final HsOfficeMembershipEntity TEST_MEMBERSHIP = |
| | | HsOfficeMembershipEntity.builder() |
| | | .uuid(UUID.randomUUID()) |
| | | .partner(TEST_PARTNER) |
| | | .memberNumber(300001) |
| | | .validity(Range.closedInfinite(LocalDate.parse("2020-01-01"))) |
| | |
| | | import org.springframework.boot.test.web.server.LocalServerPort; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.HashSet; |
| | | import java.util.Set; |
| | | import javax.persistence.EntityManager; |
| | | import java.util.UUID; |
| | | |
| | | import static net.hostsharing.test.IsValidUuidMatcher.isUuidValid; |
| | |
| | | webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, |
| | | classes = { HsadminNgApplication.class, JpaAttempt.class } |
| | | ) |
| | | @Transactional |
| | | class HsOfficePartnerControllerAcceptanceTest { |
| | | |
| | | @LocalServerPort |
| | |
| | | @Autowired |
| | | JpaAttempt jpaAttempt; |
| | | |
| | | Set<UUID> tempPartnerUuids = new HashSet<>(); |
| | | @Autowired |
| | | EntityManager em; |
| | | |
| | | @Nested |
| | | @Accepts({ "Partner:F(Find)" }) |
| | | @Transactional |
| | | class ListPartners { |
| | | |
| | | @Test |
| | |
| | | |
| | | @Nested |
| | | @Accepts({ "Partner:C(Create)" }) |
| | | @Transactional |
| | | class AddPartner { |
| | | |
| | | @Test |
| | |
| | | "contactUuid": "%s", |
| | | "personUuid": "%s", |
| | | "details": { |
| | | "registrationOffice": "Registergericht Aurich", |
| | | "registrationNumber": "123456" |
| | | "registrationOffice": "Temp Registergericht Aurich", |
| | | "registrationNumber": "111111" |
| | | } |
| | | } |
| | | """.formatted(givenContact.getUuid(), givenPerson.getUuid())) |
| | |
| | | .statusCode(201) |
| | | .contentType(ContentType.JSON) |
| | | .body("uuid", isUuidValid()) |
| | | .body("details.registrationOffice", is("Registergericht Aurich")) |
| | | .body("details.registrationNumber", is("123456")) |
| | | .body("details.registrationOffice", is("Temp Registergericht Aurich")) |
| | | .body("details.registrationNumber", is("111111")) |
| | | .body("contact.label", is(givenContact.getLabel())) |
| | | .body("person.tradeName", is(givenPerson.getTradeName())) |
| | | .header("Location", startsWith("http://localhost")) |
| | | .extract().header("Location"); // @formatter:on |
| | | |
| | | // finally, the new partner can be accessed under the generated UUID |
| | | final var newUserUuid = toCleanup(UUID.fromString( |
| | | location.substring(location.lastIndexOf('/') + 1))); |
| | | final var newUserUuid = UUID.fromString( |
| | | location.substring(location.lastIndexOf('/') + 1)); |
| | | assertThat(newUserUuid).isNotNull(); |
| | | } |
| | | |
| | |
| | | |
| | | @Nested |
| | | @Accepts({ "Partner:R(Read)" }) |
| | | @Transactional |
| | | class GetPartner { |
| | | |
| | | @Test |
| | |
| | | |
| | | @Nested |
| | | @Accepts({ "Partner:U(Update)" }) |
| | | @Transactional |
| | | class PatchPartner { |
| | | |
| | | @Test |
| | |
| | | "contactUuid": "%s", |
| | | "personUuid": "%s", |
| | | "details": { |
| | | "registrationOffice": "Registergericht Hamburg", |
| | | "registrationOffice": "Temp Registergericht Aurich", |
| | | "registrationNumber": "222222", |
| | | "birthName": "Maja Schmidt", |
| | | "birthday": "1938-04-08", |
| | |
| | | .matches(person -> { |
| | | assertThat(person.getPerson().getTradeName()).isEqualTo("Third OHG"); |
| | | assertThat(person.getContact().getLabel()).isEqualTo("forth contact"); |
| | | assertThat(person.getDetails().getRegistrationOffice()).isEqualTo("Registergericht Hamburg"); |
| | | assertThat(person.getDetails().getRegistrationOffice()).isEqualTo("Temp Registergericht Aurich"); |
| | | assertThat(person.getDetails().getRegistrationNumber()).isEqualTo("222222"); |
| | | assertThat(person.getDetails().getBirthName()).isEqualTo("Maja Schmidt"); |
| | | assertThat(person.getDetails().getBirthday()).isEqualTo("1938-04-08"); |
| | |
| | | .matches(person -> { |
| | | assertThat(person.getPerson().getTradeName()).isEqualTo(givenPartner.getPerson().getTradeName()); |
| | | assertThat(person.getContact().getLabel()).isEqualTo(givenPartner.getContact().getLabel()); |
| | | assertThat(person.getDetails().getRegistrationOffice()).isEqualTo(null); |
| | | assertThat(person.getDetails().getRegistrationNumber()).isEqualTo(null); |
| | | assertThat(person.getDetails().getRegistrationOffice()).isEqualTo("Temp Registergericht Leer"); |
| | | assertThat(person.getDetails().getRegistrationNumber()).isEqualTo("333333"); |
| | | assertThat(person.getDetails().getBirthName()).isEqualTo("Maja Schmidt"); |
| | | assertThat(person.getDetails().getBirthday()).isEqualTo("1938-04-08"); |
| | | assertThat(person.getDetails().getDateOfDeath()).isEqualTo("2022-01-12"); |
| | |
| | | |
| | | @Nested |
| | | @Accepts({ "Partner:D(Delete)" }) |
| | | @Transactional |
| | | class DeletePartner { |
| | | |
| | | @Test |
| | |
| | | final var givenPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0); |
| | | final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0); |
| | | final var newPartner = HsOfficePartnerEntity.builder() |
| | | .uuid(UUID.randomUUID()) |
| | | .person(givenPerson) |
| | | .contact(givenContact) |
| | | .details(HsOfficePartnerDetailsEntity.builder() |
| | | .uuid((UUID.randomUUID())) |
| | | .registrationOffice("Temp Registergericht Leer") |
| | | .registrationNumber("333333") |
| | | .build()) |
| | | .build(); |
| | | |
| | | toCleanup(newPartner.getUuid()); |
| | | |
| | | return partnerRepo.save(newPartner); |
| | | }).assertSuccessful().returnedValue(); |
| | | } |
| | | |
| | | private UUID toCleanup(final UUID tempPartnerUuid) { |
| | | tempPartnerUuids.add(tempPartnerUuid); |
| | | return tempPartnerUuid; |
| | | } |
| | | |
| | | @AfterEach |
| | | void cleanup() { |
| | | tempPartnerUuids.forEach(uuid -> { |
| | | jpaAttempt.transacted(() -> { |
| | | context.define("superuser-alex@hostsharing.net", null); |
| | | System.out.println("DELETING temporary partner: " + uuid); |
| | | final var count = partnerRepo.deleteByUuid(uuid); |
| | | System.out.println("DELETED temporary partner: " + uuid + (count > 0 ? " successful" : " failed")); |
| | | }); |
| | | }); |
| | | final var deleted = jpaAttempt.transacted(() -> { |
| | | context.define("superuser-alex@hostsharing.net", null); |
| | | em.createNativeQuery(""" |
| | | delete from hs_office_partner p |
| | | where p.detailsuuid in ( |
| | | select d.uuid from hs_office_partner_details d |
| | | where d.registrationoffice like 'Temp %') |
| | | """) |
| | | .executeUpdate(); |
| | | }).assertSuccessful().returnedValue(); |
| | | |
| | | final var remaining = jpaAttempt.transacted(() -> { |
| | | em.createNativeQuery(""" |
| | | select count(p) from hs_office_partner p |
| | | where p.detailsuuid in ( |
| | | select d.uuid from hs_office_partner_details d |
| | | where d.registrationoffice like 'Temp %') |
| | | """) |
| | | .getSingleResult(); |
| | | }).assertSuccessful().returnedValue(); |
| | | System.err.println("@AfterEach" + ": " + deleted + " records deleted, " + remaining + " remaining"); |
| | | } |
| | | |
| | | } |
| | |
| | | // when |
| | | final var result = attempt(em, () -> { |
| | | final var newPartner = toCleanup(HsOfficePartnerEntity.builder() |
| | | .uuid(UUID.randomUUID()) |
| | | .person(givenPerson) |
| | | .contact(givenContact) |
| | | .details(HsOfficePartnerDetailsEntity.builder() |
| | | .uuid(UUID.randomUUID()) |
| | | .build()) |
| | | .build()); |
| | | return partnerRepo.save(newPartner); |
| | |
| | | final var givenPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0); |
| | | final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0); |
| | | final var newPartner = toCleanup(HsOfficePartnerEntity.builder() |
| | | .uuid(UUID.randomUUID()) |
| | | .person(givenPerson) |
| | | .contact(givenContact) |
| | | .details(HsOfficePartnerDetailsEntity.builder().uuid(UUID.randomUUID()).build()) |
| | | .details(HsOfficePartnerDetailsEntity.builder().build()) |
| | | .build()); |
| | | return partnerRepo.save(newPartner); |
| | | }); |
| | |
| | | final var givenPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0); |
| | | final var givenContact = contactRepo.findContactByOptionalLabelLike(contact).get(0); |
| | | final var newPartner = HsOfficePartnerEntity.builder() |
| | | .uuid(UUID.randomUUID()) |
| | | .person(givenPerson) |
| | | .contact(givenContact) |
| | | .details(HsOfficePartnerDetailsEntity.builder() |
| | | .uuid(UUID.randomUUID()) |
| | | .build()) |
| | | .details(HsOfficePartnerDetailsEntity.builder().build()) |
| | | .build(); |
| | | |
| | | toCleanup(newPartner); |
| | |
| | | |
| | | static public HsOfficePartnerEntity HsOfficePartnerWithLegalPerson(final String tradeName) { |
| | | return HsOfficePartnerEntity.builder() |
| | | .uuid(UUID.randomUUID()) |
| | | .person(HsOfficePersonEntity.builder() |
| | | .personType(LEGAL) |
| | | .tradeName(tradeName) |
| | |
| | | |
| | | import io.restassured.RestAssured; |
| | | import io.restassured.http.ContentType; |
| | | import net.hostsharing.test.Accepts; |
| | | import net.hostsharing.hsadminng.HsadminNgApplication; |
| | | import net.hostsharing.hsadminng.context.Context; |
| | | import net.hostsharing.test.Accepts; |
| | | import net.hostsharing.test.JpaAttempt; |
| | | import org.apache.commons.lang3.RandomStringUtils; |
| | | import org.json.JSONException; |
| | | import org.junit.jupiter.api.AfterEach; |
| | | import org.junit.jupiter.api.BeforeEach; |
| | | import org.junit.jupiter.api.Nested; |
| | | import org.junit.jupiter.api.Test; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | |
| | | import org.springframework.boot.test.web.server.LocalServerPort; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.HashSet; |
| | | import java.util.Set; |
| | | import javax.persistence.EntityManager; |
| | | import java.util.UUID; |
| | | |
| | | import static net.hostsharing.test.IsValidUuidMatcher.isUuidValid; |
| | |
| | | webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, |
| | | classes = { HsadminNgApplication.class, JpaAttempt.class } |
| | | ) |
| | | @Transactional |
| | | class HsOfficePersonControllerAcceptanceTest { |
| | | |
| | | @LocalServerPort |
| | |
| | | @Autowired |
| | | JpaAttempt jpaAttempt; |
| | | |
| | | Set<UUID> tempPersonUuids = new HashSet<>(); |
| | | @Autowired |
| | | EntityManager em; |
| | | |
| | | @Nested |
| | | @Accepts({ "Person:F(Find)" }) |
| | |
| | | class AddPerson { |
| | | |
| | | @Test |
| | | void globalAdmin_withoutAssumedRole_canAddPerson() { |
| | | |
| | | context.define("superuser-alex@hostsharing.net"); |
| | | void globalAdmin_canAddPerson() { |
| | | |
| | | final var location = RestAssured // @formatter:off |
| | | .given() |
| | |
| | | { |
| | | "personType": "NATURAL", |
| | | "familyName": "Tester", |
| | | "givenName": "Testi" |
| | | "givenName": "Temp Testi" |
| | | } |
| | | """) |
| | | .port(port) |
| | |
| | | .body("uuid", isUuidValid()) |
| | | .body("personType", is("NATURAL")) |
| | | .body("familyName", is("Tester")) |
| | | .body("givenName", is("Testi")) |
| | | .body("givenName", is("Temp Testi")) |
| | | .header("Location", startsWith("http://localhost")) |
| | | .extract().header("Location"); // @formatter:on |
| | | |
| | | // finally, the new person can be accessed under the generated UUID |
| | | final var newUserUuid = toCleanup(UUID.fromString( |
| | | location.substring(location.lastIndexOf('/') + 1))); |
| | | final var newUserUuid = UUID.fromString( |
| | | location.substring(location.lastIndexOf('/') + 1)); |
| | | assertThat(newUserUuid).isNotNull(); |
| | | } |
| | | } |
| | | |
| | | @Nested |
| | | @Accepts({ "Person:R(Read)" }) |
| | | @Transactional |
| | | class GetPerson { |
| | | |
| | | @Test |
| | | void globalAdmin_withoutAssumedRole_canGetArbitraryPerson() { |
| | | void globalAdmin_canGetArbitraryPerson() { |
| | | context.define("superuser-alex@hostsharing.net"); |
| | | final var givenPersonUuid = personRepo.findPersonByOptionalNameLike("Erben").get(0).getUuid(); |
| | | |
| | |
| | | @Test |
| | | @Accepts({ "Person:X(Access Control)" }) |
| | | void normalUser_canNotGetUnrelatedPerson() { |
| | | context.define("superuser-alex@hostsharing.net"); |
| | | final var givenPersonUuid = personRepo.findPersonByOptionalNameLike("Erben").get(0).getUuid(); |
| | | final var givenPersonUuid = jpaAttempt.transacted(() -> { |
| | | context.define("superuser-alex@hostsharing.net"); |
| | | return personRepo.findPersonByOptionalNameLike("Erben").get(0).getUuid(); |
| | | }).returnedValue(); |
| | | |
| | | RestAssured // @formatter:off |
| | | .given() |
| | |
| | | @Test |
| | | @Accepts({ "Person:X(Access Control)" }) |
| | | void personOwnerUser_canGetRelatedPerson() { |
| | | context.define("superuser-alex@hostsharing.net"); |
| | | final var givenPersonUuid = personRepo.findPersonByOptionalNameLike("Erben").get(0).getUuid(); |
| | | final var givenPersonUuid = jpaAttempt.transacted(() -> { |
| | | context.define("superuser-alex@hostsharing.net"); |
| | | return personRepo.findPersonByOptionalNameLike("Erben").get(0).getUuid(); |
| | | }).returnedValue(); |
| | | |
| | | RestAssured // @formatter:off |
| | | .given() |
| | |
| | | |
| | | @Nested |
| | | @Accepts({ "Person:U(Update)" }) |
| | | @Transactional |
| | | class PatchPerson { |
| | | |
| | | @Test |
| | | void globalAdmin_withoutAssumedRole_canPatchAllPropertiesOfArbitraryPerson() { |
| | | void globalAdmin_canPatchAllPropertiesOfArbitraryPerson() { |
| | | |
| | | context.define("superuser-alex@hostsharing.net"); |
| | | final var givenPerson = givenSomeTemporaryPersonCreatedBy("selfregistered-test-user@hostsharing.org"); |
| | | |
| | | final var location = RestAssured // @formatter:off |
| | |
| | | .body(""" |
| | | { |
| | | "personType": "JOINT_REPRESENTATION", |
| | | "tradeName": "Patched Trade Name", |
| | | "familyName": "Patched Family Name", |
| | | "givenName": "Patched Given Name" |
| | | "tradeName": "Temp Trade Name - patched", |
| | | "familyName": "Temp Family Name - patched", |
| | | "givenName": "Temp Given Name - patched" |
| | | } |
| | | """) |
| | | .port(port) |
| | |
| | | .contentType(ContentType.JSON) |
| | | .body("uuid", isUuidValid()) |
| | | .body("personType", is("JOINT_REPRESENTATION")) |
| | | .body("tradeName", is("Patched Trade Name")) |
| | | .body("familyName", is("Patched Family Name")) |
| | | .body("givenName", is("Patched Given Name")); |
| | | .body("tradeName", is("Temp Trade Name - patched")) |
| | | .body("familyName", is("Temp Family Name - patched")) |
| | | .body("givenName", is("Temp Given Name - patched")); |
| | | // @formatter:on |
| | | |
| | | // finally, the person is actually updated |
| | |
| | | assertThat(personRepo.findByUuid(givenPerson.getUuid())).isPresent().get() |
| | | .matches(person -> { |
| | | assertThat(person.getPersonType()).isEqualTo(HsOfficePersonType.JOINT_REPRESENTATION); |
| | | assertThat(person.getTradeName()).isEqualTo("Patched Trade Name"); |
| | | assertThat(person.getFamilyName()).isEqualTo("Patched Family Name"); |
| | | assertThat(person.getGivenName()).isEqualTo("Patched Given Name"); |
| | | assertThat(person.getTradeName()).isEqualTo("Temp Trade Name - patched"); |
| | | assertThat(person.getFamilyName()).isEqualTo("Temp Family Name - patched"); |
| | | assertThat(person.getGivenName()).isEqualTo("Temp Given Name - patched"); |
| | | return true; |
| | | }); |
| | | } |
| | | |
| | | @Test |
| | | void globalAdmin_withoutAssumedRole_canPatchPartialPropertiesOfArbitraryPerson() { |
| | | void globalAdmin_canPatchPartialPropertiesOfArbitraryPerson() { |
| | | |
| | | context.define("superuser-alex@hostsharing.net"); |
| | | final var givenPerson = givenSomeTemporaryPersonCreatedBy("selfregistered-test-user@hostsharing.org"); |
| | | |
| | | final var location = RestAssured // @formatter:off |
| | |
| | | .contentType(ContentType.JSON) |
| | | .body(""" |
| | | { |
| | | "familyName": "Patched Family Name", |
| | | "givenName": "Patched Given Name" |
| | | "familyName": "Temp Family Name - patched", |
| | | "givenName": "Temp Given Name - patched" |
| | | } |
| | | """) |
| | | .port(port) |
| | |
| | | .body("uuid", isUuidValid()) |
| | | .body("personType", is(givenPerson.getPersonType().toString())) |
| | | .body("tradeName", is(givenPerson.getTradeName())) |
| | | .body("familyName", is("Patched Family Name")) |
| | | .body("givenName", is("Patched Given Name")); |
| | | .body("familyName", is("Temp Family Name - patched")) |
| | | .body("givenName", is("Temp Given Name - patched")); |
| | | // @formatter:on |
| | | |
| | | // finally, the person is actually updated |
| | | context.define("superuser-alex@hostsharing.net"); |
| | | assertThat(personRepo.findByUuid(givenPerson.getUuid())).isPresent().get() |
| | | .matches(person -> { |
| | | assertThat(person.getPersonType()).isEqualTo(givenPerson.getPersonType()); |
| | | assertThat(person.getTradeName()).isEqualTo(givenPerson.getTradeName()); |
| | | assertThat(person.getFamilyName()).isEqualTo("Patched Family Name"); |
| | | assertThat(person.getGivenName()).isEqualTo("Patched Given Name"); |
| | | assertThat(person.getFamilyName()).isEqualTo("Temp Family Name - patched"); |
| | | assertThat(person.getGivenName()).isEqualTo("Temp Given Name - patched"); |
| | | return true; |
| | | }); |
| | | } |
| | |
| | | |
| | | @Nested |
| | | @Accepts({ "Person:D(Delete)" }) |
| | | @Transactional |
| | | class DeletePerson { |
| | | |
| | | @Test |
| | | void globalAdmin_withoutAssumedRole_canDeleteArbitraryPerson() { |
| | | context.define("superuser-alex@hostsharing.net"); |
| | | void globalAdmin_canDeleteArbitraryPerson() { |
| | | final var givenPerson = givenSomeTemporaryPersonCreatedBy("selfregistered-test-user@hostsharing.org"); |
| | | |
| | | RestAssured // @formatter:off |
| | |
| | | .statusCode(204); // @formatter:on |
| | | |
| | | // then the given person is gone |
| | | |
| | | context.define("superuser-alex@hostsharing.net"); |
| | | assertThat(personRepo.findByUuid(givenPerson.getUuid())).isEmpty(); |
| | | } |
| | | |
| | |
| | | @Test |
| | | @Accepts({ "Person:X(Access Control)" }) |
| | | void normalUser_canNotDeleteUnrelatedPerson() { |
| | | context.define("superuser-alex@hostsharing.net"); |
| | | final var givenPerson = givenSomeTemporaryPersonCreatedBy("selfregistered-test-user@hostsharing.org"); |
| | | |
| | | RestAssured // @formatter:off |
| | |
| | | // @formatter:on |
| | | |
| | | // then the given person is still there |
| | | context.define("superuser-alex@hostsharing.net"); |
| | | assertThat(personRepo.findByUuid(givenPerson.getUuid())).isNotEmpty(); |
| | | } |
| | | } |
| | |
| | | .personType(HsOfficePersonType.LEGAL) |
| | | .tradeName("Temp " + Context.getCallerMethodNameFromStackFrame(2)) |
| | | .familyName(RandomStringUtils.randomAlphabetic(10) + "@example.org") |
| | | .givenName("Given Name " + RandomStringUtils.randomAlphabetic(10)) |
| | | .givenName("Temp Given Name " + RandomStringUtils.randomAlphabetic(10)) |
| | | .build(); |
| | | |
| | | toCleanup(newPerson.getUuid()); |
| | | |
| | | return personRepo.save(newPerson); |
| | | }).assertSuccessful().returnedValue(); |
| | | } |
| | | |
| | | private UUID toCleanup(final UUID tempPersonUuid) { |
| | | tempPersonUuids.add(tempPersonUuid); |
| | | return tempPersonUuid; |
| | | } |
| | | |
| | | @BeforeEach |
| | | @AfterEach |
| | | void cleanup() { |
| | | tempPersonUuids.forEach(uuid -> { |
| | | jpaAttempt.transacted(() -> { |
| | | context.define("superuser-alex@hostsharing.net", null); |
| | | System.out.println("DELETING temporary person: " + uuid); |
| | | 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 -> hsOfficePersonEntity.toShortString()).orElse("null") + ")")); |
| | | }).assertSuccessful(); |
| | | }); |
| | | jpaAttempt.transacted(() -> { |
| | | context.define("superuser-alex@hostsharing.net", null); |
| | | em.createQuery(""" |
| | | DELETE FROM HsOfficePersonEntity p |
| | | WHERE p.tradeName LIKE 'Temp %' OR p.givenName LIKE 'Temp %' |
| | | """).executeUpdate(); |
| | | }).assertSuccessful(); |
| | | } |
| | | } |
| | |
| | | |
| | | static public HsOfficePersonEntity hsOfficePerson(final String tradeName) { |
| | | return HsOfficePersonEntity.builder() |
| | | .uuid(UUID.randomUUID()) |
| | | .personType(HsOfficePersonType.NATURAL) |
| | | .tradeName(tradeName) |
| | | .build(); |
| | |
| | | package net.hostsharing.hsadminng.hs.office.relationship; |
| | | |
| | | import net.hostsharing.hsadminng.HsadminNgApplication; |
| | | import net.hostsharing.hsadminng.context.Context; |
| | | import net.hostsharing.hsadminng.context.ContextBasedTest; |
| | | import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRepository; |
| | |
| | | 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.context.annotation.Import; |
| | | import org.springframework.orm.jpa.JpaSystemException; |
| | | import org.springframework.test.annotation.DirtiesContext; |
| | | |
| | | import javax.persistence.EntityManager; |
| | | import javax.servlet.http.HttpServletRequest; |
| | |
| | | // when |
| | | final var result = attempt(em, () -> { |
| | | final var newRelationship = toCleanup(HsOfficeRelationshipEntity.builder() |
| | | .uuid(UUID.randomUUID()) |
| | | .relAnchor(givenAnchorPerson) |
| | | .relHolder(givenHolderPerson) |
| | | .relType(HsOfficeRelationshipType.JOINT_AGENT) |
| | |
| | | final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Anita").get(0); |
| | | final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0); |
| | | final var newRelationship = toCleanup(HsOfficeRelationshipEntity.builder() |
| | | .uuid(UUID.randomUUID()) |
| | | .relAnchor(givenAnchorPerson) |
| | | .relHolder(givenHolderPerson) |
| | | .relType(HsOfficeRelationshipType.JOINT_AGENT) |
| | |
| | | final var givenHolderPerson = personRepo.findPersonByOptionalNameLike(holderPerson).get(0); |
| | | final var givenContact = contactRepo.findContactByOptionalLabelLike(contact).get(0); |
| | | final var newRelationship = HsOfficeRelationshipEntity.builder() |
| | | .uuid(UUID.randomUUID()) |
| | | .relType(HsOfficeRelationshipType.JOINT_AGENT) |
| | | .relAnchor(givenAnchorPerson) |
| | | .relHolder(givenHolderPerson) |
| | |
| | | import com.vladmihalcea.hibernate.type.range.Range; |
| | | import io.restassured.RestAssured; |
| | | import io.restassured.http.ContentType; |
| | | import net.hostsharing.test.Accepts; |
| | | import net.hostsharing.hsadminng.HsadminNgApplication; |
| | | import net.hostsharing.hsadminng.context.Context; |
| | | import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountRepository; |
| | | import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository; |
| | | import net.hostsharing.test.Accepts; |
| | | import net.hostsharing.test.JpaAttempt; |
| | | import org.json.JSONException; |
| | | import org.junit.jupiter.api.AfterEach; |
| | | import org.junit.jupiter.api.BeforeEach; |
| | | import org.junit.jupiter.api.Nested; |
| | | import org.junit.jupiter.api.Test; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | |
| | | import org.springframework.boot.test.web.server.LocalServerPort; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import javax.persistence.EntityManager; |
| | | import java.time.LocalDate; |
| | | import java.util.HashSet; |
| | | import java.util.Set; |
| | | import java.util.UUID; |
| | | |
| | | import static net.hostsharing.test.IsValidUuidMatcher.isUuidValid; |
| | |
| | | @Autowired |
| | | JpaAttempt jpaAttempt; |
| | | |
| | | Set<UUID> tempSepaMandateUuids = new HashSet<>(); |
| | | @Autowired |
| | | EntityManager em; |
| | | |
| | | @Nested |
| | | @Accepts({ "SepaMandate:F(Find)" }) |
| | |
| | | { |
| | | "debitorUuid": "%s", |
| | | "bankAccountUuid": "%s", |
| | | "reference": "temp ref A", |
| | | "reference": "temp ref CAT A", |
| | | "validFrom": "2022-10-13" |
| | | } |
| | | """.formatted(givenDebitor.getUuid(), givenBankAccount.getUuid())) |
| | |
| | | .body("uuid", isUuidValid()) |
| | | .body("debitor.partner.person.tradeName", is("Third OHG")) |
| | | .body("bankAccount.iban", is("DE02200505501015871393")) |
| | | .body("reference", is("temp ref A")) |
| | | .body("reference", is("temp ref CAT A")) |
| | | .body("validFrom", is("2022-10-13")) |
| | | .body("validTo", equalTo(null)) |
| | | .header("Location", startsWith("http://localhost")) |
| | | .extract().header("Location"); // @formatter:on |
| | | |
| | | // finally, the new sepaMandate can be accessed under the generated UUID |
| | | final var newUserUuid = toCleanup(UUID.fromString( |
| | | location.substring(location.lastIndexOf('/') + 1))); |
| | | final var newUserUuid = UUID.fromString( |
| | | location.substring(location.lastIndexOf('/') + 1)); |
| | | assertThat(newUserUuid).isNotNull(); |
| | | } |
| | | |
| | |
| | | .body(""" |
| | | { |
| | | "bankAccountUuid": "%s", |
| | | "reference": "temp ref A", |
| | | "reference": "temp ref CAT B", |
| | | "validFrom": "2022-10-13" |
| | | } |
| | | """.formatted(givenBankAccount.getUuid())) |
| | |
| | | { |
| | | "debitorUuid": "%s", |
| | | "bankAccountUuid": "%s", |
| | | "reference": "temp ref A", |
| | | "reference": "temp ref CAT C", |
| | | "validFrom": "2022-10-13", |
| | | "validTo": "2024-12-31" |
| | | } |
| | |
| | | { |
| | | "debitorUuid": "%s", |
| | | "bankAccountUuid": "%s", |
| | | "reference": "temp ref A", |
| | | "reference": "temp refCAT D", |
| | | "validFrom": "2022-10-13", |
| | | "validTo": "2024-12-31" |
| | | } |
| | |
| | | "debitorNumber": 10001, |
| | | "billingContact": { "label": "first contact" } |
| | | }, |
| | | "bankAccount": { |
| | | "bankAccount": { |
| | | "holder": "First GmbH", |
| | | "iban": "DE02120300000000202051" |
| | | }, |
| | |
| | | "debitorNumber": 10001, |
| | | "billingContact": { "label": "first contact" } |
| | | }, |
| | | "bankAccount": { |
| | | "bankAccount": { |
| | | "holder": "First GmbH", |
| | | "iban": "DE02120300000000202051" |
| | | }, |
| | |
| | | .body("uuid", isUuidValid()) |
| | | .body("debitor.partner.person.tradeName", is("First GmbH")) |
| | | .body("bankAccount.iban", is("DE02120300000000202051")) |
| | | .body("reference", is("temp ref X")) |
| | | .body("reference", is("temp ref CAT Z")) |
| | | .body("validFrom", is("2022-11-01")) |
| | | .body("validTo", is("2022-12-31")); |
| | | // @formatter:on |
| | |
| | | .matches(mandate -> { |
| | | assertThat(mandate.getDebitor().toString()).isEqualTo("debitor(10001: First GmbH)"); |
| | | assertThat(mandate.getBankAccount().toShortString()).isEqualTo("First GmbH"); |
| | | assertThat(mandate.getReference()).isEqualTo("temp ref X"); |
| | | assertThat(mandate.getReference()).isEqualTo("temp ref CAT Z"); |
| | | assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,2023-01-01)"); |
| | | return true; |
| | | }); |
| | |
| | | .contentType(ContentType.JSON) |
| | | .body(""" |
| | | { |
| | | "reference": "new ref" |
| | | "reference": "temp ref CAT new" |
| | | } |
| | | """) |
| | | .port(port) |
| | |
| | | return true; |
| | | }); |
| | | } |
| | | |
| | | } |
| | | |
| | | @Nested |
| | |
| | | void bankAccountAdminUser_canNotDeleteRelatedSepaMandate() { |
| | | context.define("superuser-alex@hostsharing.net"); |
| | | final var givenSepaMandate = givenSomeTemporarySepaMandate(); |
| | | assertThat(givenSepaMandate.getReference()).isEqualTo("temp ref X"); |
| | | |
| | | RestAssured // @formatter:off |
| | | .given() |
| | |
| | | void normalUser_canNotDeleteUnrelatedSepaMandate() { |
| | | context.define("superuser-alex@hostsharing.net"); |
| | | final var givenSepaMandate = givenSomeTemporarySepaMandate(); |
| | | assertThat(givenSepaMandate.getReference()).isEqualTo("temp ref X"); |
| | | |
| | | RestAssured // @formatter:off |
| | | .given() |
| | |
| | | .uuid(UUID.randomUUID()) |
| | | .debitor(givenDebitor) |
| | | .bankAccount(givenBankAccount) |
| | | .reference("temp ref X") |
| | | .reference("temp ref CAT Z") |
| | | .validity(Range.closedOpen( |
| | | LocalDate.parse("2022-11-01"), LocalDate.parse("2023-03-31"))) |
| | | .build(); |
| | | |
| | | toCleanup(newSepaMandate.getUuid()); |
| | | |
| | | return sepaMandateRepo.save(newSepaMandate); |
| | | }).assertSuccessful().returnedValue(); |
| | | } |
| | | |
| | | private UUID toCleanup(final UUID tempSepaMandateUuid) { |
| | | tempSepaMandateUuids.add(tempSepaMandateUuid); |
| | | return tempSepaMandateUuid; |
| | | } |
| | | |
| | | @BeforeEach |
| | | @AfterEach |
| | | void cleanup() { |
| | | tempSepaMandateUuids.forEach(uuid -> { |
| | | jpaAttempt.transacted(() -> { |
| | | context.define("superuser-alex@hostsharing.net", null); |
| | | System.out.println("DELETING temporary sepaMandate: " + uuid); |
| | | final var count = sepaMandateRepo.deleteByUuid(uuid); |
| | | System.out.println("DELETED temporary sepaMandate: " + uuid + (count > 0 ? " successful" : " failed")); |
| | | }); |
| | | }); |
| | | jpaAttempt.transacted(() -> { |
| | | context.define("superuser-alex@hostsharing.net", null); |
| | | final var count = em.createQuery("DELETE FROM HsOfficeSepaMandateEntity s WHERE s.reference like 'temp %'") |
| | | .executeUpdate(); |
| | | if (count == 0) { |
| | | System.out.println("nothing deleted"); |
| | | } |
| | | }).assertSuccessful(); |
| | | } |
| | | |
| | | } |
| | |
| | | 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.context.annotation.Import; |
| | | import org.springframework.orm.jpa.JpaSystemException; |
| | | import org.springframework.test.annotation.DirtiesContext; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import javax.persistence.EntityManager; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.time.LocalDate; |
| | | import java.util.*; |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | |
| | | import static net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantEntity.grantDisplaysOf; |
| | | import static net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleEntity.roleNamesOf; |
| | |
| | | import static org.assertj.core.api.Assumptions.assumeThat; |
| | | |
| | | @DataJpaTest |
| | | @Import( { Context.class, JpaAttempt.class }) |
| | | @Import({ Context.class, JpaAttempt.class }) |
| | | class HsOfficeSepaMandateRepositoryIntegrationTest extends ContextBasedTest { |
| | | |
| | | @Autowired |
| | |
| | | RawRbacGrantRepository rawGrantRepo; |
| | | |
| | | @Autowired |
| | | EntityManager em; |
| | | JpaAttempt jpaAttempt; |
| | | |
| | | @Autowired |
| | | JpaAttempt jpaAttempt; |
| | | EntityManager em; |
| | | |
| | | @MockBean |
| | | HttpServletRequest request; |
| | | |
| | | Set<HsOfficeSepaMandateEntity> tempEntities = new HashSet<>(); |
| | | |
| | | @Nested |
| | | class CreateSepaMandate { |
| | |
| | | |
| | | // when |
| | | final var result = attempt(em, () -> { |
| | | final var newSepaMandate = toCleanup(HsOfficeSepaMandateEntity.builder() |
| | | .uuid(UUID.randomUUID()) |
| | | final var newSepaMandate = HsOfficeSepaMandateEntity.builder() |
| | | .debitor(givenDebitor) |
| | | .bankAccount(givenBankAccount) |
| | | .reference("temp ref A") |
| | | .validity(Range.closedOpen( |
| | | LocalDate.parse("2020-01-01"), LocalDate.parse("2023-01-01"))) |
| | | .build()); |
| | | .build(); |
| | | return sepaMandateRepo.save(newSepaMandate); |
| | | }); |
| | | |
| | |
| | | attempt(em, () -> { |
| | | final var givenDebitor = debitorRepo.findDebitorByOptionalNameLike("First").get(0); |
| | | final var givenBankAccount = bankAccountRepo.findByOptionalHolderLike("Paul Winkler").get(0); |
| | | final var newSepaMandate = toCleanup(HsOfficeSepaMandateEntity.builder() |
| | | .uuid(UUID.randomUUID()) |
| | | final var newSepaMandate = HsOfficeSepaMandateEntity.builder() |
| | | .debitor(givenDebitor) |
| | | .bankAccount(givenBankAccount) |
| | | .reference("temp ref B") |
| | | .validity(Range.closedOpen( |
| | | LocalDate.parse("2020-01-01"), LocalDate.parse("2023-01-01"))) |
| | | .build()); |
| | | .build(); |
| | | return sepaMandateRepo.save(newSepaMandate); |
| | | }); |
| | | |
| | |
| | | context("superuser-alex@hostsharing.net"); |
| | | givenSepaMandate.setValidity(Range.closedOpen( |
| | | givenSepaMandate.getValidity().lower(), newValidityEnd)); |
| | | return toCleanup(sepaMandateRepo.save(givenSepaMandate)); |
| | | return sepaMandateRepo.save(givenSepaMandate); |
| | | }); |
| | | |
| | | // then |
| | |
| | | |
| | | @BeforeEach |
| | | @AfterEach |
| | | @Transactional |
| | | void cleanup() { |
| | | tempEntities.forEach(tempSepaMandate -> { |
| | | jpaAttempt.transacted(() -> { |
| | | context("superuser-alex@hostsharing.net", null); |
| | | System.out.println("DELETING temporary sepaMandate: " + tempSepaMandate.toString()); |
| | | sepaMandateRepo.deleteByUuid(tempSepaMandate.getUuid()); |
| | | }); |
| | | }); |
| | | jpaAttempt.transacted(() -> { |
| | | context("superuser-alex@hostsharing.net", null); |
| | | em.createQuery("DELETE FROM HsOfficeSepaMandateEntity WHERE reference like 'temp ref%'"); |
| | | }); |
| | | context("superuser-alex@hostsharing.net", null); |
| | | em.createQuery("DELETE FROM HsOfficeSepaMandateEntity WHERE reference like 'temp ref%'").executeUpdate(); |
| | | } |
| | | |
| | | private HsOfficeSepaMandateEntity givenSomeTemporarySepaMandateBessler(final String bankAccountHolder) { |
| | |
| | | final var givenDebitor = debitorRepo.findDebitorByOptionalNameLike("First").get(0); |
| | | final var givenBankAccount = bankAccountRepo.findByOptionalHolderLike(bankAccountHolder).get(0); |
| | | final var newSepaMandate = HsOfficeSepaMandateEntity.builder() |
| | | .uuid(UUID.randomUUID()) |
| | | .debitor(givenDebitor) |
| | | .bankAccount(givenBankAccount) |
| | | .reference("temp ref X") |
| | |
| | | LocalDate.parse("2020-01-01"), LocalDate.parse("2023-01-01"))) |
| | | .build(); |
| | | |
| | | toCleanup(newSepaMandate); |
| | | |
| | | return sepaMandateRepo.save(newSepaMandate); |
| | | }).assertSuccessful().returnedValue(); |
| | | } |
| | | |
| | | private HsOfficeSepaMandateEntity toCleanup(final HsOfficeSepaMandateEntity tempEntity) { |
| | | tempEntities.add(tempEntity); |
| | | return tempEntity; |
| | | } |
| | | |
| | | void exactlyTheseSepaMandatesAreReturned( |
| | |
| | | import org.springframework.test.web.servlet.MockMvc; |
| | | import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; |
| | | |
| | | import javax.persistence.EntityManager; |
| | | |
| | | import static java.util.Arrays.asList; |
| | | import static net.hostsharing.hsadminng.rbac.rbacrole.TestRbacRole.*; |
| | | import static org.hamcrest.Matchers.hasSize; |
| | |
| | | @MockBean |
| | | RbacRoleRepository rbacRoleRepository; |
| | | |
| | | @MockBean |
| | | EntityManager em; |
| | | |
| | | @Test |
| | | void apiCustomersWillReturnCustomersFromRepository() throws Exception { |
| | | |
| | |
| | | import org.springframework.test.web.servlet.MockMvc; |
| | | import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; |
| | | |
| | | import javax.persistence.EntityManager; |
| | | import java.util.UUID; |
| | | |
| | | import static net.hostsharing.test.IsValidUuidMatcher.isUuidValid; |
| | |
| | | @MockBean |
| | | RbacUserRepository rbacUserRepository; |
| | | |
| | | @MockBean |
| | | EntityManager em; |
| | | |
| | | @Test |
| | | void createUserUsesGivenUuid() throws Exception { |
| | | // given |
| | |
| | | static final TestCustomerEntity yyy = hsCustomer("yyy", 10002, "yyy@example.com"); |
| | | |
| | | static public TestCustomerEntity hsCustomer(final String prefix, final int reference, final String adminName) { |
| | | return new TestCustomerEntity(randomUUID(), prefix, reference, adminName); |
| | | return new TestCustomerEntity(null, prefix, reference, adminName); |
| | | } |
| | | } |
| | |
| | | import net.hostsharing.hsadminng.context.Context; |
| | | import net.hostsharing.test.JpaAttempt; |
| | | import org.junit.jupiter.api.AfterEach; |
| | | import org.junit.jupiter.api.BeforeEach; |
| | | import org.junit.jupiter.api.Nested; |
| | | import org.junit.jupiter.api.Test; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | |
| | | import org.springframework.boot.test.web.server.LocalServerPort; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.HashSet; |
| | | import java.util.Set; |
| | | import javax.persistence.EntityManager; |
| | | import java.util.UUID; |
| | | |
| | | import static org.assertj.core.api.Assertions.assertThat; |
| | |
| | | @Autowired |
| | | JpaAttempt jpaAttempt; |
| | | |
| | | Set<UUID> tempPartnerUuids = new HashSet<>(); |
| | | @Autowired |
| | | EntityManager em; |
| | | |
| | | @Nested |
| | | class ListCustomers { |
| | |
| | | .extract().header("Location"); // @formatter:on |
| | | |
| | | // finally, the new customer can be viewed by its own admin |
| | | final var newUserUuid = toCleanup(UUID.fromString( |
| | | location.substring(location.lastIndexOf('/') + 1))); |
| | | final var newUserUuid = UUID.fromString( |
| | | location.substring(location.lastIndexOf('/') + 1)); |
| | | context.define("customer-admin@uuu.example.com"); |
| | | assertThat(testCustomerRepository.findByUuid(newUserUuid)) |
| | | .hasValueSatisfying(c -> assertThat(c.getPrefix()).isEqualTo("uuu")); |
| | | } |
| | | |
| | | @Test |
| | | void globalAdmin_withoutAssumedRole_canAddCustomerWithGivenUuid() { |
| | | |
| | | final var givenUuid = toCleanup(UUID.randomUUID()); |
| | | |
| | | final var location = RestAssured // @formatter:off |
| | | .given() |
| | | .header("current-user", "superuser-alex@hostsharing.net") |
| | | .contentType(ContentType.JSON) |
| | | .body(""" |
| | | { |
| | | "uuid": "%s", |
| | | "reference": 90010, |
| | | "prefix": "vvv", |
| | | "adminUserName": "customer-admin@vvv.example.com" |
| | | } |
| | | """.formatted(givenUuid)) |
| | | .port(port) |
| | | .when() |
| | | .post("http://localhost/api/test/customers") |
| | | .then().assertThat() |
| | | .statusCode(201) |
| | | .contentType(ContentType.JSON) |
| | | .body("prefix", is("vvv")) |
| | | .header("Location", startsWith("http://localhost")) |
| | | .extract().header("Location"); // @formatter:on |
| | | |
| | | // finally, the new customer can be viewed by its own admin |
| | | final var newUserUuid = UUID.fromString( |
| | | location.substring(location.lastIndexOf('/') + 1)); |
| | | context.define("customer-admin@vvv.example.com"); |
| | | assertThat(testCustomerRepository.findByUuid(newUserUuid)) |
| | | .hasValueSatisfying(c -> { |
| | | assertThat(c.getPrefix()).isEqualTo("vvv"); |
| | | assertThat(c.getUuid()).isEqualTo(givenUuid); |
| | | }); |
| | | } |
| | | |
| | | @Test |
| | |
| | | .body("message", containsString("line: 1, column: 1")); |
| | | // @formatter:on |
| | | } |
| | | |
| | | } |
| | | |
| | | private UUID toCleanup(final UUID tempPartnerUuid) { |
| | | tempPartnerUuids.add(tempPartnerUuid); |
| | | return tempPartnerUuid; |
| | | } |
| | | |
| | | @BeforeEach |
| | | @AfterEach |
| | | void cleanup() { |
| | | tempPartnerUuids.forEach(uuid -> { |
| | | jpaAttempt.transacted(() -> { |
| | | context.define("superuser-alex@hostsharing.net", null); |
| | | System.out.println("DELETING temporary partner: " + uuid); |
| | | final var entity = testCustomerRepository.findByUuid(uuid); |
| | | final var count = testCustomerRepository.deleteByUuid(uuid); |
| | | System.out.println( |
| | | "DELETED temporary partner: " + uuid + (count > 0 ? " successful" : " failed") + " (" + entity.map( |
| | | TestCustomerEntity::getPrefix).orElse("???") + ")"); |
| | | }).assertSuccessful(); |
| | | }); |
| | | jpaAttempt.transacted(() -> { |
| | | context.define("superuser-alex@hostsharing.net", null); |
| | | em.createQuery("DELETE FROM TestCustomerEntity c WHERE c.reference < 99900").executeUpdate(); |
| | | }).assertSuccessful(); |
| | | } |
| | | } |
| | |
| | | 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.context.annotation.Import; |
| | | import org.springframework.test.annotation.DirtiesContext; |
| | | |
| | | import javax.persistence.EntityManager; |
| | | import javax.persistence.PersistenceException; |
| | |
| | | package net.hostsharing.test; |
| | | |
| | | import org.assertj.core.api.ObjectAssert; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.core.NestedExceptionUtils; |
| | | import org.springframework.stereotype.Service; |
| | |
| | | return result; |
| | | } |
| | | |
| | | public ObjectAssert<T> assertThatResult() { |
| | | assertSuccessful(); |
| | | return assertThat(returnedValue()); |
| | | } |
| | | |
| | | public RuntimeException caughtException() { |
| | | return exception; |
| | | } |
| | |
| | | package net.hostsharing.test; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | import lombok.NoArgsConstructor; |
| | | import lombok.Setter; |
| | | import lombok.*; |
| | | import net.hostsharing.hsadminng.errors.DisplayName; |
| | | import net.hostsharing.hsadminng.mapper.Mapper; |
| | | import org.junit.jupiter.api.Test; |
| | | import org.junit.jupiter.api.extension.ExtendWith; |
| | | import org.mockito.InjectMocks; |
| | | import org.mockito.Mock; |
| | | import org.mockito.junit.jupiter.MockitoExtension; |
| | | |
| | | import javax.persistence.EntityManager; |
| | | import javax.persistence.ManyToOne; |
| | | import javax.validation.ValidationException; |
| | | import java.util.List; |
| | | import java.util.UUID; |
| | | |
| | | import static org.assertj.core.api.Assertions.assertThat; |
| | | import static org.assertj.core.api.Assertions.catchThrowable; |
| | | import static org.junit.jupiter.api.Assertions.fail; |
| | | import static org.mockito.Mockito.when; |
| | | |
| | | @ExtendWith(MockitoExtension.class) |
| | | class MapperUnitTest { |
| | | |
| | | private Mapper mapper = new Mapper(); |
| | | @Mock |
| | | EntityManager em; |
| | | |
| | | @Getter |
| | | @Setter |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public static class SourceBean { |
| | | @InjectMocks |
| | | Mapper mapper; |
| | | |
| | | private String a; |
| | | private String b; |
| | | } |
| | | |
| | | @Getter |
| | | @Setter |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public static class TargetBean { |
| | | |
| | | private String a; |
| | | private String b; |
| | | private String c; |
| | | } |
| | | final UUID GIVEN_UUID = UUID.randomUUID(); |
| | | |
| | | @Test |
| | | void mapsNullBeanToNull() { |
| | |
| | | |
| | | @Test |
| | | void mapsBean() { |
| | | final SourceBean givenSource = new SourceBean("1234", "Text"); |
| | | final SourceBean givenSource = SourceBean.builder().a("1234").b("Text").build(); |
| | | final var result = mapper.map(givenSource, TargetBean.class); |
| | | assertThat(result).usingRecursiveComparison().isEqualTo( |
| | | new TargetBean("1234", "Text", null) |
| | | TargetBean.builder().a("1234").b("Text").build() |
| | | ); |
| | | } |
| | | |
| | | @Test |
| | | void mapsBeanWithExistingSubEntity() { |
| | | final SourceBean givenSource = SourceBean.builder().a("1234").b("Text").s1(new SubSourceBean1(GIVEN_UUID)).build(); |
| | | when(em.find(SubTargetBean1.class, GIVEN_UUID)).thenReturn(new SubTargetBean1(GIVEN_UUID, "xxx")); |
| | | |
| | | final var result = mapper.map(givenSource, TargetBean.class); |
| | | assertThat(result).usingRecursiveComparison().isEqualTo( |
| | | TargetBean.builder().a("1234").b("Text").s1(new SubTargetBean1(GIVEN_UUID, "xxx")).build() |
| | | ); |
| | | } |
| | | |
| | | @Test |
| | | void mapsBeanWithSubEntityWithNullUuid() { |
| | | final SourceBean givenSource = SourceBean.builder().a("1234").b("Text").s1(new SubSourceBean1(null)).build(); |
| | | |
| | | final var result = mapper.map(givenSource, TargetBean.class); |
| | | assertThat(result).usingRecursiveComparison().isEqualTo( |
| | | TargetBean.builder().a("1234").b("Text").s1(new SubTargetBean1(null, null)).build() |
| | | ); |
| | | } |
| | | |
| | | @Test |
| | | void mapsBeanWithSubEntityWithoutUuidField() { |
| | | final SourceBean givenSource = SourceBean.builder().a("1234").b("Text").s3(new SubSourceBean3("xxx")).build(); |
| | | |
| | | final var result = mapper.map(givenSource, TargetBean.class); |
| | | assertThat(result).usingRecursiveComparison().isEqualTo( |
| | | TargetBean.builder().a("1234").b("Text").s3(new SubTargetBean3("xxx")).build() |
| | | ); |
| | | } |
| | | |
| | | @Test |
| | | void mapsBeanWithSubEntityNotFound() { |
| | | final SourceBean givenSource = SourceBean.builder().a("1234").b("Text").s1(new SubSourceBean1(GIVEN_UUID)).build(); |
| | | when(em.find(SubTargetBean1.class, GIVEN_UUID)).thenReturn(null); |
| | | |
| | | final var exception = catchThrowable(() -> |
| | | mapper.map(givenSource, TargetBean.class) |
| | | ); |
| | | |
| | | assertThat(exception).isInstanceOf(ValidationException.class) |
| | | .hasMessage("Unable to find SubTargetBean1 with uuid " + GIVEN_UUID); |
| | | } |
| | | |
| | | @Test |
| | | void mapsBeanWithSubEntityNotFoundAndDisplayName() { |
| | | final SourceBean givenSource = SourceBean.builder().a("1234").b("Text").s2(new SubSourceBean2(GIVEN_UUID)).build(); |
| | | when(em.find(SubTargetBean2.class, GIVEN_UUID)).thenReturn(null); |
| | | |
| | | final var exception = catchThrowable(() -> |
| | | mapper.map(givenSource, TargetBean.class) |
| | | ); |
| | | |
| | | assertThat(exception).isInstanceOf(ValidationException.class) |
| | | .hasMessage("Unable to find SomeDisplayName with uuid " + GIVEN_UUID); |
| | | } |
| | | |
| | | @Test |
| | | void mapsBeanWithPostmapper() { |
| | | final SourceBean givenSource = new SourceBean("1234", "Text"); |
| | | final SourceBean givenSource = SourceBean.builder().a("1234").b("Text").build(); |
| | | final var result = mapper.map(givenSource, TargetBean.class, (s, t) -> {t.setC("Extra");}); |
| | | assertThat(result).usingRecursiveComparison().isEqualTo( |
| | | new TargetBean("1234", "Text", "Extra") |
| | | TargetBean.builder().a("1234").b("Text").c("Extra").build() |
| | | ); |
| | | } |
| | | |
| | | @Test |
| | | void mapsList() { |
| | | final var givenSource = List.of( |
| | | new SourceBean("111", "Text A"), |
| | | new SourceBean("222", "Text B"), |
| | | new SourceBean("333", "Text C")); |
| | | SourceBean.builder().a("111").b("Text A").build(), |
| | | SourceBean.builder().a("222").b("Text B").build(), |
| | | SourceBean.builder().a("333").b("Text C").build()); |
| | | final var result = mapper.mapList(givenSource, TargetBean.class); |
| | | assertThat(result).usingRecursiveComparison().isEqualTo( |
| | | List.of( |
| | | new TargetBean("111", "Text A", null), |
| | | new TargetBean("222", "Text B", null), |
| | | new TargetBean("333", "Text C", null))); |
| | | TargetBean.builder().a("111").b("Text A").build(), |
| | | TargetBean.builder().a("222").b("Text B").build(), |
| | | TargetBean.builder().a("333").b("Text C").build())); |
| | | } |
| | | |
| | | @Test |
| | | void mapsListWithPostMapper() { |
| | | final var givenSource = List.of( |
| | | new SourceBean("111", "Text A"), |
| | | new SourceBean("222", "Text B"), |
| | | new SourceBean("333", "Text C")); |
| | | SourceBean.builder().a("111").b("Text A").build(), |
| | | SourceBean.builder().a("222").b("Text B").build(), |
| | | SourceBean.builder().a("333").b("Text C").build()); |
| | | final var result = mapper.mapList(givenSource, TargetBean.class, (s, t) -> {t.setC("Extra");}); |
| | | assertThat(result).usingRecursiveComparison().isEqualTo( |
| | | List.of( |
| | | new TargetBean("111", "Text A", "Extra"), |
| | | new TargetBean("222", "Text B", "Extra"), |
| | | new TargetBean("333", "Text C", "Extra"))); |
| | | TargetBean.builder().a("111").b("Text A").c("Extra").build(), |
| | | TargetBean.builder().a("222").b("Text B").c("Extra").build(), |
| | | TargetBean.builder().a("333").b("Text C").c("Extra").build())); |
| | | } |
| | | |
| | | @Getter |
| | | @Setter |
| | | @Builder |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public static class SourceBean { |
| | | |
| | | private String a; |
| | | private String b; |
| | | private SubSourceBean1 s1; |
| | | private SubSourceBean2 s2; |
| | | private SubSourceBean3 s3; |
| | | } |
| | | |
| | | @Getter |
| | | @Setter |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public static class SubSourceBean1 { |
| | | |
| | | private UUID uuid; |
| | | } |
| | | |
| | | @Getter |
| | | @Setter |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public static class SubSourceBean2 { |
| | | |
| | | private UUID uuid; |
| | | } |
| | | |
| | | @Getter |
| | | @Setter |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public static class SubSourceBean3 { |
| | | |
| | | private String x; |
| | | } |
| | | |
| | | @Getter |
| | | @Setter |
| | | @Builder |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public static class TargetBean { |
| | | |
| | | private String a; |
| | | private String b; |
| | | private String c; |
| | | |
| | | @ManyToOne |
| | | private SubTargetBean1 s1; |
| | | |
| | | @ManyToOne |
| | | private SubTargetBean2 s2; |
| | | |
| | | @ManyToOne |
| | | private SubTargetBean3 s3; |
| | | } |
| | | |
| | | @Getter |
| | | @Setter |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public static class SubTargetBean1 { |
| | | |
| | | private UUID uuid; |
| | | private String x; |
| | | } |
| | | |
| | | @Getter |
| | | @Setter |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | @DisplayName("SomeDisplayName") |
| | | public static class SubTargetBean2 { |
| | | |
| | | private UUID uuid; |
| | | private String x; |
| | | } |
| | | |
| | | |
| | | @Getter |
| | | @Setter |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public static class SubTargetBean3 { |
| | | |
| | | private String x; |
| | | } |
| | | |
| | | } |