Upgrade to SpringBoot 3.4.1 and dependencies (#147)
Co-authored-by: Michael Hoennig <michael@hoennig.de> Reviewed-on: #147 Reviewed-by: Marc Sandlus <marc.sandlus@hostsharing.net>
This commit is contained in:
parent
a7ffee9348
commit
9c8d7616e3
4
.aliases
4
.aliases
@ -93,7 +93,8 @@ alias gw-spotless='./gradlew spotlessApply -x pitest -x test -x :processResource
|
||||
alias gw-test='. .aliases; ./gradlew test'
|
||||
alias gw-check='. .aliases; gw test check -x pitest'
|
||||
|
||||
alias cas-curl='bin/cas-curl'
|
||||
alias howto=bin/howto
|
||||
alias cas-curl=bin/cas-curl
|
||||
|
||||
# etc/docker-compose.yml limits CPUs+MEM and includes a PostgreSQL config for analysing slow queries
|
||||
alias gw-importOfficeData-in-docker-compose='
|
||||
@ -108,3 +109,4 @@ source .environment
|
||||
|
||||
alias scenario-reports-upload='./gradlew scenarioTests convertMarkdownToHtml && ssh hsh03-hsngdev@h50.hostsharing.net "rm -f doms/hsngdev.hs-example.de/htdocs-ssl/scenarios/office/*.html" && scp build/doc/scenarios/*.html hsh03-hsngdev@h50.hostsharing.net:doms/hsngdev.hs-example.de/htdocs-ssl/scenarios/office'
|
||||
alias scenario-reports-open='open https://hsngdev.hs-example.de/scenarios/office'
|
||||
|
||||
|
@ -4,5 +4,5 @@ export HSADMINNG_POSTGRES_ADMIN_PASSWORD=
|
||||
export HSADMINNG_POSTGRES_RESTRICTED_USERNAME=restricted
|
||||
export HSADMINNG_SUPERUSER=superuser-alex@hostsharing.net
|
||||
export HSADMINNG_MIGRATION_DATA_PATH=migration
|
||||
export LIQUIBASE_CONTEXT=
|
||||
export LIQUIBASE_COMMAND_CONTEXT_FILTER=
|
||||
export LANG=en_US.UTF-8
|
||||
|
@ -4,5 +4,5 @@ unset HSADMINNG_POSTGRES_ADMIN_PASSWORD
|
||||
unset HSADMINNG_POSTGRES_RESTRICTED_USERNAME
|
||||
unset HSADMINNG_SUPERUSER
|
||||
unset HSADMINNG_MIGRATION_DATA_PATH
|
||||
unset LIQUIBASE_CONTEXT
|
||||
unset LIQUIBASE_COMMAND_CONTEXT_FILTER
|
||||
|
||||
|
@ -617,6 +617,11 @@ Besides the following *How Tos* you can also find several *How Tos* in the sourc
|
||||
grep -r HOWTO src
|
||||
```
|
||||
|
||||
also try this (assumed you've sourced .aliases):
|
||||
```sh
|
||||
howto
|
||||
```
|
||||
|
||||
### How to Configure .pgpass for the Default PostgreSQL Database?
|
||||
|
||||
To access the default database schema as used during development, add this line to your `.pgpass` file in your users home directory:
|
||||
|
86
bin/howto
Executable file
86
bin/howto
Executable file
@ -0,0 +1,86 @@
|
||||
#!/usr/bin/python3
|
||||
import os
|
||||
import sys
|
||||
from urllib.parse import urljoin, quote
|
||||
|
||||
def path_to_file_uri(path):
|
||||
"""
|
||||
Converts a file path to a file URI.
|
||||
Handles absolute and relative paths.
|
||||
"""
|
||||
abs_path = os.path.abspath(path)
|
||||
return urljoin("file://", quote(abs_path))
|
||||
|
||||
def is_binary_file(filepath, chunk_size=1024):
|
||||
"""
|
||||
Prüft, ob eine Datei binär ist, indem sie den Inhalt der Datei auf nicht-druckbare Zeichen untersucht.
|
||||
"""
|
||||
try:
|
||||
with open(filepath, "rb") as file:
|
||||
chunk = file.read(chunk_size)
|
||||
if b"\0" in chunk: # Nullbyte ist ein typisches Zeichen für Binärdateien
|
||||
return True
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"Fehler beim Prüfen, ob Datei binär ist: {filepath}: {e}")
|
||||
return True
|
||||
|
||||
def search_keywords_in_files(keywords):
|
||||
if not keywords:
|
||||
print("Bitte geben Sie mindestens ein Stichwort an.")
|
||||
sys.exit(1)
|
||||
|
||||
# Allowed comment symbols
|
||||
comment_symbols = {"//", "#", ";"}
|
||||
|
||||
for root, dirs, files in os.walk("."):
|
||||
# Ausschließen bestimmter Verzeichnisse
|
||||
dirs[:] = [d for d in dirs if d not in {".git", "build"}]
|
||||
|
||||
for file in files:
|
||||
filepath = os.path.join(root, file)
|
||||
|
||||
# Überspringen von Binärdateien
|
||||
if is_binary_file(filepath):
|
||||
continue
|
||||
|
||||
try:
|
||||
with open(filepath, "r", encoding="utf-8") as f:
|
||||
lines = f.readlines()
|
||||
|
||||
for line_number, line in enumerate(lines, start=1):
|
||||
stripped_line = line.lstrip() # Entfernt führende Leerzeichen
|
||||
for symbol in comment_symbols:
|
||||
if stripped_line.startswith(symbol):
|
||||
# Entfernt das Kommentarzeichen und nachfolgende Leerzeichen
|
||||
howtoMatch = stripped_line[len(symbol):].lstrip()
|
||||
if howtoMatch.startswith(("HOWTO ", "HOWTO: ", "How to ")):
|
||||
if all(keyword in howtoMatch.lower() for keyword in keywords):
|
||||
|
||||
# Titelzeile ohne Kommentarzeichen
|
||||
print(howtoMatch.rstrip())
|
||||
|
||||
# Ausgabe nachfolgender Zeilen mit dem gleichen Kommentar-Präfix
|
||||
for subsequent_line in lines[line_number:]:
|
||||
subsequent_line = subsequent_line.lstrip()
|
||||
if subsequent_line.startswith(symbol):
|
||||
# Entfernt Kommentarzeichen aus Folgezeilen
|
||||
print("\t" + subsequent_line[len(symbol):].strip())
|
||||
else:
|
||||
break
|
||||
|
||||
# Link mit Zeilennummer
|
||||
print(f"--> {path_to_file_uri(filepath)}:{line_number}")
|
||||
|
||||
# Abstand zwischen Matches
|
||||
print()
|
||||
break
|
||||
except Exception as e:
|
||||
print(f"Fehler beim Lesen der Datei {filepath}: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 2:
|
||||
print("Verwendung: bin/howto <Stichwort1> <Stichwort2> ...")
|
||||
sys.exit(1)
|
||||
|
||||
search_keywords_in_files([arg.lower() for arg in sys.argv[1:]])
|
26
build.gradle
26
build.gradle
@ -1,17 +1,20 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.springframework.boot' version '3.3.7'
|
||||
id 'org.springframework.boot' version '3.4.1'
|
||||
id 'io.spring.dependency-management' version '1.1.7'
|
||||
id 'io.openapiprocessor.openapi-processor' version '2023.2'
|
||||
id 'com.github.jk1.dependency-license-report' version '2.9'
|
||||
id "org.owasp.dependencycheck" version "11.1.1"
|
||||
id "com.diffplug.spotless" version "7.0.0"
|
||||
id "org.owasp.dependencycheck" version "12.0.0"
|
||||
id "com.diffplug.spotless" version "7.0.2"
|
||||
id 'jacoco'
|
||||
id 'info.solidsoft.pitest' version '1.15.0'
|
||||
id 'se.patrikerdes.use-latest-versions' version '0.2.18'
|
||||
id 'com.github.ben-manes.versions' version '0.51.0'
|
||||
}
|
||||
|
||||
// HOWTO: find out which dependency versions are managed by Spring Boot:
|
||||
// https://docs.spring.io/spring-boot/appendix/dependency-versions/coordinates.html
|
||||
|
||||
group = 'net.hostsharing'
|
||||
version = '0.0.1-SNAPSHOT'
|
||||
|
||||
@ -20,6 +23,9 @@ wrapper {
|
||||
gradleVersion = '8.5'
|
||||
}
|
||||
|
||||
// TODO.impl: self-attaching is deprecated, see:
|
||||
// https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#0.3
|
||||
|
||||
configurations {
|
||||
compileOnly {
|
||||
extendsFrom annotationProcessor
|
||||
@ -61,23 +67,23 @@ dependencies {
|
||||
implementation 'org.springframework.boot:spring-boot-starter-actuator'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-security'
|
||||
implementation 'com.github.gavlyukovskiy:datasource-proxy-spring-boot-starter:1.10.0'
|
||||
implementation 'org.springdoc:springdoc-openapi:2.6.0'
|
||||
implementation 'org.postgresql:postgresql:42.7.4'
|
||||
implementation 'org.liquibase:liquibase-core:4.30.0'
|
||||
implementation 'org.springdoc:springdoc-openapi:2.8.3'
|
||||
implementation 'org.postgresql:postgresql'
|
||||
implementation 'org.liquibase:liquibase-core'
|
||||
implementation 'io.hypersistence:hypersistence-utils-hibernate-63:3.9.0'
|
||||
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.18.2'
|
||||
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'
|
||||
implementation 'org.openapitools:jackson-databind-nullable:0.2.6'
|
||||
implementation 'org.apache.commons:commons-text:1.13.0'
|
||||
implementation 'net.java.dev.jna:jna:5.16.0'
|
||||
implementation 'org.modelmapper:modelmapper:3.2.2'
|
||||
implementation 'org.iban4j:iban4j:3.2.10-RELEASE'
|
||||
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0'
|
||||
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.3'
|
||||
implementation 'org.reflections:reflections:0.10.2'
|
||||
|
||||
compileOnly 'org.projectlombok:lombok'
|
||||
testCompileOnly 'org.projectlombok:lombok'
|
||||
|
||||
// FIXME: developmentOnly 'org.springframework.boot:spring-boot-devtools'
|
||||
developmentOnly 'org.springframework.boot:spring-boot-devtools'
|
||||
|
||||
annotationProcessor 'org.projectlombok:lombok'
|
||||
testAnnotationProcessor 'org.projectlombok:lombok'
|
||||
@ -89,7 +95,7 @@ dependencies {
|
||||
testImplementation 'org.testcontainers:postgresql'
|
||||
testImplementation 'com.tngtech.archunit:archunit-junit5:1.3.0'
|
||||
testImplementation 'io.rest-assured:spring-mock-mvc'
|
||||
testImplementation 'org.hamcrest:hamcrest-core:3.0'
|
||||
testImplementation 'org.hamcrest:hamcrest-core'
|
||||
testImplementation 'org.pitest:pitest-junit5-plugin:1.2.1'
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-api'
|
||||
testImplementation 'org.wiremock:wiremock-standalone:3.10.0'
|
||||
|
@ -5,9 +5,23 @@
|
||||
{ "moduleLicense": "Apache-2.0" },
|
||||
{ "moduleLicense": "Apache License 2.0" },
|
||||
{ "moduleLicense": "Apache License v2.0" },
|
||||
{ "moduleLicense": "Apache License Version 2.0" },
|
||||
{ "moduleLicense": "Apache License, Version 2.0" },
|
||||
{ "moduleLicense": "The Apache License, Version 2.0" },
|
||||
{ "moduleLicense": "The Apache Software License, Version 2.0" },
|
||||
|
||||
{
|
||||
"moduleLicense": null,
|
||||
"#moduleLicense": "Apache License 2.0, see https://github.com/springdoc/springdoc-openapi/blob/main/LICENSE",
|
||||
"moduleVersion": "2.4.0",
|
||||
"moduleName": "org.springdoc:springdoc-openapi"
|
||||
},
|
||||
{
|
||||
"moduleLicense": null,
|
||||
"moduleVersion": "1.0.0",
|
||||
"moduleName": "org.jspecify:jspecify"
|
||||
},
|
||||
|
||||
{ "moduleLicense": "BSD License" },
|
||||
{ "moduleLicense": "BSD-2-Clause" },
|
||||
{ "moduleLicense": "BSD-3-Clause" },
|
||||
@ -46,14 +60,8 @@
|
||||
{
|
||||
"moduleLicense": "Public Domain, per Creative Commons CC0",
|
||||
"moduleVersion": "2.0.3"
|
||||
},
|
||||
|
||||
{
|
||||
"moduleLicense": null,
|
||||
"#moduleLicense": "Apache License 2.0, see https://github.com/springdoc/springdoc-openapi/blob/main/LICENSE",
|
||||
"moduleVersion": "2.4.0",
|
||||
"moduleName": "org.springdoc:springdoc-openapi"
|
||||
}
|
||||
|
||||
|
||||
]
|
||||
}
|
||||
|
@ -97,6 +97,7 @@ public class RestResponseEntityExceptionHandler
|
||||
return errorResponse(request, HttpStatus.valueOf(statusCode.value()),
|
||||
Optional.ofNullable(response.getBody()).map(Object::toString).orElse(firstMessageLine(exc)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked,rawtypes")
|
||||
protected ResponseEntity handleHttpMessageNotReadable(
|
||||
@ -131,7 +132,7 @@ public class RestResponseEntityExceptionHandler
|
||||
final HttpStatusCode status,
|
||||
final WebRequest request) {
|
||||
final var errorList = exc
|
||||
.getAllValidationResults()
|
||||
.getParameterValidationResults()
|
||||
.stream()
|
||||
.map(ParameterValidationResult::getResolvableErrors)
|
||||
.flatMap(Collection::stream)
|
||||
|
@ -5,6 +5,7 @@ import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||
import net.hostsharing.hsadminng.rbac.role.WithRoleId;
|
||||
import net.hostsharing.hsadminng.repr.Stringify;
|
||||
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||
|
||||
@ -24,7 +25,7 @@ import static net.hostsharing.hsadminng.repr.Stringify.stringify;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@DisplayAs("BookingDebitor")
|
||||
public class HsBookingDebitorEntity implements Stringifyable {
|
||||
public class HsBookingDebitorEntity implements Stringifyable, WithRoleId {
|
||||
|
||||
public static final String DEBITOR_NUMBER_TAG = "D-";
|
||||
|
||||
|
@ -7,7 +7,7 @@ import net.hostsharing.hsadminng.hs.booking.generated.api.v1.api.HsBookingProjec
|
||||
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingProjectInsertResource;
|
||||
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingProjectPatchResource;
|
||||
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingProjectResource;
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@ -26,7 +26,7 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
|
||||
private Context context;
|
||||
|
||||
@Autowired
|
||||
private StandardMapper mapper;
|
||||
private StrictMapper mapper;
|
||||
|
||||
@Autowired
|
||||
private HsBookingProjectRbacRepository bookingProjectRepo;
|
||||
|
@ -89,7 +89,7 @@ public abstract class HsHostingAsset implements Stringifyable, BaseEntity<HsHost
|
||||
@JoinColumn(name = "alarmcontactuuid")
|
||||
private HsOfficeContactRealEntity alarmContact;
|
||||
|
||||
@OneToMany(cascade = CascadeType.REFRESH, orphanRemoval = true, fetch = FetchType.LAZY)
|
||||
@OneToMany(cascade = { CascadeType.PERSIST, CascadeType.REFRESH }, orphanRemoval = true, fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "parentassetuuid", referencedColumnName = "uuid")
|
||||
private List<HsHostingAssetRealEntity> subHostingAssets;
|
||||
|
||||
|
@ -12,7 +12,7 @@ import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAsse
|
||||
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetResource;
|
||||
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetTypeResource;
|
||||
import net.hostsharing.hsadminng.mapper.KeyValueMap;
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
@ -36,7 +36,7 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
|
||||
private Context context;
|
||||
|
||||
@Autowired
|
||||
private StandardMapper mapper;
|
||||
private StrictMapper mapper;
|
||||
|
||||
@Autowired
|
||||
private HsHostingAssetRbacRepository rbacAssetRepo;
|
||||
|
@ -9,7 +9,7 @@ import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
|
||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
|
||||
import net.hostsharing.hsadminng.lambda.Reducer;
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import net.hostsharing.hsadminng.mapper.ToStringConverter;
|
||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||
|
||||
@ -31,8 +31,8 @@ public class DomainSetupHostingAssetFactory extends HostingAssetFactory {
|
||||
final EntityManagerWrapper emw,
|
||||
final HsBookingItemRealEntity newBookingItemRealEntity,
|
||||
final HsHostingAssetAutoInsertResource asset,
|
||||
final StandardMapper standardMapper) {
|
||||
super(emw, newBookingItemRealEntity, asset, standardMapper);
|
||||
final StrictMapper StrictMapper) {
|
||||
super(emw, newBookingItemRealEntity, asset, StrictMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -6,7 +6,7 @@ import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsHostingAsse
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.validators.HostingAssetEntitySaveProcessor;
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ abstract class HostingAssetFactory {
|
||||
final EntityManagerWrapper emw;
|
||||
final HsBookingItemRealEntity fromBookingItem;
|
||||
final HsHostingAssetAutoInsertResource asset;
|
||||
final StandardMapper standardMapper;
|
||||
final StrictMapper StrictMapper;
|
||||
|
||||
protected abstract HsHostingAsset create();
|
||||
|
||||
|
@ -9,7 +9,7 @@ import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsHostingAsse
|
||||
import net.hostsharing.hsadminng.hs.booking.item.BookingItemCreatedAppEvent;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset;
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
@ -25,7 +25,7 @@ public class HsBookingItemCreatedListener implements ApplicationListener<Booking
|
||||
private ObjectMapper jsonMapper;
|
||||
|
||||
@Autowired
|
||||
private StandardMapper standardMapper;
|
||||
private StrictMapper StrictMapper;
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
@ -44,9 +44,9 @@ public class HsBookingItemCreatedListener implements ApplicationListener<Booking
|
||||
final var asset = jsonMapper.readValue(event.getEntity().getAssetJson(), HsHostingAssetAutoInsertResource.class);
|
||||
final var factory = switch (newBookingItemRealEntity.getType()) {
|
||||
case PRIVATE_CLOUD, CLOUD_SERVER, MANAGED_SERVER ->
|
||||
forNowNoAutomaticHostingAssetCreationPossible(emw, newBookingItemRealEntity, asset, standardMapper);
|
||||
case MANAGED_WEBSPACE -> new ManagedWebspaceHostingAssetFactory(emw, newBookingItemRealEntity, asset, standardMapper);
|
||||
case DOMAIN_SETUP -> new DomainSetupHostingAssetFactory(emw, newBookingItemRealEntity, asset, standardMapper);
|
||||
forNowNoAutomaticHostingAssetCreationPossible(emw, newBookingItemRealEntity, asset, StrictMapper);
|
||||
case MANAGED_WEBSPACE -> new ManagedWebspaceHostingAssetFactory(emw, newBookingItemRealEntity, asset, StrictMapper);
|
||||
case DOMAIN_SETUP -> new DomainSetupHostingAssetFactory(emw, newBookingItemRealEntity, asset, StrictMapper);
|
||||
};
|
||||
if (factory != null) {
|
||||
final var statusMessage = factory.createAndPersist();
|
||||
@ -62,9 +62,9 @@ public class HsBookingItemCreatedListener implements ApplicationListener<Booking
|
||||
final EntityManagerWrapper emw,
|
||||
final HsBookingItemRealEntity fromBookingItem,
|
||||
final HsHostingAssetAutoInsertResource asset,
|
||||
final StandardMapper standardMapper
|
||||
final StrictMapper StrictMapper
|
||||
) {
|
||||
return new HostingAssetFactory(emw, fromBookingItem, asset, standardMapper) {
|
||||
return new HostingAssetFactory(emw, fromBookingItem, asset, StrictMapper) {
|
||||
|
||||
@Override
|
||||
protected HsHostingAsset create() {
|
||||
|
@ -5,7 +5,7 @@ import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsHostingAsse
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||
|
||||
import jakarta.validation.ValidationException;
|
||||
@ -19,8 +19,8 @@ public class ManagedWebspaceHostingAssetFactory extends HostingAssetFactory {
|
||||
final EntityManagerWrapper emw,
|
||||
final HsBookingItemRealEntity newBookingItemRealEntity,
|
||||
final HsHostingAssetAutoInsertResource asset,
|
||||
final StandardMapper standardMapper) {
|
||||
super(emw, newBookingItemRealEntity, asset, standardMapper);
|
||||
final StrictMapper StrictMapper) {
|
||||
super(emw, newBookingItemRealEntity, asset, StrictMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -32,7 +32,7 @@ public class ManagedWebspaceHostingAssetFactory extends HostingAssetFactory {
|
||||
.map(Enum::name)
|
||||
.orElse(null));
|
||||
}
|
||||
final var managedWebspaceHostingAsset = standardMapper.map(asset, HsHostingAssetRealEntity.class);
|
||||
final var managedWebspaceHostingAsset = StrictMapper.map(asset, HsHostingAssetRealEntity.class);
|
||||
managedWebspaceHostingAsset.setBookingItem(fromBookingItem);
|
||||
emw.createQuery(
|
||||
"SELECT asset FROM HsHostingAssetRealEntity asset WHERE asset.bookingItem.uuid=:bookingItemUuid",
|
||||
|
@ -5,7 +5,7 @@ import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeBankAccountsApi;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeBankAccountInsertResource;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeBankAccountResource;
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import org.iban4j.BicUtil;
|
||||
import org.iban4j.IbanUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -25,7 +25,7 @@ public class HsOfficeBankAccountController implements HsOfficeBankAccountsApi {
|
||||
private Context context;
|
||||
|
||||
@Autowired
|
||||
private StandardMapper mapper;
|
||||
private StrictMapper mapper;
|
||||
|
||||
@Autowired
|
||||
private HsOfficeBankAccountRepository bankAccountRepo;
|
||||
|
@ -12,6 +12,7 @@ import lombok.experimental.SuperBuilder;
|
||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
|
||||
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.role.WithRoleId;
|
||||
import net.hostsharing.hsadminng.repr.Stringify;
|
||||
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||
import org.hibernate.annotations.GenericGenerator;
|
||||
@ -37,7 +38,7 @@ import static net.hostsharing.hsadminng.repr.Stringify.stringify;
|
||||
@SuperBuilder(toBuilder = true)
|
||||
@FieldNameConstants
|
||||
@DisplayAs("Contact")
|
||||
public class HsOfficeContact implements Stringifyable, BaseEntity<HsOfficeContact> {
|
||||
public class HsOfficeContact implements Stringifyable, BaseEntity<HsOfficeContact>, WithRoleId {
|
||||
|
||||
private static Stringify<HsOfficeContact> toString = stringify(HsOfficeContact.class, "contact")
|
||||
.withProp(Fields.caption, HsOfficeContact::getCaption)
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.hostsharing.hsadminng.hs.office.contact;
|
||||
|
||||
import io.micrometer.core.annotation.Timed;
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeContactsApi;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeContactInsertResource;
|
||||
@ -28,7 +28,7 @@ public class HsOfficeContactController implements HsOfficeContactsApi {
|
||||
private Context context;
|
||||
|
||||
@Autowired
|
||||
private StandardMapper mapper;
|
||||
private StrictMapper mapper;
|
||||
|
||||
@Autowired
|
||||
private HsOfficeContactRbacRepository contactRepo;
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
package net.hostsharing.hsadminng.hs.office.coopassets;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
@ -10,11 +9,22 @@ import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
||||
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacSpec;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacSpec.SQL;
|
||||
import net.hostsharing.hsadminng.repr.Stringify;
|
||||
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||
import org.hibernate.annotations.GenericGenerator;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EnumType;
|
||||
import jakarta.persistence.Enumerated;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.OneToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.persistence.Version;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
@ -57,8 +67,7 @@ public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, BaseE
|
||||
.quotedValues(false);
|
||||
|
||||
@Id
|
||||
@GeneratedValue(generator = "UUID")
|
||||
@GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
|
||||
@GeneratedValue
|
||||
private UUID uuid;
|
||||
|
||||
@Version
|
||||
@ -122,15 +131,15 @@ public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, BaseE
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getTaggedMemberNumber() {
|
||||
return ofNullable(membership).map(HsOfficeMembershipEntity::toShortString).orElse("M-???????");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return stringify.apply(this);
|
||||
}
|
||||
|
||||
public String getTaggedMemberNumber() {
|
||||
return ofNullable(membership).map(HsOfficeMembershipEntity::toShortString).orElse("M-???????");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toShortString() {
|
||||
return "%s:%.3s:%+1.2f".formatted(
|
||||
@ -141,7 +150,7 @@ public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, BaseE
|
||||
|
||||
public static RbacSpec rbac() {
|
||||
return rbacViewFor("coopAssetsTransaction", HsOfficeCoopAssetsTransactionEntity.class)
|
||||
.withIdentityView(RbacSpec.SQL.projection("reference"))
|
||||
.withIdentityView(SQL.projection("reference"))
|
||||
.withUpdatableColumns("comment")
|
||||
.importEntityAlias("membership", HsOfficeMembershipEntity.class, usingDefaultCase(),
|
||||
dependsOnColumn("membershipUuid"),
|
||||
|
@ -1,14 +1,13 @@
|
||||
package net.hostsharing.hsadminng.hs.office.coopshares;
|
||||
|
||||
import jakarta.persistence.EntityNotFoundException;
|
||||
|
||||
import io.micrometer.core.annotation.Timed;
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.errors.MultiValidationException;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeCoopSharesApi;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionInsertResource;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionResource;
|
||||
import net.hostsharing.hsadminng.errors.MultiValidationException;
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipRepository;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.springframework.format.annotation.DateTimeFormat.ISO;
|
||||
@ -25,6 +24,7 @@ import java.util.function.BiConsumer;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionTypeResource.CANCELLATION;
|
||||
import static net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionTypeResource.SUBSCRIPTION;
|
||||
import static net.hostsharing.hsadminng.hs.validation.UuidResolver.resolve;
|
||||
|
||||
@RestController
|
||||
public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopSharesApi {
|
||||
@ -33,14 +33,16 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar
|
||||
private Context context;
|
||||
|
||||
@Autowired
|
||||
private StandardMapper mapper;
|
||||
private StrictMapper mapper;
|
||||
|
||||
@Autowired
|
||||
private HsOfficeCoopSharesTransactionRepository coopSharesTransactionRepo;
|
||||
|
||||
@Autowired
|
||||
private HsOfficeMembershipRepository membershipRepo;
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
|
||||
@Timed("app.office.coopShares.api.getListOfCoopShares")
|
||||
public ResponseEntity<List<HsOfficeCoopSharesTransactionResource>> getListOfCoopShares(
|
||||
final String currentSubject,
|
||||
@ -55,7 +57,10 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar
|
||||
fromValueDate,
|
||||
toValueDate);
|
||||
|
||||
final var resources = mapper.mapList(entities, HsOfficeCoopSharesTransactionResource.class);
|
||||
final var resources = mapper.mapList(
|
||||
entities,
|
||||
HsOfficeCoopSharesTransactionResource.class,
|
||||
ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||
return ResponseEntity.ok(resources);
|
||||
}
|
||||
|
||||
@ -70,7 +75,10 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar
|
||||
context.define(currentSubject, assumedRoles);
|
||||
validate(requestBody);
|
||||
|
||||
final var entityToSave = mapper.map(requestBody, HsOfficeCoopSharesTransactionEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
|
||||
final var entityToSave = mapper.map(
|
||||
requestBody,
|
||||
HsOfficeCoopSharesTransactionEntity.class,
|
||||
RESOURCE_TO_ENTITY_POSTMAPPER);
|
||||
|
||||
final var saved = coopSharesTransactionRepo.save(entityToSave);
|
||||
|
||||
@ -79,7 +87,7 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar
|
||||
.path("/api/hs/office/coopsharestransactions/{id}")
|
||||
.buildAndExpand(saved.getUuid())
|
||||
.toUri();
|
||||
final var mapped = mapper.map(saved, HsOfficeCoopSharesTransactionResource.class);
|
||||
final var mapped = mapper.map(saved, HsOfficeCoopSharesTransactionResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||
return ResponseEntity.created(uri).body(mapped);
|
||||
}
|
||||
|
||||
@ -87,15 +95,18 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar
|
||||
@Transactional(readOnly = true)
|
||||
@Timed("app.office.coopShares.repo.getSingleCoopShareTransactionByUuid")
|
||||
public ResponseEntity<HsOfficeCoopSharesTransactionResource> getSingleCoopShareTransactionByUuid(
|
||||
final String currentSubject, final String assumedRoles, final UUID shareTransactionUuid) {
|
||||
final String currentSubject, final String assumedRoles, final UUID shareTransactionUuid) {
|
||||
|
||||
context.define(currentSubject, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = coopSharesTransactionRepo.findByUuid(shareTransactionUuid);
|
||||
if (result.isEmpty()) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
return ResponseEntity.ok(mapper.map(result.get(), HsOfficeCoopSharesTransactionResource.class));
|
||||
final var result = coopSharesTransactionRepo.findByUuid(shareTransactionUuid);
|
||||
if (result.isEmpty()) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
return ResponseEntity.ok(mapper.map(
|
||||
result.get(),
|
||||
HsOfficeCoopSharesTransactionResource.class,
|
||||
ENTITY_TO_RESOURCE_POSTMAPPER));
|
||||
|
||||
}
|
||||
|
||||
@ -137,9 +148,16 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar
|
||||
}
|
||||
|
||||
final BiConsumer<HsOfficeCoopSharesTransactionInsertResource, HsOfficeCoopSharesTransactionEntity> RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
|
||||
if ( resource.getRevertedShareTxUuid() != null ) {
|
||||
entity.setRevertedShareTx(coopSharesTransactionRepo.findByUuid(resource.getRevertedShareTxUuid())
|
||||
.orElseThrow(() -> new EntityNotFoundException("ERROR: [400] revertedShareTxUuid %s not found".formatted(resource.getRevertedShareTxUuid()))));
|
||||
entity.setMembership(resolve("membership.uuid", resource.getMembershipUuid(), membershipRepo::findByUuid));
|
||||
if (resource.getRevertedShareTxUuid() != null) {
|
||||
entity.setRevertedShareTx(resolve(
|
||||
"revertedShareTx.uuid",
|
||||
resource.getRevertedShareTxUuid(),
|
||||
coopSharesTransactionRepo::findByUuid));
|
||||
}
|
||||
};
|
||||
|
||||
final BiConsumer<HsOfficeCoopSharesTransactionEntity, HsOfficeCoopSharesTransactionResource> ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> {
|
||||
resource.setMembershipUuid(entity.getMembership().getUuid());
|
||||
};
|
||||
}
|
||||
|
@ -7,13 +7,23 @@ import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacSpec;
|
||||
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacSpec;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacSpec.SQL;
|
||||
import net.hostsharing.hsadminng.repr.Stringify;
|
||||
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EnumType;
|
||||
import jakarta.persistence.Enumerated;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.OneToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.persistence.Version;
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDate;
|
||||
import java.util.UUID;
|
||||
@ -132,6 +142,7 @@ public class HsOfficeCoopSharesTransactionEntity implements Stringifyable, BaseE
|
||||
directlyFetchedByDependsOnColumn(),
|
||||
NOT_NULL)
|
||||
|
||||
// the membership:ADMIN is not to be confused with the member itself, it's an account manager of the coop
|
||||
.toRole("membership", ADMIN).grantPermission(INSERT)
|
||||
.toRole("membership", ADMIN).grantPermission(UPDATE)
|
||||
.toRole("membership", AGENT).grantPermission(SELECT);
|
||||
|
@ -2,14 +2,16 @@ package net.hostsharing.hsadminng.hs.office.debitor;
|
||||
|
||||
import io.micrometer.core.annotation.Timed;
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountRepository;
|
||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeDebitorsApi;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorInsertResource;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorPatchResource;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorResource;
|
||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealRepository;
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.persistence.EntityExistsValidator;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.hibernate.Hibernate;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -26,6 +28,7 @@ import java.util.UUID;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.DEBITOR;
|
||||
import static net.hostsharing.hsadminng.hs.validation.UuidResolver.resolve;
|
||||
import static net.hostsharing.hsadminng.repr.TaggedNumber.cropTag;
|
||||
|
||||
@RestController
|
||||
@ -36,16 +39,22 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
||||
private Context context;
|
||||
|
||||
@Autowired
|
||||
private StandardMapper mapper;
|
||||
private StrictMapper mapper;
|
||||
|
||||
@Autowired
|
||||
private HsOfficeDebitorRepository debitorRepo;
|
||||
|
||||
@Autowired
|
||||
private HsOfficeRelationRealRepository relrealRepo;
|
||||
private HsOfficeRelationRealRepository realRelRepo;
|
||||
|
||||
@Autowired
|
||||
private EntityExistsValidator entityValidator;
|
||||
private HsOfficePersonRealRepository realPersonRepo;
|
||||
|
||||
@Autowired
|
||||
private HsOfficeContactRealRepository realContactRepo;
|
||||
|
||||
@Autowired
|
||||
private HsOfficeBankAccountRepository bankAccountRepo;
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager em;
|
||||
@ -63,9 +72,9 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
||||
|
||||
final var entities = partnerNumber != null
|
||||
? debitorRepo.findDebitorsByPartnerNumber(cropTag("P-", partnerNumber))
|
||||
: partnerUuid != null
|
||||
? debitorRepo.findDebitorsByPartnerUuid(partnerUuid)
|
||||
: debitorRepo.findDebitorsByOptionalNameLike(name);
|
||||
: partnerUuid != null
|
||||
? debitorRepo.findDebitorsByPartnerUuid(partnerUuid)
|
||||
: debitorRepo.findDebitorsByOptionalNameLike(name);
|
||||
|
||||
final var resources = mapper.mapList(entities, HsOfficeDebitorResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||
return ResponseEntity.ok(resources);
|
||||
@ -81,34 +90,19 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
||||
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
Validate.isTrue(body.getDebitorRel() == null || body.getDebitorRelUuid() == null,
|
||||
Validate.isTrue(
|
||||
body.getDebitorRel() == null || body.getDebitorRelUuid() == null,
|
||||
"ERROR: [400] exactly one of debitorRel and debitorRelUuid must be supplied, but found both");
|
||||
Validate.isTrue(body.getDebitorRel() != null || body.getDebitorRelUuid() != null,
|
||||
Validate.isTrue(
|
||||
body.getDebitorRel() != null || body.getDebitorRelUuid() != null,
|
||||
"ERROR: [400] exactly one of debitorRel and debitorRelUuid must be supplied, but found none");
|
||||
Validate.isTrue(body.getDebitorRel() == null || body.getDebitorRel().getMark() == null,
|
||||
Validate.isTrue(
|
||||
body.getDebitorRel() == null || body.getDebitorRel().getMark() == null,
|
||||
"ERROR: [400] debitorRel.mark must be null");
|
||||
|
||||
final var entityToSave = mapper.map(body, HsOfficeDebitorEntity.class);
|
||||
if (body.getDebitorRel() != null) {
|
||||
final var debitorRel = mapper.map("debitorRel.", body.getDebitorRel(), HsOfficeRelationRealEntity.class);
|
||||
debitorRel.setType(DEBITOR);
|
||||
entityValidator.validateEntityExists("debitorRel.anchorUuid", debitorRel.getAnchor());
|
||||
entityValidator.validateEntityExists("debitorRel.holderUuid", debitorRel.getHolder());
|
||||
entityValidator.validateEntityExists("debitorRel.contactUuid", debitorRel.getContact());
|
||||
entityToSave.setDebitorRel(relrealRepo.save(debitorRel));
|
||||
} else {
|
||||
final var debitorRelOptional = relrealRepo.findByUuid(body.getDebitorRelUuid());
|
||||
debitorRelOptional.ifPresentOrElse(
|
||||
debitorRel -> {entityToSave.setDebitorRel(relrealRepo.save(debitorRel));},
|
||||
() -> {
|
||||
throw new ValidationException(
|
||||
"Unable to find RealRelation by debitorRelUuid: " + body.getDebitorRelUuid());
|
||||
});
|
||||
}
|
||||
final var entityToSave = mapper.map(body, HsOfficeDebitorEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
|
||||
|
||||
final var savedEntity = debitorRepo.save(entityToSave);
|
||||
em.flush();
|
||||
em.refresh(savedEntity);
|
||||
final var savedEntity = debitorRepo.save(entityToSave).reload(em);
|
||||
|
||||
final var uri =
|
||||
MvcUriComponentsBuilder.fromController(getClass())
|
||||
@ -181,7 +175,7 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
||||
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var current = debitorRepo.findByUuid(debitorUuid).orElseThrow();
|
||||
final var current = debitorRepo.findByUuid(debitorUuid).orElseThrow().reload(em);
|
||||
|
||||
new HsOfficeDebitorEntityPatcher(em, current).apply(body);
|
||||
|
||||
@ -191,7 +185,39 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
||||
return ResponseEntity.ok(mapped);
|
||||
}
|
||||
|
||||
final BiConsumer<HsOfficeDebitorInsertResource, HsOfficeDebitorEntity> RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
|
||||
if (resource.getDebitorRel() != null) {
|
||||
final var debitorRel = realRelRepo.save(HsOfficeRelationRealEntity.builder()
|
||||
.type(DEBITOR)
|
||||
.anchor(resolve(
|
||||
"debitorRel.anchor.uuid", resource.getDebitorRel().getAnchorUuid(), realPersonRepo::findByUuid))
|
||||
.holder(resolve(
|
||||
"debitorRel.holder.uuid", resource.getDebitorRel().getHolderUuid(), realPersonRepo::findByUuid))
|
||||
.contact(resolve(
|
||||
"debitorRel.contact.uuid", resource.getDebitorRel().getContactUuid(), realContactRepo::findByUuid))
|
||||
.build());
|
||||
entity.setDebitorRel(debitorRel);
|
||||
} else {
|
||||
final var debitorRelOptional = realRelRepo.findByUuid(resource.getDebitorRelUuid());
|
||||
debitorRelOptional.ifPresentOrElse(
|
||||
debitorRel -> {
|
||||
entity.setDebitorRel(realRelRepo.save(debitorRel));
|
||||
},
|
||||
() -> {
|
||||
throw new ValidationException(
|
||||
"Unable to find debitorRel.uuid: " + resource.getDebitorRelUuid());
|
||||
});
|
||||
}
|
||||
|
||||
if (resource.getRefundBankAccountUuid() != null) {
|
||||
entity.setRefundBankAccount(resolve(
|
||||
"refundBankAccount.uuid", resource.getRefundBankAccountUuid(), bankAccountRepo::findByUuid));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
final BiConsumer<HsOfficeDebitorEntity, HsOfficeDebitorResource> ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> {
|
||||
resource.setDebitorNumber(entity.getTaggedDebitorNumber());
|
||||
resource.getPartner().setPartnerNumber(entity.getPartner().getTaggedPartnerNumber());
|
||||
};
|
||||
}
|
||||
|
@ -7,7 +7,8 @@ import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartner;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
|
||||
@ -16,7 +17,6 @@ import net.hostsharing.hsadminng.rbac.generator.RbacSpec;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacSpec.SQL;
|
||||
import net.hostsharing.hsadminng.repr.Stringify;
|
||||
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||
import org.hibernate.annotations.GenericGenerator;
|
||||
import org.hibernate.annotations.JoinFormula;
|
||||
import org.hibernate.annotations.NotFound;
|
||||
import org.hibernate.annotations.NotFoundAction;
|
||||
@ -75,7 +75,6 @@ public class HsOfficeDebitorEntity implements BaseEntity<HsOfficeDebitorEntity>,
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
@GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
|
||||
private UUID uuid;
|
||||
|
||||
@Version
|
||||
@ -87,16 +86,16 @@ public class HsOfficeDebitorEntity implements BaseEntity<HsOfficeDebitorEntity>,
|
||||
value = """
|
||||
(
|
||||
SELECT DISTINCT partner.uuid
|
||||
FROM hs_office.partner_rv partner
|
||||
FROM hs_office.partner partner
|
||||
JOIN hs_office.relation dRel
|
||||
ON dRel.uuid = debitorreluuid AND dRel.type = 'DEBITOR'
|
||||
ON dRel.uuid = debitorRelUuid AND dRel.type = 'DEBITOR'
|
||||
JOIN hs_office.relation pRel
|
||||
ON pRel.uuid = partner.partnerRelUuid AND pRel.type = 'PARTNER'
|
||||
WHERE pRel.holderUuid = dRel.anchorUuid
|
||||
)
|
||||
""")
|
||||
@NotFound(action = NotFoundAction.IGNORE) // TODO.impl: map a simplified raw-PartnerEntity, just for the partner-number
|
||||
private HsOfficePartnerEntity partner;
|
||||
@NotFound(action = NotFoundAction.EXCEPTION) // TODO.impl: map a simplified raw-PartnerEntity, just for the partner-number
|
||||
private HsOfficePartnerRealEntity partner;
|
||||
|
||||
@Column(name = "debitornumbersuffix", length = 2)
|
||||
@Pattern(regexp = TWO_DECIMAL_DIGITS)
|
||||
@ -132,9 +131,7 @@ public class HsOfficeDebitorEntity implements BaseEntity<HsOfficeDebitorEntity>,
|
||||
@Override
|
||||
public HsOfficeDebitorEntity load() {
|
||||
BaseEntity.super.load();
|
||||
if (partner != null) {
|
||||
partner.load();
|
||||
}
|
||||
partner.load();
|
||||
debitorRel.load();
|
||||
if (refundBankAccount != null) {
|
||||
refundBankAccount.load();
|
||||
@ -145,7 +142,7 @@ public class HsOfficeDebitorEntity implements BaseEntity<HsOfficeDebitorEntity>,
|
||||
public String getTaggedDebitorNumber() {
|
||||
return ofNullable(partner)
|
||||
.filter(partner -> debitorNumberSuffix != null)
|
||||
.map(HsOfficePartnerEntity::getPartnerNumber)
|
||||
.map(HsOfficePartner::getPartnerNumber)
|
||||
.map(partnerNumber -> DEBITOR_NUMBER_TAG + partnerNumber + debitorNumberSuffix)
|
||||
.orElse(null);
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ public interface HsOfficeDebitorRepository extends Repository<HsOfficeDebitorEnt
|
||||
|
||||
@Query("""
|
||||
SELECT debitor FROM HsOfficeDebitorEntity debitor
|
||||
JOIN HsOfficePartnerEntity partner
|
||||
JOIN HsOfficePartnerRealEntity partner
|
||||
ON partner.partnerRel.holder = debitor.debitorRel.anchor
|
||||
AND partner.partnerRel.type = 'PARTNER' AND debitor.debitorRel.type = 'DEBITOR'
|
||||
WHERE partner.partnerNumber = :partnerNumber
|
||||
@ -42,7 +42,7 @@ public interface HsOfficeDebitorRepository extends Repository<HsOfficeDebitorEnt
|
||||
|
||||
@Query("""
|
||||
SELECT debitor FROM HsOfficeDebitorEntity debitor
|
||||
JOIN HsOfficePartnerEntity partner
|
||||
JOIN HsOfficePartnerRealEntity partner
|
||||
ON partner.partnerRel.holder = debitor.debitorRel.anchor
|
||||
AND partner.partnerRel.type = 'PARTNER' AND debitor.debitorRel.type = 'DEBITOR'
|
||||
JOIN HsOfficePersonRealEntity person
|
||||
|
@ -6,14 +6,16 @@ import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeMembersh
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipInsertResource;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipPatchResource;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipResource;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealRepository;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
|
||||
|
||||
import jakarta.persistence.EntityNotFoundException;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.BiConsumer;
|
||||
@ -28,7 +30,10 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
|
||||
private Context context;
|
||||
|
||||
@Autowired
|
||||
private StandardMapper mapper;
|
||||
private StrictMapper mapper;
|
||||
|
||||
@Autowired
|
||||
private HsOfficePartnerRealRepository partnerRepo;
|
||||
|
||||
@Autowired
|
||||
private HsOfficeMembershipRepository membershipRepo;
|
||||
@ -47,7 +52,7 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
|
||||
|
||||
final var entities = partnerNumber != null
|
||||
? membershipRepo.findMembershipsByPartnerNumber(
|
||||
cropTag(HsOfficePartnerEntity.PARTNER_NUMBER_TAG, partnerNumber))
|
||||
cropTag(HsOfficePartnerRbacEntity.PARTNER_NUMBER_TAG, partnerNumber))
|
||||
: partnerUuid != null
|
||||
? membershipRepo.findMembershipsByPartnerUuid(partnerUuid)
|
||||
: membershipRepo.findAll();
|
||||
@ -68,7 +73,7 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
|
||||
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entityToSave = mapper.map(body, HsOfficeMembershipEntity.class);
|
||||
final var entityToSave = mapper.map(body, HsOfficeMembershipEntity.class, SEPA_MANDATE_RESOURCE_TO_ENTITY_POSTMAPPER);
|
||||
|
||||
final var saved = membershipRepo.save(entityToSave);
|
||||
|
||||
@ -164,5 +169,12 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
|
||||
if (entity.getValidity().hasUpperBound()) {
|
||||
resource.setValidTo(entity.getValidity().upper().minusDays(1));
|
||||
}
|
||||
resource.getPartner().setPartnerNumber(entity.getPartner().getTaggedPartnerNumber()); // TODO.refa: use partner mapper?
|
||||
};
|
||||
|
||||
final BiConsumer<HsOfficeMembershipInsertResource, HsOfficeMembershipEntity> SEPA_MANDATE_RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
|
||||
entity.setPartner(partnerRepo.findByUuid(resource.getPartnerUuid())
|
||||
.orElseThrow(() -> new EntityNotFoundException(
|
||||
"ERROR: [400] partnerUuid %s not found".formatted(resource.getPartnerUuid()))));
|
||||
};
|
||||
}
|
||||
|
@ -8,11 +8,12 @@ import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
|
||||
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacSpec;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacSpec.SQL;
|
||||
import net.hostsharing.hsadminng.rbac.role.WithRoleId;
|
||||
import net.hostsharing.hsadminng.repr.Stringify;
|
||||
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||
import org.hibernate.annotations.Type;
|
||||
@ -63,7 +64,7 @@ import static net.hostsharing.hsadminng.repr.Stringify.stringify;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@DisplayAs("Membership")
|
||||
public class HsOfficeMembershipEntity implements BaseEntity<HsOfficeMembershipEntity>, Stringifyable {
|
||||
public class HsOfficeMembershipEntity implements BaseEntity<HsOfficeMembershipEntity>, Stringifyable, WithRoleId {
|
||||
|
||||
public static final String MEMBER_NUMBER_TAG = "M-";
|
||||
public static final String TWO_DECIMAL_DIGITS = "^([0-9]{2})$";
|
||||
@ -84,7 +85,7 @@ public class HsOfficeMembershipEntity implements BaseEntity<HsOfficeMembershipEn
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "partneruuid")
|
||||
private HsOfficePartnerEntity partner;
|
||||
private HsOfficePartnerRealEntity partner;
|
||||
|
||||
@Column(name = "membernumbersuffix", length = 2)
|
||||
@Pattern(regexp = TWO_DECIMAL_DIGITS)
|
||||
|
@ -2,18 +2,18 @@ package net.hostsharing.hsadminng.hs.office.membership;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipPatchResource;
|
||||
import net.hostsharing.hsadminng.mapper.EntityPatcher;
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.mapper.OptionalFromJson;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class HsOfficeMembershipEntityPatcher implements EntityPatcher<HsOfficeMembershipPatchResource> {
|
||||
|
||||
private final StandardMapper mapper;
|
||||
private final StrictMapper mapper;
|
||||
private final HsOfficeMembershipEntity entity;
|
||||
|
||||
public HsOfficeMembershipEntityPatcher(
|
||||
final StandardMapper mapper,
|
||||
final StrictMapper mapper,
|
||||
final HsOfficeMembershipEntity entity) {
|
||||
this.mapper = mapper;
|
||||
this.entity = entity;
|
||||
|
@ -0,0 +1,103 @@
|
||||
package net.hostsharing.hsadminng.hs.office.partner;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContact;
|
||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePerson;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
||||
import net.hostsharing.hsadminng.repr.Stringify;
|
||||
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||
import org.hibernate.annotations.NotFound;
|
||||
import org.hibernate.annotations.NotFoundAction;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.MappedSuperclass;
|
||||
import jakarta.persistence.Version;
|
||||
import java.util.UUID;
|
||||
|
||||
import static jakarta.persistence.CascadeType.DETACH;
|
||||
import static jakarta.persistence.CascadeType.MERGE;
|
||||
import static jakarta.persistence.CascadeType.PERSIST;
|
||||
import static jakarta.persistence.CascadeType.REFRESH;
|
||||
import static java.util.Optional.ofNullable;
|
||||
import static net.hostsharing.hsadminng.repr.Stringify.stringify;
|
||||
|
||||
@MappedSuperclass
|
||||
@Getter
|
||||
@Setter
|
||||
@SuperBuilder(toBuilder = true)
|
||||
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
||||
@AllArgsConstructor(access = AccessLevel.PROTECTED)
|
||||
@DisplayAs("Partner")
|
||||
public class HsOfficePartner<T extends HsOfficePartner<?>> implements Stringifyable, BaseEntity<T> {
|
||||
|
||||
public static final String PARTNER_NUMBER_TAG = "P-";
|
||||
|
||||
protected static Stringify<HsOfficePartner> stringify = stringify(HsOfficePartner.class, "partner")
|
||||
.withIdProp(HsOfficePartner::toShortString)
|
||||
.withProp(p -> ofNullable(p.getPartnerRel())
|
||||
.map(HsOfficeRelation::getHolder)
|
||||
.map(HsOfficePerson::toShortString)
|
||||
.orElse(null))
|
||||
.withProp(p -> ofNullable(p.getPartnerRel())
|
||||
.map(HsOfficeRelation::getContact)
|
||||
.map(HsOfficeContact::toShortString)
|
||||
.orElse(null))
|
||||
.quotedValues(false);
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private UUID uuid;
|
||||
|
||||
@Version
|
||||
private int version;
|
||||
|
||||
@Column(name = "partnernumber", columnDefinition = "numeric(5) not null")
|
||||
private Integer partnerNumber;
|
||||
|
||||
@ManyToOne(cascade = { PERSIST, MERGE, REFRESH, DETACH }, optional = false, fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "partnerreluuid", nullable = false)
|
||||
private HsOfficeRelationRealEntity partnerRel;
|
||||
|
||||
@ManyToOne(cascade = { PERSIST, MERGE, REFRESH, DETACH }, optional = true, fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "detailsuuid")
|
||||
@NotFound(action = NotFoundAction.IGNORE)
|
||||
private HsOfficePartnerDetailsEntity details;
|
||||
|
||||
@Override
|
||||
public T load() {
|
||||
BaseEntity.super.load();
|
||||
partnerRel.load();
|
||||
if (details != null) {
|
||||
details.load();
|
||||
}
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public String getTaggedPartnerNumber() {
|
||||
return PARTNER_NUMBER_TAG + partnerNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return stringify.apply(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toShortString() {
|
||||
return getTaggedPartnerNumber();
|
||||
}
|
||||
}
|
@ -13,7 +13,7 @@ import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealRepository;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType;
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
@ -26,6 +26,7 @@ import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.PersistenceContext;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.EX_PARTNER;
|
||||
import static net.hostsharing.hsadminng.repr.TaggedNumber.cropTag;
|
||||
@ -38,10 +39,10 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
||||
private Context context;
|
||||
|
||||
@Autowired
|
||||
private StandardMapper mapper;
|
||||
private StrictMapper mapper;
|
||||
|
||||
@Autowired
|
||||
private HsOfficePartnerRepository partnerRepo;
|
||||
private HsOfficePartnerRbacRepository partnerRepo;
|
||||
|
||||
@Autowired
|
||||
private HsOfficeRelationRealRepository relationRepo;
|
||||
@ -60,7 +61,7 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
||||
|
||||
final var entities = partnerRepo.findPartnerByOptionalNameLike(name);
|
||||
|
||||
final var resources = mapper.mapList(entities, HsOfficePartnerResource.class);
|
||||
final var resources = mapper.mapList(entities, HsOfficePartnerResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||
return ResponseEntity.ok(resources);
|
||||
}
|
||||
|
||||
@ -83,7 +84,7 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
||||
.path("/api/hs/office/partners/{id}")
|
||||
.buildAndExpand(saved.getUuid())
|
||||
.toUri();
|
||||
final var mapped = mapper.map(saved, HsOfficePartnerResource.class);
|
||||
final var mapped = mapper.map(saved, HsOfficePartnerResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||
return ResponseEntity.created(uri).body(mapped);
|
||||
}
|
||||
|
||||
@ -101,7 +102,8 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
||||
if (result.isEmpty()) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
return ResponseEntity.ok(mapper.map(result.get(), HsOfficePartnerResource.class));
|
||||
final var mapped = mapper.map(result.get(), HsOfficePartnerResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||
return ResponseEntity.ok(mapped);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -118,7 +120,8 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
||||
if (result.isEmpty()) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
return ResponseEntity.ok(mapper.map(result.get(), HsOfficePartnerResource.class));
|
||||
final var mapped = mapper.map(result.get(), HsOfficePartnerResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||
return ResponseEntity.ok(mapped);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -161,20 +164,20 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
||||
final var saved = partnerRepo.save(current);
|
||||
optionallyCreateExPartnerRelation(saved, previousPartnerRel);
|
||||
|
||||
final var mapped = mapper.map(saved, HsOfficePartnerResource.class);
|
||||
final var mapped = mapper.map(saved, HsOfficePartnerResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||
return ResponseEntity.ok(mapped);
|
||||
}
|
||||
|
||||
private void optionallyCreateExPartnerRelation(final HsOfficePartnerEntity saved, final HsOfficeRelationRealEntity previousPartnerRel) {
|
||||
private void optionallyCreateExPartnerRelation(final HsOfficePartnerRbacEntity saved, final HsOfficeRelationRealEntity previousPartnerRel) {
|
||||
if (!saved.getPartnerRel().getUuid().equals(previousPartnerRel.getUuid())) {
|
||||
// TODO.impl: we also need to use the new partner-person as the anchor
|
||||
relationRepo.save(previousPartnerRel.toBuilder().uuid(null).type(EX_PARTNER).build());
|
||||
}
|
||||
}
|
||||
|
||||
private HsOfficePartnerEntity createPartnerEntity(final HsOfficePartnerInsertResource body) {
|
||||
final var entityToSave = new HsOfficePartnerEntity();
|
||||
entityToSave.setPartnerNumber(cropTag(HsOfficePartnerEntity.PARTNER_NUMBER_TAG, body.getPartnerNumber()));
|
||||
private HsOfficePartnerRbacEntity createPartnerEntity(final HsOfficePartnerInsertResource body) {
|
||||
final var entityToSave = new HsOfficePartnerRbacEntity();
|
||||
entityToSave.setPartnerNumber(cropTag(HsOfficePartnerRbacEntity.PARTNER_NUMBER_TAG, body.getPartnerNumber()));
|
||||
entityToSave.setPartnerRel(persistPartnerRel(body.getPartnerRel()));
|
||||
entityToSave.setDetails(mapper.map(body.getDetails(), HsOfficePartnerDetailsEntity.class));
|
||||
return entityToSave;
|
||||
@ -197,4 +200,8 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
||||
throw new ReferenceNotFoundException(entityClass, uuid, exc);
|
||||
}
|
||||
}
|
||||
|
||||
final BiConsumer<HsOfficePartnerRbacEntity, HsOfficePartnerResource> ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> {
|
||||
resource.setPartnerNumber(entity.getTaggedPartnerNumber());
|
||||
};
|
||||
}
|
||||
|
@ -1,128 +0,0 @@
|
||||
package net.hostsharing.hsadminng.hs.office.partner;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContact;
|
||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePerson;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
|
||||
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacSpec;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacSpec.SQL;
|
||||
import net.hostsharing.hsadminng.repr.Stringify;
|
||||
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||
import org.hibernate.annotations.NotFound;
|
||||
import org.hibernate.annotations.NotFoundAction;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
import static jakarta.persistence.CascadeType.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.Column.dependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.GLOBAL;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.Permission.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.Permission.SELECT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.Role.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.SQL.directlyFetchedByDependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.rbacViewFor;
|
||||
import static java.util.Optional.ofNullable;
|
||||
import static net.hostsharing.hsadminng.repr.Stringify.stringify;
|
||||
|
||||
@Entity
|
||||
@Table(schema = "hs_office", name = "partner_rv")
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@DisplayAs("Partner")
|
||||
public class HsOfficePartnerEntity implements Stringifyable, BaseEntity<HsOfficePartnerEntity> {
|
||||
|
||||
public static final String PARTNER_NUMBER_TAG = "P-";
|
||||
|
||||
private static Stringify<HsOfficePartnerEntity> stringify = stringify(HsOfficePartnerEntity.class, "partner")
|
||||
.withIdProp(HsOfficePartnerEntity::toShortString)
|
||||
.withProp(p -> ofNullable(p.getPartnerRel())
|
||||
.map(HsOfficeRelation::getHolder)
|
||||
.map(HsOfficePerson::toShortString)
|
||||
.orElse(null))
|
||||
.withProp(p -> ofNullable(p.getPartnerRel())
|
||||
.map(HsOfficeRelation::getContact)
|
||||
.map(HsOfficeContact::toShortString)
|
||||
.orElse(null))
|
||||
.quotedValues(false);
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private UUID uuid;
|
||||
|
||||
@Version
|
||||
private int version;
|
||||
|
||||
@Column(name = "partnernumber", columnDefinition = "numeric(5) not null")
|
||||
private Integer partnerNumber;
|
||||
|
||||
@ManyToOne(cascade = { PERSIST, MERGE, REFRESH, DETACH }, optional = false, fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "partnerreluuid", nullable = false)
|
||||
private HsOfficeRelationRealEntity partnerRel;
|
||||
|
||||
@ManyToOne(cascade = { PERSIST, MERGE, REFRESH, DETACH }, optional = true, fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "detailsuuid")
|
||||
@NotFound(action = NotFoundAction.IGNORE)
|
||||
private HsOfficePartnerDetailsEntity details;
|
||||
|
||||
@Override
|
||||
public HsOfficePartnerEntity load() {
|
||||
BaseEntity.super.load();
|
||||
partnerRel.load();
|
||||
details.load();
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getTaggedPartnerNumber() {
|
||||
return PARTNER_NUMBER_TAG + partnerNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return stringify.apply(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toShortString() {
|
||||
return getTaggedPartnerNumber();
|
||||
}
|
||||
|
||||
public static RbacSpec rbac() {
|
||||
return rbacViewFor("partner", HsOfficePartnerEntity.class)
|
||||
.withIdentityView(SQL.projection("'P-' || partnerNumber"))
|
||||
.withUpdatableColumns("partnerRelUuid")
|
||||
.toRole(GLOBAL, ADMIN).grantPermission(INSERT)
|
||||
|
||||
.importRootEntityAliasProxy("partnerRel", HsOfficeRelationRbacEntity.class,
|
||||
usingDefaultCase(),
|
||||
directlyFetchedByDependsOnColumn(),
|
||||
dependsOnColumn("partnerRelUuid"))
|
||||
.createPermission(DELETE).grantedTo("partnerRel", OWNER)
|
||||
.createPermission(UPDATE).grantedTo("partnerRel", ADMIN)
|
||||
.createPermission(SELECT).grantedTo("partnerRel", TENANT)
|
||||
|
||||
.importSubEntityAlias("partnerDetails", HsOfficePartnerDetailsEntity.class,
|
||||
directlyFetchedByDependsOnColumn(),
|
||||
dependsOnColumn("detailsUuid"))
|
||||
.createPermission("partnerDetails", DELETE).grantedTo("partnerRel", OWNER)
|
||||
.createPermission("partnerDetails", UPDATE).grantedTo("partnerRel", AGENT)
|
||||
.createPermission("partnerDetails", SELECT).grantedTo("partnerRel", AGENT); // not TENANT!
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
rbac().generateWithBaseFileName("5-hs-office/504-partner/5043-hs-office-partner-rbac");
|
||||
}
|
||||
}
|
@ -9,10 +9,10 @@ import jakarta.persistence.EntityManager;
|
||||
|
||||
class HsOfficePartnerEntityPatcher implements EntityPatcher<HsOfficePartnerPatchResource> {
|
||||
private final EntityManager em;
|
||||
private final HsOfficePartnerEntity entity;
|
||||
private final HsOfficePartnerRbacEntity entity;
|
||||
HsOfficePartnerEntityPatcher(
|
||||
final EntityManager em,
|
||||
final HsOfficePartnerEntity entity) {
|
||||
final HsOfficePartnerRbacEntity entity) {
|
||||
this.em = em;
|
||||
this.entity = entity;
|
||||
}
|
||||
|
@ -0,0 +1,59 @@
|
||||
package net.hostsharing.hsadminng.hs.office.partner;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacSpec;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacSpec.SQL;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import java.io.IOException;
|
||||
|
||||
import static jakarta.persistence.CascadeType.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.Column.dependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.GLOBAL;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.Permission.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.Permission.SELECT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.Role.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.SQL.directlyFetchedByDependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.rbacViewFor;
|
||||
|
||||
@Entity
|
||||
@Table(schema = "hs_office", name = "partner_rv")
|
||||
@Getter
|
||||
@Setter
|
||||
@SuperBuilder(toBuilder = true)
|
||||
@NoArgsConstructor
|
||||
@DisplayAs("RbacPartner")
|
||||
public class HsOfficePartnerRbacEntity extends HsOfficePartner<HsOfficePartnerRbacEntity> {
|
||||
|
||||
public static RbacSpec rbac() {
|
||||
return rbacViewFor("partner", HsOfficePartnerRbacEntity.class)
|
||||
.withIdentityView(SQL.projection("'P-' || partnerNumber"))
|
||||
.withUpdatableColumns("partnerRelUuid")
|
||||
.toRole(GLOBAL, ADMIN).grantPermission(INSERT)
|
||||
|
||||
.importRootEntityAliasProxy("partnerRel", HsOfficeRelationRbacEntity.class,
|
||||
usingDefaultCase(),
|
||||
directlyFetchedByDependsOnColumn(),
|
||||
dependsOnColumn("partnerRelUuid"))
|
||||
.createPermission(DELETE).grantedTo("partnerRel", OWNER)
|
||||
.createPermission(UPDATE).grantedTo("partnerRel", ADMIN)
|
||||
.createPermission(SELECT).grantedTo("partnerRel", TENANT)
|
||||
|
||||
.importSubEntityAlias("partnerDetails", HsOfficePartnerDetailsEntity.class,
|
||||
directlyFetchedByDependsOnColumn(),
|
||||
dependsOnColumn("detailsUuid"))
|
||||
.createPermission("partnerDetails", DELETE).grantedTo("partnerRel", OWNER)
|
||||
.createPermission("partnerDetails", UPDATE).grantedTo("partnerRel", AGENT)
|
||||
.createPermission("partnerDetails", SELECT).grantedTo("partnerRel", AGENT); // not TENANT!
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
rbac().generateWithBaseFileName("5-hs-office/504-partner/5043-hs-office-partner-rbac");
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package net.hostsharing.hsadminng.hs.office.partner;
|
||||
|
||||
import io.micrometer.core.annotation.Timed;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface HsOfficePartnerRbacRepository extends Repository<HsOfficePartnerRbacEntity, UUID> {
|
||||
|
||||
@Timed("app.office.partners.repo.findByUuid.rbac")
|
||||
Optional<HsOfficePartnerRbacEntity> findByUuid(UUID id);
|
||||
|
||||
@Timed("app.office.partners.repo.findAll.rbac")
|
||||
List<HsOfficePartnerRbacEntity> findAll(); // TODO.refa: move to a repo in test sources
|
||||
|
||||
@Query(value = """
|
||||
select partner.uuid, partner.detailsuuid, partner.partnernumber, partner.partnerreluuid, partner.version
|
||||
from hs_office.partner_rv partner
|
||||
join hs_office.relation partnerRel on partnerRel.uuid = partner.partnerreluuid
|
||||
join hs_office.contact contact on contact.uuid = partnerRel.contactuuid
|
||||
join hs_office.person partnerPerson on partnerPerson.uuid = partnerRel.holderuuid
|
||||
left join hs_office.partner_details_rv partnerDetails on partnerDetails.uuid = partner.detailsuuid
|
||||
where :name is null
|
||||
or (partnerDetails.uuid is not null and partnerDetails.birthname like (cast(:name as text) || '%') escape '')
|
||||
or contact.caption like (cast(:name as text) || '%') escape ''
|
||||
or partnerPerson.tradename like (cast(:name as text) || '%') escape ''
|
||||
or partnerPerson.givenname like (cast(:name as text) || '%') escape ''
|
||||
or partnerPerson.familyname like (cast(:name as text) || '%') escape ''
|
||||
""", nativeQuery = true)
|
||||
@Timed("app.office.partners.repo.findPartnerByOptionalNameLike.rbac")
|
||||
List<HsOfficePartnerRbacEntity> findPartnerByOptionalNameLike(String name);
|
||||
|
||||
@Timed("app.office.partners.repo.findPartnerByPartnerNumber.rbac")
|
||||
Optional<HsOfficePartnerRbacEntity> findPartnerByPartnerNumber(Integer partnerNumber);
|
||||
|
||||
@Timed("app.office.partners.repo.save.rbac")
|
||||
HsOfficePartnerRbacEntity save(final HsOfficePartnerRbacEntity entity);
|
||||
|
||||
@Timed("app.office.partners.repo.count.rbac")
|
||||
long count();
|
||||
|
||||
@Timed("app.office.partners.repo.deleteByUuid.rbac")
|
||||
int deleteByUuid(UUID uuid);
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package net.hostsharing.hsadminng.hs.office.partner;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
|
||||
@Entity
|
||||
@Table(schema = "hs_office", name = "partner")
|
||||
@Getter
|
||||
@Setter
|
||||
@SuperBuilder(toBuilder = true)
|
||||
@NoArgsConstructor
|
||||
@DisplayAs("RealPartner")
|
||||
public class HsOfficePartnerRealEntity extends HsOfficePartner<HsOfficePartnerRealEntity> {
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package net.hostsharing.hsadminng.hs.office.partner;
|
||||
|
||||
import io.micrometer.core.annotation.Timed;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface HsOfficePartnerRealRepository extends Repository<HsOfficePartnerRealEntity, UUID> {
|
||||
|
||||
@Timed("app.office.partners.repo.findByUuid.real")
|
||||
Optional<HsOfficePartnerRealEntity> findByUuid(UUID id);
|
||||
|
||||
@Timed("app.office.partners.repo.findAll.real")
|
||||
List<HsOfficePartnerRbacEntity> findAll(); // TODO.refa: move to a repo in test sources
|
||||
|
||||
@Query(value = """
|
||||
select partner.uuid, partner.detailsuuid, partner.partnernumber, partner.partnerreluuid, partner.version
|
||||
from hs_office.partner partner
|
||||
join hs_office.relation partnerRel on partnerRel.uuid = partner.partnerreluuid
|
||||
join hs_office.contact contact on contact.uuid = partnerRel.contactuuid
|
||||
join hs_office.person partnerPerson on partnerPerson.uuid = partnerRel.holderuuid
|
||||
left join hs_office.partner_details_rv partnerDetails on partnerDetails.uuid = partner.detailsuuid
|
||||
where :name is null
|
||||
or (partnerDetails.uuid is not null and partnerDetails.birthname like (cast(:name as text) || '%') escape '')
|
||||
or contact.caption like (cast(:name as text) || '%') escape ''
|
||||
or partnerPerson.tradename like (cast(:name as text) || '%') escape ''
|
||||
or partnerPerson.givenname like (cast(:name as text) || '%') escape ''
|
||||
or partnerPerson.familyname like (cast(:name as text) || '%') escape ''
|
||||
""", nativeQuery = true)
|
||||
@Timed("app.office.partners.repo.findPartnerByOptionalNameLike.real")
|
||||
List<HsOfficePartnerRealEntity> findPartnerByOptionalNameLike(String name);
|
||||
|
||||
@Timed("app.office.partners.repo.findPartnerByPartnerNumber.real")
|
||||
Optional<HsOfficePartnerRealEntity> findPartnerByPartnerNumber(Integer partnerNumber);
|
||||
|
||||
@Timed("app.office.partners.repo.save.real")
|
||||
HsOfficePartnerRealEntity save(final HsOfficePartnerRealEntity entity);
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package net.hostsharing.hsadminng.hs.office.partner;
|
||||
|
||||
import io.micrometer.core.annotation.Timed;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface HsOfficePartnerRepository extends Repository<HsOfficePartnerEntity, UUID> {
|
||||
|
||||
@Timed("app.office.partners.repo.findByUuid")
|
||||
Optional<HsOfficePartnerEntity> findByUuid(UUID id);
|
||||
|
||||
@Timed("app.office.partners.repo.findAll")
|
||||
List<HsOfficePartnerEntity> findAll(); // TODO.refa: move to a repo in test sources
|
||||
|
||||
@Query("""
|
||||
SELECT partner FROM HsOfficePartnerEntity partner
|
||||
JOIN HsOfficeRelationRealEntity rel ON rel.uuid = partner.partnerRel.uuid
|
||||
JOIN HsOfficeContactRealEntity contact ON contact.uuid = rel.contact.uuid
|
||||
JOIN HsOfficePersonRealEntity person ON person.uuid = rel.holder.uuid
|
||||
WHERE :name is null
|
||||
OR partner.details.birthName like concat(cast(:name as text), '%')
|
||||
OR contact.caption like concat(cast(:name as text), '%')
|
||||
OR person.tradeName like concat(cast(:name as text), '%')
|
||||
OR person.givenName like concat(cast(:name as text), '%')
|
||||
OR person.familyName like concat(cast(:name as text), '%')
|
||||
""")
|
||||
@Timed("app.office.partners.repo.findPartnerByOptionalNameLike")
|
||||
List<HsOfficePartnerEntity> findPartnerByOptionalNameLike(String name);
|
||||
|
||||
@Timed("app.office.partners.repo.findPartnerByPartnerNumber")
|
||||
Optional<HsOfficePartnerEntity> findPartnerByPartnerNumber(Integer partnerNumber);
|
||||
|
||||
@Timed("app.office.partners.repo.save")
|
||||
HsOfficePartnerEntity save(final HsOfficePartnerEntity entity);
|
||||
|
||||
@Timed("app.office.partners.repo.count")
|
||||
long count();
|
||||
|
||||
@Timed("app.office.partners.repo.deleteByUuid")
|
||||
int deleteByUuid(UUID uuid);
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package net.hostsharing.hsadminng.hs.office.person;
|
||||
|
||||
import io.micrometer.core.annotation.Timed;
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficePersonsApi;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePersonInsertResource;
|
||||
@ -24,7 +24,7 @@ public class HsOfficePersonController implements HsOfficePersonsApi {
|
||||
private Context context;
|
||||
|
||||
@Autowired
|
||||
private StandardMapper mapper;
|
||||
private StrictMapper mapper;
|
||||
|
||||
@Autowired
|
||||
private HsOfficePersonRbacRepository personRepo;
|
||||
|
@ -3,7 +3,6 @@ package net.hostsharing.hsadminng.hs.office.person;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.FieldNameConstants;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||
|
||||
@ -17,7 +16,6 @@ import jakarta.persistence.Table;
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@SuperBuilder(toBuilder = true)
|
||||
@FieldNameConstants
|
||||
@DisplayAs("RealPerson")
|
||||
public class HsOfficePersonRealEntity extends HsOfficePerson<HsOfficePersonRealEntity> {
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeRelation
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.*;
|
||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository;
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@ -32,7 +32,7 @@ public class HsOfficeRelationController implements HsOfficeRelationsApi {
|
||||
private Context context;
|
||||
|
||||
@Autowired
|
||||
private StandardMapper mapper;
|
||||
private StrictMapper mapper;
|
||||
|
||||
@Autowired
|
||||
private HsOfficeRelationRbacRepository rbacRelationRepo;
|
||||
|
@ -2,11 +2,14 @@ package net.hostsharing.hsadminng.hs.office.sepamandate;
|
||||
|
||||
import io.micrometer.core.annotation.Timed;
|
||||
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.hsadminng.hs.office.generated.api.v1.api.HsOfficeSepaMandatesApi;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorResource;
|
||||
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.StandardMapper;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@ -15,6 +18,7 @@ import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBui
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.PersistenceContext;
|
||||
import jakarta.validation.ValidationException;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.BiConsumer;
|
||||
@ -29,7 +33,13 @@ public class HsOfficeSepaMandateController implements HsOfficeSepaMandatesApi {
|
||||
private Context context;
|
||||
|
||||
@Autowired
|
||||
private StandardMapper mapper;
|
||||
private StrictMapper mapper;
|
||||
|
||||
@Autowired
|
||||
private HsOfficeDebitorRepository debitorRepo;
|
||||
|
||||
@Autowired
|
||||
private HsOfficeBankAccountRepository bankAccountRepo;
|
||||
|
||||
@Autowired
|
||||
private HsOfficeSepaMandateRepository sepaMandateRepo;
|
||||
@ -137,10 +147,22 @@ public class HsOfficeSepaMandateController implements HsOfficeSepaMandatesApi {
|
||||
if (entity.getValidity().hasUpperBound()) {
|
||||
resource.setValidTo(entity.getValidity().upper().minusDays(1));
|
||||
}
|
||||
resource.setDebitor(mapper.map(entity.getDebitor(), HsOfficeDebitorResource.class));
|
||||
resource.getDebitor().setDebitorNumber(entity.getDebitor().getTaggedDebitorNumber());
|
||||
resource.getDebitor().getPartner().setPartnerNumber(entity.getDebitor().getPartner().getTaggedPartnerNumber());
|
||||
};
|
||||
|
||||
final BiConsumer<HsOfficeSepaMandateInsertResource, HsOfficeSepaMandateEntity> SEPA_MANDATE_RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
|
||||
entity.setValidity(toPostgresDateRange(resource.getValidFrom(), resource.getValidTo()));
|
||||
entity.setDebitor(debitorRepo.findByUuid(resource.getDebitorUuid()).orElseThrow( () ->
|
||||
new ValidationException(
|
||||
"debitor.uuid='" + resource.getDebitorUuid() + "' not found or not accessible"
|
||||
)
|
||||
));
|
||||
entity.setBankAccount(bankAccountRepo.findByUuid(resource.getBankAccountUuid()).orElseThrow( () ->
|
||||
new ValidationException(
|
||||
"bankAccount.uuid='" + resource.getBankAccountUuid() + "' not found or not accessible"
|
||||
)
|
||||
));
|
||||
};
|
||||
}
|
||||
|
@ -0,0 +1,17 @@
|
||||
package net.hostsharing.hsadminng.hs.validation;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
import jakarta.validation.ValidationException;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
|
||||
@UtilityClass
|
||||
public class UuidResolver {
|
||||
|
||||
public static <T> T resolve(final String jsonPath, final UUID uuid, final Function<UUID, Optional<T>> findByUuid) {
|
||||
return findByUuid.apply(uuid)
|
||||
.orElseThrow(() -> new ValidationException("Unable to find " + jsonPath + ": " + uuid));
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package net.hostsharing.hsadminng.mapper;
|
||||
|
||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* A nicer API for ModelMapper in standard mode.
|
||||
*/
|
||||
@Component
|
||||
public class StandardMapper extends Mapper {
|
||||
|
||||
public StandardMapper(@Autowired final EntityManagerWrapper em) {
|
||||
super(em);
|
||||
getConfiguration().setAmbiguityIgnored(true);
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ package net.hostsharing.hsadminng.persistence;
|
||||
|
||||
import org.hibernate.Hibernate;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface BaseEntity<T extends BaseEntity<?>> {
|
||||
@ -15,4 +16,10 @@ public interface BaseEntity<T extends BaseEntity<?>> {
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
};
|
||||
|
||||
default T reload(final EntityManager em) {
|
||||
em.flush();
|
||||
em.refresh(this);
|
||||
return load();
|
||||
}
|
||||
}
|
||||
|
@ -1,38 +0,0 @@
|
||||
package net.hostsharing.hsadminng.persistence;
|
||||
|
||||
import net.hostsharing.hsadminng.errors.DisplayAs.DisplayName;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.validation.ValidationException;
|
||||
|
||||
@Service
|
||||
public class EntityExistsValidator {
|
||||
|
||||
@Autowired
|
||||
private EntityManagerWrapper em;
|
||||
|
||||
public <T extends BaseEntity<T>> void validateEntityExists(final String property, final T entitySkeleton) {
|
||||
final var foundEntity = em.find(entityClass(entitySkeleton), entitySkeleton.getUuid());
|
||||
if ( foundEntity == null) {
|
||||
throw new ValidationException("Unable to find " + DisplayName.of(entitySkeleton) + " by " + property + ": " + entitySkeleton.getUuid());
|
||||
}
|
||||
}
|
||||
|
||||
private static <T extends BaseEntity<T>> Class<?> entityClass(final T entityOrProxy) {
|
||||
final var entityClass = entityClass(entityOrProxy.getClass());
|
||||
if (entityClass == null) {
|
||||
throw new IllegalArgumentException("@Entity not found in superclass hierarchy of " + entityOrProxy.getClass());
|
||||
}
|
||||
return entityClass;
|
||||
}
|
||||
|
||||
private static Class<?> entityClass(final Class<?> entityOrProxyClass) {
|
||||
return entityOrProxyClass.isAnnotationPresent(Entity.class)
|
||||
? entityOrProxyClass
|
||||
: entityOrProxyClass.getSuperclass() == null
|
||||
? null
|
||||
: entityClass(entityOrProxyClass.getSuperclass());
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.rbac.grant;
|
||||
|
||||
import io.micrometer.core.annotation.Timed;
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import net.hostsharing.hsadminng.rbac.generated.api.v1.api.RbacGrantsApi;
|
||||
import net.hostsharing.hsadminng.rbac.generated.api.v1.model.RbacGrantResource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -23,7 +23,7 @@ public class RbacGrantController implements RbacGrantsApi {
|
||||
private Context context;
|
||||
|
||||
@Autowired
|
||||
private StandardMapper mapper;
|
||||
private StrictMapper mapper;
|
||||
|
||||
@Autowired
|
||||
private RbacGrantRepository rbacGrantRepository;
|
||||
|
@ -30,7 +30,7 @@ public class RbacGrantsDiagramService {
|
||||
try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {
|
||||
writer.write("""
|
||||
### all grants to %s
|
||||
|
||||
|
||||
```mermaid
|
||||
%s
|
||||
```
|
||||
@ -49,8 +49,18 @@ public class RbacGrantsDiagramService {
|
||||
NON_TEST_ENTITIES;
|
||||
|
||||
public static final EnumSet<Include> ALL = EnumSet.allOf(Include.class);
|
||||
public static final EnumSet<Include> ALL_TEST_ENTITY_RELATED = EnumSet.of(USERS, DETAILS, NOT_ASSUMED, TEST_ENTITIES, PERMISSIONS);
|
||||
public static final EnumSet<Include> ALL_NON_TEST_ENTITY_RELATED = EnumSet.of(USERS, DETAILS, NOT_ASSUMED, NON_TEST_ENTITIES, PERMISSIONS);
|
||||
public static final EnumSet<Include> ALL_TEST_ENTITY_RELATED = EnumSet.of(
|
||||
USERS,
|
||||
DETAILS,
|
||||
NOT_ASSUMED,
|
||||
TEST_ENTITIES,
|
||||
PERMISSIONS);
|
||||
public static final EnumSet<Include> ALL_NON_TEST_ENTITY_RELATED = EnumSet.of(
|
||||
USERS,
|
||||
DETAILS,
|
||||
NOT_ASSUMED,
|
||||
NON_TEST_ENTITIES,
|
||||
PERMISSIONS);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
@ -66,9 +76,9 @@ public class RbacGrantsDiagramService {
|
||||
|
||||
public String allGrantsTocurrentSubject(final EnumSet<Include> includes) {
|
||||
final var graph = new LimitedHashSet<RawRbacGrantEntity>();
|
||||
for ( UUID subjectUuid: context.fetchCurrentSubjectOrAssumedRolesUuids() ) {
|
||||
for (UUID subjectUuid : context.fetchCurrentSubjectOrAssumedRolesUuids()) {
|
||||
traverseGrantsTo(graph, subjectUuid, includes);
|
||||
}
|
||||
}
|
||||
return toMermaidFlowchart(graph, includes);
|
||||
}
|
||||
|
||||
@ -78,7 +88,7 @@ public class RbacGrantsDiagramService {
|
||||
if (!includes.contains(PERMISSIONS) && g.getDescendantIdName().startsWith("perm:")) {
|
||||
return;
|
||||
}
|
||||
if ( !g.getDescendantIdName().startsWith("role:rbac.global")) {
|
||||
if (!g.getDescendantIdName().startsWith("role:rbac.global")) {
|
||||
if (!includes.contains(TEST_ENTITIES) && g.getDescendantIdName().contains(":rbactest.")) {
|
||||
return;
|
||||
}
|
||||
@ -94,12 +104,17 @@ public class RbacGrantsDiagramService {
|
||||
}
|
||||
|
||||
public String allGrantsFrom(final UUID targetObject, final String op, final EnumSet<Include> includes) {
|
||||
final var refUuid = (UUID) em.createNativeQuery("SELECT uuid FROM rbac.permission WHERE objectuuid=:targetObject AND op=:op")
|
||||
final var graph = new LimitedHashSet<RawRbacGrantEntity>();
|
||||
|
||||
@SuppressWarnings("unchecked") // List -> List<List<UUID>>
|
||||
final var refUuidLists = (List<List<UUID>>) em.createNativeQuery(
|
||||
"select uuid from rbac.permission where objectUuid=:targetObject and op=:op",
|
||||
List.class)
|
||||
.setParameter("targetObject", targetObject)
|
||||
.setParameter("op", op)
|
||||
.getSingleResult();
|
||||
final var graph = new LimitedHashSet<RawRbacGrantEntity>();
|
||||
traverseGrantsFrom(graph, refUuid, includes);
|
||||
.getResultList();
|
||||
refUuidLists.stream().flatMap(Collection::stream)
|
||||
.forEach(refUuid -> traverseGrantsFrom(graph, refUuid, includes));
|
||||
return toMermaidFlowchart(graph, includes);
|
||||
}
|
||||
|
||||
@ -125,20 +140,20 @@ public class RbacGrantsDiagramService {
|
||||
final var entities =
|
||||
includes.contains(DETAILS)
|
||||
? graph.stream()
|
||||
.flatMap(g -> Stream.of(
|
||||
new Node(g.getAscendantIdName(), g.getAscendingUuid()),
|
||||
new Node(g.getDescendantIdName(), g.getDescendantUuid()))
|
||||
)
|
||||
.collect(groupingBy(RbacGrantsDiagramService::renderEntityIdName))
|
||||
.entrySet().stream()
|
||||
.map(entity -> "subgraph " + cleanId(entity.getKey()) + renderSubgraph(entity.getKey()) + "\n\n "
|
||||
+ entity.getValue().stream()
|
||||
.map(n -> renderNode(n.idName(), n.uuid()).replace("\n", "\n "))
|
||||
.sorted()
|
||||
.distinct()
|
||||
.collect(joining("\n\n ")))
|
||||
.collect(joining("\n\nend\n\n"))
|
||||
+ "\n\nend\n\n"
|
||||
.flatMap(g -> Stream.of(
|
||||
new Node(g.getAscendantIdName(), g.getAscendingUuid()),
|
||||
new Node(g.getDescendantIdName(), g.getDescendantUuid()))
|
||||
)
|
||||
.collect(groupingBy(RbacGrantsDiagramService::renderEntityIdName))
|
||||
.entrySet().stream()
|
||||
.map(entity -> "subgraph " + cleanId(entity.getKey()) + renderSubgraph(entity.getKey()) + "\n\n "
|
||||
+ entity.getValue().stream()
|
||||
.map(n -> renderNode(n.idName(), n.uuid()).replace("\n", "\n "))
|
||||
.sorted()
|
||||
.distinct()
|
||||
.collect(joining("\n\n ")))
|
||||
.collect(joining("\n\nend\n\n"))
|
||||
+ "\n\nend\n\n"
|
||||
: "";
|
||||
|
||||
final var grants = graph.stream()
|
||||
@ -193,7 +208,7 @@ public class RbacGrantsDiagramService {
|
||||
final var refType = refType(idName);
|
||||
|
||||
if (refType.equals("user")) {
|
||||
final var displayName = idName.substring(refType.length()+1);
|
||||
final var displayName = idName.substring(refType.length() + 1);
|
||||
return "(" + displayName + "\nref:" + uuid + ")";
|
||||
}
|
||||
if (refType.equals("role")) {
|
||||
@ -215,15 +230,20 @@ public class RbacGrantsDiagramService {
|
||||
@NotNull
|
||||
private static String cleanId(final String idName) {
|
||||
return idName.replaceAll("@.*", "")
|
||||
.replace("[", "").replace("]", "").replace("(", "").replace(")", "").replace(",", "").replace(">", ":").replace("|", "_");
|
||||
.replace("[", "")
|
||||
.replace("]", "")
|
||||
.replace("(", "")
|
||||
.replace(")", "")
|
||||
.replace(",", "")
|
||||
.replace(">", ":")
|
||||
.replace("|", "_");
|
||||
}
|
||||
|
||||
|
||||
static class LimitedHashSet<T> extends HashSet<T> {
|
||||
|
||||
@Override
|
||||
public boolean add(final T t) {
|
||||
if (size() < GRANT_LIMIT ) {
|
||||
if (size() < GRANT_LIMIT) {
|
||||
return super.add(t);
|
||||
} else {
|
||||
return false;
|
||||
|
@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.rbac.role;
|
||||
|
||||
import io.micrometer.core.annotation.Timed;
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import net.hostsharing.hsadminng.rbac.generated.api.v1.api.RbacRolesApi;
|
||||
import net.hostsharing.hsadminng.rbac.generated.api.v1.model.RbacRoleResource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -19,7 +19,7 @@ public class RbacRoleController implements RbacRolesApi {
|
||||
private Context context;
|
||||
|
||||
@Autowired
|
||||
private StandardMapper mapper;
|
||||
private StrictMapper mapper;
|
||||
|
||||
@Autowired
|
||||
private RbacRoleRepository rbacRoleRepository;
|
||||
|
@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.rbac.subject;
|
||||
|
||||
import io.micrometer.core.annotation.Timed;
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import net.hostsharing.hsadminng.rbac.generated.api.v1.api.RbacSubjectsApi;
|
||||
import net.hostsharing.hsadminng.rbac.generated.api.v1.model.RbacSubjectPermissionResource;
|
||||
import net.hostsharing.hsadminng.rbac.generated.api.v1.model.RbacSubjectResource;
|
||||
@ -22,7 +22,7 @@ public class RbacSubjectController implements RbacSubjectsApi {
|
||||
private Context context;
|
||||
|
||||
@Autowired
|
||||
private StandardMapper mapper;
|
||||
private StrictMapper mapper;
|
||||
|
||||
@Autowired
|
||||
private RbacSubjectRepository rbacSubjectRepository;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.hostsharing.hsadminng.rbac.test.cust;
|
||||
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import net.hostsharing.hsadminng.test.generated.api.v1.api.TestCustomersApi;
|
||||
import net.hostsharing.hsadminng.test.generated.api.v1.model.TestCustomerResource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -21,7 +21,7 @@ public class TestCustomerController implements TestCustomersApi {
|
||||
private Context context;
|
||||
|
||||
@Autowired
|
||||
private StandardMapper mapper;
|
||||
private StrictMapper mapper;
|
||||
|
||||
@Autowired
|
||||
private TestCustomerRepository testCustomerRepository;
|
||||
|
@ -1,6 +1,6 @@
|
||||
package net.hostsharing.hsadminng.rbac.test.pac;
|
||||
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import net.hostsharing.hsadminng.mapper.OptionalFromJson;
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.test.generated.api.v1.api.TestPackagesApi;
|
||||
@ -21,7 +21,7 @@ public class TestPackageController implements TestPackagesApi {
|
||||
private Context context;
|
||||
|
||||
@Autowired
|
||||
private StandardMapper mapper;
|
||||
private StrictMapper mapper;
|
||||
|
||||
@Autowired
|
||||
private TestPackageRepository testPackageRepository;
|
||||
|
@ -90,6 +90,7 @@ components:
|
||||
type: boolean
|
||||
vatReverseCharge:
|
||||
type: boolean
|
||||
# TODO.feat: alternatively the complete refundBankAccount
|
||||
refundBankAccount.uuid:
|
||||
type: string
|
||||
format: uuid
|
||||
|
@ -43,7 +43,10 @@ end; $$;
|
||||
|
||||
do language plpgsql $$
|
||||
begin
|
||||
call base.defineContext('creating coopSharesTransaction test-data');
|
||||
call base.defineContext('creating coopSharesTransaction test-data',
|
||||
null,
|
||||
'superuser-alex@hostsharing.net',
|
||||
'rbac.global#global:ADMIN');
|
||||
SET CONSTRAINTS ALL DEFERRED;
|
||||
|
||||
call hs_office.coopsharetx_create_test_data(10001, '01');
|
||||
|
@ -49,7 +49,10 @@ end; $$;
|
||||
|
||||
do language plpgsql $$
|
||||
begin
|
||||
call base.defineContext('creating coopAssetsTransaction test-data');
|
||||
call base.defineContext('creating coopAssetsTransaction test-data',
|
||||
null,
|
||||
'superuser-alex@hostsharing.net',
|
||||
'rbac.global#global:ADMIN');
|
||||
SET CONSTRAINTS ALL DEFERRED;
|
||||
|
||||
call hs_office.coopassettx_create_test_data(10001, '01');
|
||||
|
@ -81,8 +81,7 @@ class RestResponseEntityExceptionHandlerUnitTest {
|
||||
void handleJpaObjectRetrievalFailureExceptionWithDisplayName() {
|
||||
// given
|
||||
final var givenException = new JpaObjectRetrievalFailureException(
|
||||
new EntityNotFoundException(
|
||||
"Unable to find net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity with id 12345-123454")
|
||||
new EntityNotFoundException("Unable to find Entity with id 12345-123454")
|
||||
);
|
||||
final var givenWebRequest = mock(WebRequest.class);
|
||||
|
||||
@ -91,7 +90,7 @@ class RestResponseEntityExceptionHandlerUnitTest {
|
||||
|
||||
// then
|
||||
assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(400);
|
||||
assertThat(errorResponse.getBody().getMessage()).isEqualTo("ERROR: [400] Unable to find Partner with uuid 12345-123454");
|
||||
assertThat(errorResponse.getBody().getMessage()).isEqualTo("ERROR: [400] Unable to find Entity with id 12345-123454");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -643,7 +643,6 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
final var givenProject = realProjectRepo.findByCaption(projectCaption).stream()
|
||||
.findAny().orElseThrow();
|
||||
final var newBookingItem = HsBookingItemRealEntity.builder()
|
||||
.uuid(UUID.randomUUID())
|
||||
.project(givenProject)
|
||||
.type(hsBookingItemType)
|
||||
.caption("some test-booking")
|
||||
|
@ -14,7 +14,7 @@ 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.context.TestConfiguration;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.MediaType;
|
||||
@ -48,23 +48,23 @@ class HsBookingItemControllerRestTest {
|
||||
@Autowired
|
||||
MockMvc mockMvc;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
Context contextMock;
|
||||
|
||||
@Autowired
|
||||
@SuppressWarnings("unused") // not used in test, but in controller class
|
||||
StrictMapper mapper;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
EntityManagerWrapper em;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
EntityManagerFactory emf;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
HsBookingProjectRealRepository realProjectRepo;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
HsBookingItemRbacRepository rbacBookingItemRepo;
|
||||
|
||||
@TestConfiguration
|
||||
|
@ -13,7 +13,7 @@ import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.orm.jpa.JpaSystemException;
|
||||
|
||||
@ -61,7 +61,7 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
|
||||
@PersistenceContext
|
||||
EntityManager em;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
HttpServletRequest request;
|
||||
|
||||
@Test
|
||||
|
@ -270,7 +270,6 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
final var givenDebitor = debitorRepo.findByDebitorNumber(debitorNumber).stream().findAny().orElseThrow();
|
||||
final var newBookingProject = HsBookingProjectRealEntity.builder()
|
||||
.uuid(UUID.randomUUID())
|
||||
.debitor(givenDebitor)
|
||||
.caption(caption)
|
||||
.build();
|
||||
|
@ -13,7 +13,7 @@ import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.EnumSource;
|
||||
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.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.orm.jpa.JpaSystemException;
|
||||
|
||||
@ -56,7 +56,7 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
|
||||
@PersistenceContext
|
||||
EntityManager em;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
HttpServletRequest request;
|
||||
|
||||
@Test
|
||||
|
@ -488,7 +488,6 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
|
||||
final var givenAsset = givenSomeTemporaryHostingAsset(() ->
|
||||
HsHostingAssetRealEntity.builder()
|
||||
.uuid(UUID.randomUUID())
|
||||
.bookingItem(givenSomeNewBookingItem(
|
||||
"D-1000111 default project",
|
||||
HsBookingItemType.MANAGED_SERVER,
|
||||
@ -571,7 +570,6 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
|
||||
final var givenAsset = givenSomeTemporaryHostingAsset(() ->
|
||||
HsHostingAssetRealEntity.builder()
|
||||
.uuid(UUID.randomUUID())
|
||||
.type(UNIX_USER)
|
||||
.parentAsset(givenRealHostingAsset(MANAGED_WEBSPACE, "fir01"))
|
||||
.identifier("fir01-temp")
|
||||
@ -648,7 +646,6 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
final var givenAsset = givenSomeTemporaryHostingAsset(() ->
|
||||
HsHostingAssetRealEntity.builder()
|
||||
.uuid(UUID.randomUUID())
|
||||
.bookingItem(givenSomeNewBookingItem(
|
||||
"D-1000111 default project",
|
||||
HsBookingItemType.MANAGED_SERVER,
|
||||
@ -681,7 +678,6 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
final var givenAsset = givenSomeTemporaryHostingAsset(() ->
|
||||
HsHostingAssetRealEntity.builder()
|
||||
.uuid(UUID.randomUUID())
|
||||
.bookingItem(givenSomeNewBookingItem(
|
||||
"D-1000111 default project",
|
||||
HsBookingItemType.MANAGED_SERVER,
|
||||
|
@ -9,7 +9,7 @@ import net.hostsharing.hsadminng.config.JsonObjectMapperConfiguration;
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealRepository;
|
||||
import net.hostsharing.hsadminng.mapper.Array;
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@ -24,7 +24,7 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
@ -54,7 +54,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@WebMvcTest(HsHostingAssetController.class)
|
||||
@Import({ StandardMapper.class, JsonObjectMapperConfiguration.class, DisableSecurityConfig.class })
|
||||
@Import({ StrictMapper.class, JsonObjectMapperConfiguration.class, DisableSecurityConfig.class })
|
||||
@RunWith(SpringRunner.class)
|
||||
@ActiveProfiles("test")
|
||||
public class HsHostingAssetControllerRestTest {
|
||||
@ -62,27 +62,27 @@ public class HsHostingAssetControllerRestTest {
|
||||
@Autowired
|
||||
MockMvc mockMvc;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
Context contextMock;
|
||||
|
||||
@Autowired
|
||||
@SuppressWarnings("unused") // not used in test, but in controller class
|
||||
StandardMapper mapper;
|
||||
StrictMapper mapper;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
EntityManagerWrapper em;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
EntityManagerFactory emf;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
@SuppressWarnings("unused") // bean needs to be present for HsHostingAssetController
|
||||
private HsBookingItemRealRepository realBookingItemRepo;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
private HsHostingAssetRealRepository realAssetRepo;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
private HsHostingAssetRbacRepository rbacAssetRepo;
|
||||
|
||||
@TestConfiguration
|
||||
|
@ -17,7 +17,7 @@ import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.EnumSource;
|
||||
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.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.orm.jpa.JpaSystemException;
|
||||
|
||||
@ -70,7 +70,7 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
|
||||
@PersistenceContext
|
||||
EntityManager em;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
HttpServletRequest request;
|
||||
|
||||
@Test
|
||||
|
@ -12,7 +12,7 @@ import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import net.hostsharing.hsadminng.config.JsonObjectMapperConfiguration;
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
@ -59,7 +59,7 @@ class DomainSetupHostingAssetFactoryUnitTest {
|
||||
private ObjectMapper jsonMapper = new JsonObjectMapperConfiguration().customObjectMapper().build();
|
||||
|
||||
@Spy
|
||||
private StandardMapper standardMapper = new StandardMapper(emw);
|
||||
private StrictMapper StrictMapper = new StrictMapper(emw);
|
||||
|
||||
@InjectMocks
|
||||
private HsBookingItemCreatedListener listener;
|
||||
|
@ -8,7 +8,7 @@ import net.hostsharing.hsadminng.hs.booking.item.BookingItemCreatedEventEntity;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
|
||||
import net.hostsharing.hsadminng.lambda.Reducer;
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapperFake;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
@ -42,7 +42,7 @@ class HsBookingItemCreatedListenerUnitTest {
|
||||
private ObjectMapper jsonMapper = new JsonObjectMapperConfiguration().customObjectMapper().build();
|
||||
|
||||
@Spy
|
||||
private StandardMapper standardMapper = new StandardMapper(emw);
|
||||
private StrictMapper StrictMapper = new StrictMapper(emw);
|
||||
|
||||
@InjectMocks
|
||||
private HsBookingItemCreatedListener listener;
|
||||
|
@ -13,7 +13,7 @@ import net.hostsharing.hsadminng.hs.hosting.asset.validators.Dns;
|
||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContact;
|
||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
|
||||
import net.hostsharing.hsadminng.lambda.Reducer;
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapperFake;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@ -55,7 +55,7 @@ class ManagedWebspaceHostingAssetFactoryUnitTest {
|
||||
private ObjectMapper jsonMapper = new JsonObjectMapperConfiguration().customObjectMapper().build();
|
||||
|
||||
@Spy
|
||||
private StandardMapper standardMapper = new StandardMapper(emw);
|
||||
private StrictMapper StrictMapper = new StrictMapper(emw);
|
||||
|
||||
@InjectMocks
|
||||
private HsBookingItemCreatedListener listener;
|
||||
|
@ -10,7 +10,7 @@ import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipStatus;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerDetailsEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
|
||||
@ -84,7 +84,7 @@ public abstract class BaseOfficeDataImport extends CsvDataImport {
|
||||
|
||||
static Map<Integer, HsOfficeContactRealEntity> contacts = new WriteOnceMap<>();
|
||||
static Map<Integer, HsOfficePersonRealEntity> persons = new WriteOnceMap<>();
|
||||
static Map<Integer, HsOfficePartnerEntity> partners = new WriteOnceMap<>();
|
||||
static Map<Integer, HsOfficePartnerRealEntity> partners = new WriteOnceMap<>();
|
||||
static Map<Integer, HsOfficeDebitorEntity> debitors = new WriteOnceMap<>();
|
||||
static Map<Integer, HsOfficeMembershipEntity> memberships = new WriteOnceMap<>();
|
||||
|
||||
@ -743,7 +743,7 @@ public abstract class BaseOfficeDataImport extends CsvDataImport {
|
||||
null // is set during contacts import depending on assigned roles
|
||||
);
|
||||
|
||||
final var partner = HsOfficePartnerEntity.builder()
|
||||
final var partner = HsOfficePartnerRealEntity.builder()
|
||||
.partnerNumber(rec.getInteger("member_id"))
|
||||
.details(HsOfficePartnerDetailsEntity.builder().build())
|
||||
.partnerRel(partnerRel)
|
||||
|
@ -14,7 +14,7 @@ import org.junit.jupiter.api.extension.TestWatcher;
|
||||
import org.opentest4j.AssertionFailedError;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
@ -76,7 +76,7 @@ public class CsvDataImport extends ContextBasedTest {
|
||||
@Autowired
|
||||
JpaAttempt jpaAttempt;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
HttpServletRequest request;
|
||||
|
||||
static final LinkedHashSet<String> errors = new LinkedHashSet<>();
|
||||
|
@ -1,13 +1,13 @@
|
||||
package net.hostsharing.hsadminng.hs.office.bankaccount;
|
||||
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.EnumSource;
|
||||
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.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
@ -26,14 +26,14 @@ class HsOfficeBankAccountControllerRestTest {
|
||||
@Autowired
|
||||
MockMvc mockMvc;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
Context contextMock;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
@SuppressWarnings("unused") // not used in test, but in controller class
|
||||
StandardMapper mapper;
|
||||
StrictMapper mapper;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
HsOfficeBankAccountRepository bankAccountRepo;
|
||||
|
||||
enum InvalidIbanTestCase {
|
||||
|
@ -11,7 +11,7 @@ import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
@ -46,7 +46,7 @@ class HsOfficeBankAccountRepositoryIntegrationTest extends ContextBasedTestWithC
|
||||
@Autowired
|
||||
JpaAttempt jpaAttempt;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
HttpServletRequest request;
|
||||
|
||||
@Nested
|
||||
|
@ -374,7 +374,6 @@ class HsOfficeContactControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
||||
return jpaAttempt.transacted(() -> {
|
||||
context.define(creatingUser);
|
||||
final var newContact = HsOfficeContactRbacEntity.builder()
|
||||
.uuid(UUID.randomUUID())
|
||||
.caption("Temp from " + Context.getCallerMethodNameFromStackFrame(1) )
|
||||
.postalAddress(Map.ofEntries(
|
||||
entry("name", RandomStringUtils.randomAlphabetic(6) + " " + RandomStringUtils.randomAlphabetic(10)),
|
||||
|
@ -11,7 +11,7 @@ import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
@ -46,7 +46,7 @@ class HsOfficeContactRbacRepositoryIntegrationTest extends ContextBasedTestWithC
|
||||
@Autowired
|
||||
JpaAttempt jpaAttempt;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
HttpServletRequest request;
|
||||
|
||||
@Nested
|
||||
|
@ -4,7 +4,7 @@ import net.hostsharing.hsadminng.config.JsonObjectMapperConfiguration;
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipRepository;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealEntity;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||
import net.hostsharing.hsadminng.rbac.test.JsonBuilder;
|
||||
@ -17,10 +17,10 @@ import org.junit.jupiter.params.provider.EnumSource;
|
||||
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.context.annotation.Import;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
@ -67,7 +67,7 @@ class HsOfficeCoopAssetsTransactionControllerRestTest {
|
||||
private static final String ORIGIN_MEMBER_NUMBER = "M-1111100";
|
||||
public final HsOfficeMembershipEntity ORIGIN_TARGET_MEMBER_ENTITY = HsOfficeMembershipEntity.builder()
|
||||
.uuid(ORIGIN_MEMBERSHIP_UUID)
|
||||
.partner(HsOfficePartnerEntity.builder()
|
||||
.partner(HsOfficePartnerRealEntity.builder()
|
||||
.partnerNumber(partnerNumberOf(ORIGIN_MEMBER_NUMBER))
|
||||
.build())
|
||||
.memberNumberSuffix(suffixOf(ORIGIN_MEMBER_NUMBER))
|
||||
@ -77,7 +77,7 @@ class HsOfficeCoopAssetsTransactionControllerRestTest {
|
||||
private static final String AVAILABLE_TARGET_MEMBER_NUMBER = "M-1234500";
|
||||
public final HsOfficeMembershipEntity AVAILABLE_MEMBER_ENTITY = HsOfficeMembershipEntity.builder()
|
||||
.uuid(AVAILABLE_TARGET_MEMBERSHIP_UUID)
|
||||
.partner(HsOfficePartnerEntity.builder()
|
||||
.partner(HsOfficePartnerRealEntity.builder()
|
||||
.partnerNumber(partnerNumberOf(AVAILABLE_TARGET_MEMBER_NUMBER))
|
||||
.build())
|
||||
.memberNumberSuffix(suffixOf(AVAILABLE_TARGET_MEMBER_NUMBER))
|
||||
@ -499,20 +499,20 @@ class HsOfficeCoopAssetsTransactionControllerRestTest {
|
||||
@Autowired
|
||||
MockMvc mockMvc;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
Context contextMock;
|
||||
|
||||
@Autowired
|
||||
@SuppressWarnings("unused") // not used in test, but in controller class
|
||||
StrictMapper mapper;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
EntityManagerWrapper emw; // even if not used in test anymore, it's needed by base-class of StrictMapper
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
HsOfficeCoopAssetsTransactionRepository coopAssetsTransactionRepo;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
HsOfficeMembershipRepository membershipRepo;
|
||||
|
||||
static final String INSERT_REQUEST_BODY_TEMPLATE = """
|
||||
|
@ -13,7 +13,7 @@ import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
@ -51,7 +51,7 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase
|
||||
@Autowired
|
||||
JpaAttempt jpaAttempt;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
HttpServletRequest request;
|
||||
|
||||
@Nested
|
||||
|
@ -170,7 +170,9 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest extends ContextBased
|
||||
final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000101).orElseThrow();
|
||||
|
||||
final var location = RestAssured // @formatter:off
|
||||
.given().header("current-subject", "superuser-alex@hostsharing.net").contentType(ContentType.JSON).body("""
|
||||
.given()
|
||||
.header("current-subject", "superuser-alex@hostsharing.net")
|
||||
.contentType(ContentType.JSON).body("""
|
||||
{
|
||||
"membership.uuid": "%s",
|
||||
"transactionType": "SUBSCRIPTION",
|
||||
@ -179,15 +181,29 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest extends ContextBased
|
||||
"reference": "temp ref A",
|
||||
"comment": "just some test coop shares transaction"
|
||||
}
|
||||
""".formatted(givenMembership.getUuid())).port(port).when().post("http://localhost/api/hs/office/coopsharestransactions").then().log().all().assertThat().statusCode(201).contentType(ContentType.JSON).body("uuid", isUuidValid()).body("", lenientlyEquals("""
|
||||
""".formatted(givenMembership.getUuid()))
|
||||
.port(port)
|
||||
.when()
|
||||
.post("http://localhost/api/hs/office/coopsharestransactions")
|
||||
.then()
|
||||
.log().all()
|
||||
.assertThat()
|
||||
.statusCode(201)
|
||||
.contentType(ContentType.JSON)
|
||||
.body("uuid", isUuidValid())
|
||||
.body("", lenientlyEquals("""
|
||||
{
|
||||
"membership.uuid": "%s",
|
||||
"transactionType": "SUBSCRIPTION",
|
||||
"shareCount": 8,
|
||||
"valueDate": "2022-10-13",
|
||||
"reference": "temp ref A",
|
||||
"comment": "just some test coop shares transaction"
|
||||
}
|
||||
""")).header("Location", startsWith("http://localhost")).extract().header("Location"); // @formatter:on
|
||||
""".formatted(givenMembership.getUuid())))
|
||||
.header("Location", startsWith("http://localhost"))
|
||||
.extract()
|
||||
.header("Location"); // @formatter:on
|
||||
|
||||
// finally, the new coopSharesTransaction can be accessed under the generated UUID
|
||||
final var newShareTxUuid = UUID.fromString(location.substring(location.lastIndexOf('/') + 1));
|
||||
@ -197,7 +213,7 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest extends ContextBased
|
||||
@Test
|
||||
void globalAdmin_canAddCoopSharesReversalTransaction() {
|
||||
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
context.define("superuser-alex@hostsharing.net", "rbac.global#global:ADMIN");
|
||||
final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000101).orElseThrow();
|
||||
final var givenTransaction = jpaAttempt.transacted(() -> {
|
||||
// TODO.impl: introduce something like transactedAsSuperuser / transactedAs("...", ...)
|
||||
@ -214,46 +230,46 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest extends ContextBased
|
||||
|
||||
final var location = RestAssured // @formatter:off
|
||||
.given()
|
||||
.header("current-subject", "superuser-alex@hostsharing.net")
|
||||
.contentType(ContentType.JSON)
|
||||
.body("""
|
||||
{
|
||||
"membership.uuid": "%s",
|
||||
"transactionType": "REVERSAL",
|
||||
"shareCount": %s,
|
||||
"valueDate": "2022-10-30",
|
||||
"reference": "test reversal ref",
|
||||
"comment": "some coop shares reversal transaction",
|
||||
"revertedShareTx.uuid": "%s"
|
||||
}
|
||||
""".formatted(
|
||||
givenMembership.getUuid(),
|
||||
-givenTransaction.getShareCount(),
|
||||
givenTransaction.getUuid()))
|
||||
.port(port)
|
||||
.header("current-subject", "superuser-alex@hostsharing.net")
|
||||
.contentType(ContentType.JSON)
|
||||
.body("""
|
||||
{
|
||||
"membership.uuid": "%s",
|
||||
"transactionType": "REVERSAL",
|
||||
"shareCount": %s,
|
||||
"valueDate": "2022-10-30",
|
||||
"reference": "test reversal ref",
|
||||
"comment": "some coop shares reversal transaction",
|
||||
"revertedShareTx.uuid": "%s"
|
||||
}
|
||||
""".formatted(
|
||||
givenMembership.getUuid(),
|
||||
-givenTransaction.getShareCount(),
|
||||
givenTransaction.getUuid()))
|
||||
.port(port)
|
||||
.when()
|
||||
.post("http://localhost/api/hs/office/coopsharestransactions")
|
||||
.post("http://localhost/api/hs/office/coopsharestransactions")
|
||||
.then().log().all().assertThat()
|
||||
.statusCode(201)
|
||||
.contentType(ContentType.JSON)
|
||||
.body("uuid", isUuidValid())
|
||||
.body("", lenientlyEquals("""
|
||||
{
|
||||
"transactionType": "REVERSAL",
|
||||
"shareCount": -13,
|
||||
"valueDate": "2022-10-30",
|
||||
"reference": "test reversal ref",
|
||||
"comment": "some coop shares reversal transaction",
|
||||
"revertedShareTx": {
|
||||
"transactionType": "SUBSCRIPTION",
|
||||
"shareCount": 13,
|
||||
"valueDate": "2022-10-20",
|
||||
"reference": "test ref"
|
||||
}
|
||||
.statusCode(201)
|
||||
.contentType(ContentType.JSON)
|
||||
.body("uuid", isUuidValid())
|
||||
.body("", lenientlyEquals("""
|
||||
{
|
||||
"transactionType": "REVERSAL",
|
||||
"shareCount": -13,
|
||||
"valueDate": "2022-10-30",
|
||||
"reference": "test reversal ref",
|
||||
"comment": "some coop shares reversal transaction",
|
||||
"revertedShareTx": {
|
||||
"transactionType": "SUBSCRIPTION",
|
||||
"shareCount": 13,
|
||||
"valueDate": "2022-10-20",
|
||||
"reference": "test ref"
|
||||
}
|
||||
"""))
|
||||
.header("Location", startsWith("http://localhost"))
|
||||
.extract().header("Location"); // @formatter:on
|
||||
}
|
||||
"""))
|
||||
.header("Location", startsWith("http://localhost"))
|
||||
.extract().header("Location"); // @formatter:on
|
||||
|
||||
// finally, the new coopAssetsTransaction can be accessed under the generated UUID
|
||||
final var newShareTxUuid = UUID.fromString(
|
||||
@ -269,22 +285,34 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest extends ContextBased
|
||||
final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000101).orElseThrow();
|
||||
|
||||
RestAssured // @formatter:off
|
||||
.given().header("current-subject", "superuser-alex@hostsharing.net").contentType(ContentType.JSON).body("""
|
||||
{
|
||||
"membership.uuid": "%s",
|
||||
"transactionType": "CANCELLATION",
|
||||
"shareCount": -80,
|
||||
"valueDate": "2022-10-13",
|
||||
"reference": "temp ref X",
|
||||
"comment": "just some test coop shares transaction"
|
||||
}
|
||||
""".formatted(givenMembership.getUuid())).port(port).when().post("http://localhost/api/hs/office/coopsharestransactions").then().log().all().assertThat().statusCode(400).contentType(ContentType.JSON).body("", lenientlyEquals("""
|
||||
.given()
|
||||
.header("current-subject", "superuser-alex@hostsharing.net")
|
||||
.contentType(ContentType.JSON)
|
||||
.body("""
|
||||
{
|
||||
"statusCode": 400,
|
||||
"statusPhrase": "Bad Request",
|
||||
"message": "ERROR: [400] coop shares transaction would result in a negative number of shares"
|
||||
}
|
||||
""")); // @formatter:on
|
||||
"membership.uuid": "%s",
|
||||
"transactionType": "CANCELLATION",
|
||||
"shareCount": -80,
|
||||
"valueDate": "2022-10-13",
|
||||
"reference": "temp ref X",
|
||||
"comment": "just some test coop shares transaction"
|
||||
}
|
||||
""".formatted(givenMembership.getUuid()))
|
||||
.port(port)
|
||||
.when()
|
||||
.post("http://localhost/api/hs/office/coopsharestransactions")
|
||||
.then()
|
||||
.log().all()
|
||||
.assertThat()
|
||||
.statusCode(400)
|
||||
.contentType(ContentType.JSON)
|
||||
.body("", lenientlyEquals("""
|
||||
{
|
||||
"statusCode": 400,
|
||||
"statusPhrase": "Bad Request",
|
||||
"message": "ERROR: [400] coop shares transaction would result in a negative number of shares"
|
||||
}
|
||||
""")); // @formatter:on
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,15 @@
|
||||
package net.hostsharing.hsadminng.hs.office.coopshares;
|
||||
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipRepository;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import net.hostsharing.hsadminng.rbac.test.JsonBuilder;
|
||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.EnumSource;
|
||||
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.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
@ -31,16 +32,19 @@ class HsOfficeCoopSharesTransactionControllerRestTest {
|
||||
@Autowired
|
||||
MockMvc mockMvc;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
Context contextMock;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
@SuppressWarnings("unused") // not used in test, but in controller class
|
||||
StandardMapper mapper;
|
||||
StrictMapper mapper;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
HsOfficeCoopSharesTransactionRepository coopSharesTransactionRepo;
|
||||
|
||||
@MockitoBean
|
||||
HsOfficeMembershipRepository membershipRepo;
|
||||
|
||||
static final String VALID_INSERT_REQUEST_BODY = """
|
||||
{
|
||||
"membership.uuid": "%s",
|
||||
|
@ -13,7 +13,7 @@ import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
@ -50,7 +50,7 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase
|
||||
@Autowired
|
||||
JpaAttempt jpaAttempt;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
HttpServletRequest request;
|
||||
|
||||
@Nested
|
||||
|
@ -6,7 +6,7 @@ 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.HsOfficeContactRealRepository;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacRepository;
|
||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealRepository;
|
||||
@ -28,6 +28,7 @@ import jakarta.persistence.PersistenceContext;
|
||||
import java.util.UUID;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.DEBITOR;
|
||||
import static net.hostsharing.hsadminng.rbac.role.RbacRoleType.ADMIN;
|
||||
import static net.hostsharing.hsadminng.rbac.test.IsValidUuidMatcher.isUuidValid;
|
||||
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@ -57,7 +58,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
||||
HsOfficeDebitorRepository debitorRepo;
|
||||
|
||||
@Autowired
|
||||
HsOfficePartnerRepository partnerRepo;
|
||||
HsOfficePartnerRbacRepository partnerRepo;
|
||||
|
||||
@Autowired
|
||||
HsOfficeContactRealRepository contactRealRepo;
|
||||
@ -467,7 +468,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
||||
.post("http://localhost/api/hs/office/debitors")
|
||||
.then().log().all().assertThat()
|
||||
.statusCode(400)
|
||||
.body("message", is("ERROR: [400] Unable to find RealContact by debitorRel.contactUuid: 00000000-0000-0000-0000-000000000000"));
|
||||
.body("message", is("ERROR: [400] Unable to find debitorRel.contact.uuid: 00000000-0000-0000-0000-000000000000"));
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@ -495,7 +496,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
||||
.post("http://localhost/api/hs/office/debitors")
|
||||
.then().log().all().assertThat()
|
||||
.statusCode(400)
|
||||
.body("message", is("ERROR: [400] Unable to find RealRelation by debitorRelUuid: 00000000-0000-0000-0000-000000000000"));
|
||||
.body("message", is("ERROR: [400] Unable to find debitorRel.uuid: 00000000-0000-0000-0000-000000000000"));
|
||||
// @formatter:on
|
||||
}
|
||||
}
|
||||
@ -695,16 +696,16 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
||||
}
|
||||
|
||||
@Test
|
||||
void theContactOwner_canNotPatchARelatedDebitor() {
|
||||
void theContactAdmin_canNotPatchARelatedDebitor() {
|
||||
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
final var givenDebitor = givenSomeTemporaryDebitor();
|
||||
|
||||
// @formatter:on
|
||||
RestAssured // @formatter:off
|
||||
.given()
|
||||
.given()
|
||||
.header("current-subject", "superuser-alex@hostsharing.net")
|
||||
.header("assumed-roles", "hs_office.contact#tenthcontact:ADMIN")
|
||||
.header("assumed-roles", givenDebitor.getDebitorRel().getContact().roleId(ADMIN) )
|
||||
.contentType(ContentType.JSON)
|
||||
.body("""
|
||||
{
|
||||
@ -712,9 +713,9 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
||||
}
|
||||
""")
|
||||
.port(port)
|
||||
.when()
|
||||
.when()
|
||||
.patch("http://localhost/api/hs/office/debitors/" + givenDebitor.getUuid())
|
||||
.then().log().all().assertThat()
|
||||
.then().log().all().assertThat()
|
||||
.statusCode(403)
|
||||
.body("message", containsString("ERROR: [403] Subject"))
|
||||
.body("message", containsString("is not allowed to update hs_office.debitor uuid "));
|
||||
@ -802,7 +803,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
||||
.vatReverseCharge(false)
|
||||
.build();
|
||||
|
||||
return debitorRepo.save(newDebitor).load();
|
||||
return debitorRepo.save(newDebitor).reload(em);
|
||||
}).assertSuccessful().returnedValue();
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.hostsharing.hsadminng.hs.office.debitor;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||
@ -30,7 +30,7 @@ class HsOfficeDebitorEntityUnitTest {
|
||||
.debitorNumberSuffix("67")
|
||||
.debitorRel(givenDebitorRel)
|
||||
.defaultPrefix("som")
|
||||
.partner(HsOfficePartnerEntity.builder()
|
||||
.partner(HsOfficePartnerRealEntity.builder()
|
||||
.partnerNumber(12345)
|
||||
.build())
|
||||
.build();
|
||||
@ -45,7 +45,7 @@ class HsOfficeDebitorEntityUnitTest {
|
||||
final var given = HsOfficeDebitorEntity.builder()
|
||||
.debitorRel(givenDebitorRel)
|
||||
.debitorNumberSuffix("67")
|
||||
.partner(HsOfficePartnerEntity.builder()
|
||||
.partner(HsOfficePartnerRealEntity.builder()
|
||||
.partnerNumber(12345)
|
||||
.build())
|
||||
.build();
|
||||
@ -60,7 +60,7 @@ class HsOfficeDebitorEntityUnitTest {
|
||||
final var given = HsOfficeDebitorEntity.builder()
|
||||
.debitorRel(givenDebitorRel)
|
||||
.debitorNumberSuffix("67")
|
||||
.partner(HsOfficePartnerEntity.builder()
|
||||
.partner(HsOfficePartnerRealEntity.builder()
|
||||
.partnerNumber(12345)
|
||||
.build())
|
||||
.build();
|
||||
@ -88,7 +88,7 @@ class HsOfficeDebitorEntityUnitTest {
|
||||
final var given = HsOfficeDebitorEntity.builder()
|
||||
.debitorRel(givenDebitorRel)
|
||||
.debitorNumberSuffix("67")
|
||||
.partner(HsOfficePartnerEntity.builder().build())
|
||||
.partner(HsOfficePartnerRealEntity.builder().build())
|
||||
.build();
|
||||
|
||||
final var result = given.getTaggedDebitorNumber();
|
||||
@ -101,7 +101,7 @@ class HsOfficeDebitorEntityUnitTest {
|
||||
final var given = HsOfficeDebitorEntity.builder()
|
||||
.debitorRel(givenDebitorRel)
|
||||
.debitorNumberSuffix(null)
|
||||
.partner(HsOfficePartnerEntity.builder()
|
||||
.partner(HsOfficePartnerRealEntity.builder()
|
||||
.partnerNumber(12345)
|
||||
.build())
|
||||
.build();
|
||||
|
@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.debitor;
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountRepository;
|
||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealRepository;
|
||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||
@ -22,7 +22,7 @@ import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.orm.jpa.JpaSystemException;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@ -48,7 +48,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
|
||||
HsOfficeDebitorRepository debitorRepo;
|
||||
|
||||
@Autowired
|
||||
HsOfficePartnerRepository partnerRepo;
|
||||
HsOfficePartnerRealRepository partnerRepo;
|
||||
|
||||
@Autowired
|
||||
HsOfficeContactRealRepository contactRealRepo;
|
||||
@ -74,7 +74,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
|
||||
@Autowired
|
||||
RbacGrantsDiagramService mermaidService;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
HttpServletRequest request;
|
||||
@Nested
|
||||
class CreateDebitor {
|
||||
|
@ -5,7 +5,7 @@ import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealTestEntity.TEST_REAL_CONTACT;
|
||||
import static net.hostsharing.hsadminng.hs.office.partner.TestHsOfficePartner.TEST_PARTNER;
|
||||
import static net.hostsharing.hsadminng.hs.office.partner.HsOfficeTestRealPartner.TEST_PARTNER;
|
||||
|
||||
@UtilityClass
|
||||
public class TestHsOfficeDebitor {
|
||||
|
@ -5,7 +5,7 @@ import io.restassured.RestAssured;
|
||||
import io.restassured.http.ContentType;
|
||||
import net.hostsharing.hsadminng.HsadminNgApplication;
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealRepository;
|
||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
||||
@ -54,7 +54,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
||||
HsOfficeMembershipRepository membershipRepo;
|
||||
|
||||
@Autowired
|
||||
HsOfficePartnerRepository partnerRepo;
|
||||
HsOfficePartnerRealRepository partnerRepo;
|
||||
|
||||
@Autowired
|
||||
JpaAttempt jpaAttempt;
|
||||
@ -430,7 +430,6 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike(partnerName).get(0);
|
||||
final var newMembership = HsOfficeMembershipEntity.builder()
|
||||
.uuid(UUID.randomUUID())
|
||||
.partner(givenPartner)
|
||||
.memberNumberSuffix(TEMP_MEMBER_NUMBER_SUFFIX)
|
||||
.validity(Range.closedInfinite(LocalDate.parse("2022-11-01")))
|
||||
|
@ -2,8 +2,10 @@ package net.hostsharing.hsadminng.hs.office.membership;
|
||||
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.hs.office.coopassets.HsOfficeCoopAssetsTransactionRepository;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealRepository;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
@ -12,7 +14,7 @@ import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.EnumSource;
|
||||
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.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
@ -34,11 +36,11 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@WebMvcTest(HsOfficeMembershipController.class)
|
||||
@Import({StandardMapper.class, DisableSecurityConfig.class})
|
||||
@Import({StrictMapper.class, DisableSecurityConfig.class})
|
||||
@ActiveProfiles("test")
|
||||
public class HsOfficeMembershipControllerRestTest {
|
||||
|
||||
private static final HsOfficePartnerEntity PARTNER_12345 = HsOfficePartnerEntity.builder()
|
||||
private static final HsOfficePartnerRealEntity PARTNER_12345 = HsOfficePartnerRealEntity.builder()
|
||||
.partnerNumber(12345)
|
||||
.build();
|
||||
public static final HsOfficeMembershipEntity MEMBERSHIP_1234501 = HsOfficeMembershipEntity.builder()
|
||||
@ -69,16 +71,19 @@ public class HsOfficeMembershipControllerRestTest {
|
||||
@Autowired
|
||||
MockMvc mockMvc;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
Context contextMock;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
HsOfficeCoopAssetsTransactionRepository coopAssetsTransactionRepo;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
HsOfficePartnerRealRepository partnerRepo;
|
||||
|
||||
@MockitoBean
|
||||
HsOfficeMembershipRepository membershipRepo;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
EntityManagerWrapper em;
|
||||
|
||||
@Nested
|
||||
@ -252,7 +257,7 @@ public class HsOfficeMembershipControllerRestTest {
|
||||
|
||||
// given
|
||||
final var givenPartnerUuid = UUID.randomUUID();
|
||||
when(em.find(HsOfficePartnerEntity.class, givenPartnerUuid)).thenReturn(null);
|
||||
when(em.find(HsOfficePartnerRbacEntity.class, givenPartnerUuid)).thenReturn(null);
|
||||
|
||||
// when
|
||||
mockMvc.perform(MockMvcRequestBuilders
|
||||
@ -275,7 +280,7 @@ public class HsOfficeMembershipControllerRestTest {
|
||||
.andExpect(jsonPath("statusPhrase", is("Bad Request")))
|
||||
.andExpect(jsonPath(
|
||||
"message",
|
||||
is("ERROR: [400] Unable to find Partner by partner.uuid: " + givenPartnerUuid)));
|
||||
is("ERROR: [400] partnerUuid " + givenPartnerUuid + " not found")));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
|
@ -4,7 +4,7 @@ import io.hypersistence.utils.hibernate.type.range.Range;
|
||||
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipPatchResource;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipStatusResource;
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||
import net.hostsharing.hsadminng.rbac.test.PatchUnitTestBase;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@ -17,7 +17,7 @@ import java.time.LocalDate;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.office.partner.TestHsOfficePartner.TEST_PARTNER;
|
||||
import static net.hostsharing.hsadminng.hs.office.partner.HsOfficeTestRealPartner.TEST_PARTNER;
|
||||
import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
@ -40,7 +40,7 @@ class HsOfficeMembershipEntityPatcherUnitTest extends PatchUnitTestBase<
|
||||
@Mock
|
||||
private EntityManagerWrapper em;
|
||||
|
||||
private StandardMapper mapper = new StandardMapper(em);
|
||||
private StrictMapper mapper = new StrictMapper(em);
|
||||
|
||||
@BeforeEach
|
||||
void initMocks() {
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.hostsharing.hsadminng.hs.office.membership;
|
||||
|
||||
import io.hypersistence.utils.hibernate.type.range.Range;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealEntity;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacViewMermaidFlowchartGenerator;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@ -10,7 +10,7 @@ import java.lang.reflect.InvocationTargetException;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.office.partner.TestHsOfficePartner.TEST_PARTNER;
|
||||
import static net.hostsharing.hsadminng.hs.office.partner.HsOfficeTestRealPartner.TEST_PARTNER;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class HsOfficeMembershipEntityUnitTest {
|
||||
@ -57,7 +57,7 @@ class HsOfficeMembershipEntityUnitTest {
|
||||
|
||||
@Test
|
||||
void getMemberNumberWithoutPartnerNumberButWithSuffix() {
|
||||
givenMembership.setPartner(HsOfficePartnerEntity.builder().build());
|
||||
givenMembership.setPartner(HsOfficePartnerRealEntity.builder().build());
|
||||
final var result = givenMembership.getMemberNumber();
|
||||
assertThat(result).isEqualTo(null);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.membership;
|
||||
import io.hypersistence.utils.hibernate.type.range.Range;
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealRepository;
|
||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||
import net.hostsharing.hsadminng.rbac.grant.RawRbacGrantRepository;
|
||||
import net.hostsharing.hsadminng.rbac.role.RawRbacRoleRepository;
|
||||
@ -13,7 +13,7 @@ import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.orm.jpa.JpaSystemException;
|
||||
|
||||
@ -37,7 +37,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl
|
||||
HsOfficeMembershipRepository membershipRepo;
|
||||
|
||||
@Autowired
|
||||
HsOfficePartnerRepository partnerRepo;
|
||||
HsOfficePartnerRealRepository partnerRepo;
|
||||
|
||||
@Autowired
|
||||
HsOfficeDebitorRepository debitorRepo;
|
||||
@ -54,7 +54,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl
|
||||
@Autowired
|
||||
JpaAttempt jpaAttempt;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
HttpServletRequest request;
|
||||
|
||||
@Nested
|
||||
|
@ -4,7 +4,7 @@ import io.hypersistence.utils.hibernate.type.range.Range;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.office.partner.TestHsOfficePartner.TEST_PARTNER;
|
||||
import static net.hostsharing.hsadminng.hs.office.partner.HsOfficeTestRealPartner.TEST_PARTNER;
|
||||
|
||||
public class TestHsMembership {
|
||||
|
||||
|
@ -42,7 +42,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
||||
private Integer port;
|
||||
|
||||
@Autowired
|
||||
HsOfficePartnerRepository partnerRepo;
|
||||
HsOfficePartnerRbacRepository partnerRepo;
|
||||
|
||||
@Autowired
|
||||
HsOfficeRelationRealRepository relationRepo;
|
||||
@ -541,12 +541,12 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
||||
return partnerRel;
|
||||
}).assertSuccessful().returnedValue();
|
||||
}
|
||||
private HsOfficePartnerEntity givenSomeTemporaryPartnerBessler(final Integer partnerNumber) {
|
||||
private HsOfficePartnerRbacEntity givenSomeTemporaryPartnerBessler(final Integer partnerNumber) {
|
||||
return jpaAttempt.transacted(() -> {
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
final var partnerRel = em.merge(givenSomeTemporaryPartnerRel("Erben Bessler", "fourth contact"));
|
||||
|
||||
final var newPartner = HsOfficePartnerEntity.builder()
|
||||
final var newPartner = HsOfficePartnerRbacEntity.builder()
|
||||
.partnerRel(partnerRel)
|
||||
.partnerNumber(partnerNumber)
|
||||
.details(HsOfficePartnerDetailsEntity.builder()
|
||||
@ -561,7 +561,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
||||
|
||||
@AfterEach
|
||||
void cleanup() {
|
||||
cleanupAllNew(HsOfficePartnerEntity.class);
|
||||
cleanupAllNew(HsOfficePartnerRbacEntity.class);
|
||||
|
||||
// TODO: should not be necessary anymore, once it's deleted via after delete trigger
|
||||
cleanupAllNew(HsOfficeRelationRealEntity.class);
|
||||
|
@ -5,7 +5,7 @@ import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRbacEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealRepository;
|
||||
import net.hostsharing.hsadminng.mapper.StandardMapper;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@ -14,7 +14,7 @@ import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mock;
|
||||
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.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
@ -38,7 +38,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@WebMvcTest(HsOfficePartnerController.class)
|
||||
@Import({StandardMapper.class, DisableSecurityConfig.class})
|
||||
@Import({StrictMapper.class, DisableSecurityConfig.class})
|
||||
@ActiveProfiles("test")
|
||||
class HsOfficePartnerControllerRestTest {
|
||||
|
||||
@ -50,19 +50,19 @@ class HsOfficePartnerControllerRestTest {
|
||||
@Autowired
|
||||
MockMvc mockMvc;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
Context contextMock;
|
||||
|
||||
@MockBean
|
||||
HsOfficePartnerRepository partnerRepo;
|
||||
@MockitoBean
|
||||
HsOfficePartnerRbacRepository partnerRepo;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
HsOfficeRelationRealRepository relationRepo;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
EntityManagerWrapper em;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
EntityManagerFactory emf;
|
||||
|
||||
@Mock
|
||||
@ -75,7 +75,7 @@ class HsOfficePartnerControllerRestTest {
|
||||
HsOfficeContactRbacEntity contactMock;
|
||||
|
||||
@Mock
|
||||
HsOfficePartnerEntity partnerMock;
|
||||
HsOfficePartnerRbacEntity partnerMock;
|
||||
|
||||
@BeforeEach
|
||||
void init() {
|
||||
@ -174,7 +174,7 @@ class HsOfficePartnerControllerRestTest {
|
||||
@Test
|
||||
void respondWithPartner_ifPartnerNumberIsAvailable() throws Exception {
|
||||
// given
|
||||
when(partnerRepo.findPartnerByPartnerNumber(12345)).thenReturn(Optional.of(HsOfficePartnerEntity.builder()
|
||||
when(partnerRepo.findPartnerByPartnerNumber(12345)).thenReturn(Optional.of(HsOfficePartnerRbacEntity.builder()
|
||||
.partnerNumber(12345)
|
||||
.build()));
|
||||
|
||||
|
@ -24,7 +24,7 @@ import static org.mockito.Mockito.lenient;
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class HsOfficePartnerEntityPatcherUnitTest extends PatchUnitTestBase<
|
||||
HsOfficePartnerPatchResource,
|
||||
HsOfficePartnerEntity
|
||||
HsOfficePartnerRbacEntity
|
||||
> {
|
||||
|
||||
private static final UUID INITIAL_PARTNER_UUID = UUID.randomUUID();
|
||||
@ -53,8 +53,8 @@ class HsOfficePartnerEntityPatcherUnitTest extends PatchUnitTestBase<
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HsOfficePartnerEntity newInitialEntity() {
|
||||
final var entity = HsOfficePartnerEntity.builder()
|
||||
protected HsOfficePartnerRbacEntity newInitialEntity() {
|
||||
final var entity = HsOfficePartnerRbacEntity.builder()
|
||||
.uuid(INITIAL_PARTNER_UUID)
|
||||
.partnerNumber(12345)
|
||||
.partnerRel(HsOfficeRelationRealEntity.builder()
|
||||
@ -72,7 +72,7 @@ class HsOfficePartnerEntityPatcherUnitTest extends PatchUnitTestBase<
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HsOfficePartnerEntityPatcher createPatcher(final HsOfficePartnerEntity partner) {
|
||||
protected HsOfficePartnerEntityPatcher createPatcher(final HsOfficePartnerRbacEntity partner) {
|
||||
return new HsOfficePartnerEntityPatcher(em, partner);
|
||||
}
|
||||
|
||||
@ -83,7 +83,7 @@ class HsOfficePartnerEntityPatcherUnitTest extends PatchUnitTestBase<
|
||||
"partnerRel",
|
||||
HsOfficePartnerPatchResource::setPartnerRelUuid,
|
||||
PATCHED_PARTNER_ROLE_UUID,
|
||||
HsOfficePartnerEntity::setPartnerRel,
|
||||
HsOfficePartnerRbacEntity::setPartnerRel,
|
||||
newPartnerRel(PATCHED_PARTNER_ROLE_UUID))
|
||||
.notNullable()
|
||||
);
|
||||
|
@ -12,7 +12,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class HsOfficePartnerEntityUnitTest {
|
||||
|
||||
private final HsOfficePartnerEntity givenPartner = HsOfficePartnerEntity.builder()
|
||||
private final HsOfficePartnerRbacEntity givenPartner = HsOfficePartnerRbacEntity.builder()
|
||||
.partnerNumber(12345)
|
||||
.partnerRel(HsOfficeRelationRealEntity.builder()
|
||||
.anchor(HsOfficePersonRealEntity.builder()
|
||||
@ -42,7 +42,7 @@ class HsOfficePartnerEntityUnitTest {
|
||||
|
||||
@Test
|
||||
void definesRbac() {
|
||||
final var rbacFlowchart = new RbacViewMermaidFlowchartGenerator(HsOfficePartnerEntity.rbac()).toString();
|
||||
final var rbacFlowchart = new RbacViewMermaidFlowchartGenerator(HsOfficePartnerRbacEntity.rbac()).toString();
|
||||
assertThat(rbacFlowchart).isEqualTo("""
|
||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||
flowchart TB
|
||||
|
@ -6,19 +6,19 @@ import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealRepository;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType;
|
||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||
import net.hostsharing.hsadminng.rbac.grant.RawRbacGrantRepository;
|
||||
import net.hostsharing.hsadminng.rbac.role.RawRbacObjectRepository;
|
||||
import net.hostsharing.hsadminng.rbac.role.RawRbacRoleRepository;
|
||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.orm.jpa.JpaSystemException;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.PersistenceContext;
|
||||
@ -27,20 +27,21 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static net.hostsharing.hsadminng.mapper.Array.from;
|
||||
import static net.hostsharing.hsadminng.rbac.grant.RawRbacGrantEntity.distinctGrantDisplaysOf;
|
||||
import static net.hostsharing.hsadminng.rbac.role.RawRbacObjectEntity.objectDisplaysOf;
|
||||
import static net.hostsharing.hsadminng.rbac.role.RawRbacRoleEntity.distinctRoleNamesOf;
|
||||
import static net.hostsharing.hsadminng.mapper.Array.from;
|
||||
import static net.hostsharing.hsadminng.rbac.role.RbacRoleType.ADMIN;
|
||||
import static net.hostsharing.hsadminng.rbac.role.RbacRoleType.AGENT;
|
||||
import static net.hostsharing.hsadminng.rbac.test.JpaAttempt.attempt;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@DataJpaTest
|
||||
@Import( { Context.class, JpaAttempt.class })
|
||||
class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithCleanup {
|
||||
@Import({ Context.class, JpaAttempt.class })
|
||||
class HsOfficePartnerRbacRepositoryIntegrationTest extends ContextBasedTestWithCleanup {
|
||||
|
||||
@Autowired
|
||||
HsOfficePartnerRepository partnerRepo;
|
||||
HsOfficePartnerRbacRepository partnerRepo;
|
||||
|
||||
@Autowired
|
||||
HsOfficeRelationRealRepository relationRepo;
|
||||
@ -66,7 +67,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
||||
@Autowired
|
||||
JpaAttempt jpaAttempt;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
HttpServletRequest request;
|
||||
|
||||
@Nested
|
||||
@ -80,18 +81,19 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
||||
final var partnerRel = givenSomeTemporaryHostsharingPartnerRel("Winkler", "first contact");
|
||||
|
||||
// when
|
||||
final var result = attempt(em, () -> {
|
||||
final var newPartner = HsOfficePartnerEntity.builder()
|
||||
.partnerNumber(20031)
|
||||
.partnerRel(partnerRel)
|
||||
.details(HsOfficePartnerDetailsEntity.builder().build())
|
||||
.build();
|
||||
return partnerRepo.save(newPartner);
|
||||
});
|
||||
final var result = attempt(
|
||||
em, () -> {
|
||||
final var newPartner = HsOfficePartnerRbacEntity.builder()
|
||||
.partnerNumber(20031)
|
||||
.partnerRel(partnerRel)
|
||||
.details(HsOfficePartnerDetailsEntity.builder().build())
|
||||
.build();
|
||||
return partnerRepo.save(newPartner);
|
||||
});
|
||||
|
||||
// then
|
||||
result.assertSuccessful();
|
||||
assertThat(result.returnedValue()).isNotNull().extracting(HsOfficePartnerEntity::getUuid).isNotNull();
|
||||
assertThat(result.returnedValue()).isNotNull().extracting(HsOfficePartnerRbacEntity::getUuid).isNotNull();
|
||||
assertThatPartnerIsPersisted(result.returnedValue());
|
||||
assertThat(partnerRepo.count()).isEqualTo(count + 1);
|
||||
}
|
||||
@ -108,26 +110,27 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
||||
.toList();
|
||||
|
||||
// when
|
||||
attempt(em, () -> {
|
||||
final var givenPartnerPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0);
|
||||
final var givenContact = contactrealRepo.findContactByOptionalCaptionLike("fourth contact").get(0);
|
||||
final var givenMandantPerson = personRepo.findPersonByOptionalNameLike("Hostsharing eG").get(0);
|
||||
attempt(
|
||||
em, () -> {
|
||||
final var givenPartnerPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0);
|
||||
final var givenContact = contactrealRepo.findContactByOptionalCaptionLike("fourth contact").get(0);
|
||||
final var givenMandantPerson = personRepo.findPersonByOptionalNameLike("Hostsharing eG").get(0);
|
||||
|
||||
final var newRelation = HsOfficeRelationRealEntity.builder()
|
||||
.holder(givenPartnerPerson)
|
||||
.type(HsOfficeRelationType.PARTNER)
|
||||
.anchor(givenMandantPerson)
|
||||
.contact(givenContact)
|
||||
.build();
|
||||
relationRepo.save(newRelation);
|
||||
final var newRelation = HsOfficeRelationRealEntity.builder()
|
||||
.holder(givenPartnerPerson)
|
||||
.type(HsOfficeRelationType.PARTNER)
|
||||
.anchor(givenMandantPerson)
|
||||
.contact(givenContact)
|
||||
.build();
|
||||
relationRepo.save(newRelation);
|
||||
|
||||
final var newPartner = HsOfficePartnerEntity.builder()
|
||||
.partnerNumber(20032)
|
||||
.partnerRel(newRelation)
|
||||
.details(HsOfficePartnerDetailsEntity.builder().build())
|
||||
.build();
|
||||
return partnerRepo.save(newPartner);
|
||||
}).assertSuccessful();
|
||||
final var newPartner = HsOfficePartnerRbacEntity.builder()
|
||||
.partnerNumber(20032)
|
||||
.partnerRel(newRelation)
|
||||
.details(HsOfficePartnerDetailsEntity.builder().build())
|
||||
.build();
|
||||
return partnerRepo.save(newPartner);
|
||||
}).assertSuccessful();
|
||||
|
||||
// then
|
||||
assertThat(distinctRoleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(from(
|
||||
@ -179,7 +182,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
||||
null)));
|
||||
}
|
||||
|
||||
private void assertThatPartnerIsPersisted(final HsOfficePartnerEntity saved) {
|
||||
private void assertThatPartnerIsPersisted(final HsOfficePartnerRbacEntity saved) {
|
||||
final var found = partnerRepo.findByUuid(saved.getUuid());
|
||||
assertThat(found).isNotEmpty().get().extracting(Object::toString).isEqualTo(saved.toString());
|
||||
}
|
||||
@ -207,15 +210,32 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
||||
}
|
||||
|
||||
@Test
|
||||
public void normalUser_canViewOnlyRelatedPartners() {
|
||||
public void partnerAgent_canViewOnlyRelatedPartnersWithDetails() {
|
||||
// given:
|
||||
context("person-FirstGmbH@example.com");
|
||||
context(
|
||||
"person-FirstGmbH@example.com",
|
||||
"hs_office.relation#HostsharingeG-with-PARTNER-FirstGmbH:AGENT");
|
||||
|
||||
// when:
|
||||
final var result = partnerRepo.findPartnerByOptionalNameLike(null);
|
||||
|
||||
// then:
|
||||
exactlyThesePartnersAreReturned(result, "partner(P-10001: LP First GmbH, first contact)");
|
||||
exactlyThesePartnersAreReturned(result,
|
||||
"partner(P-10001: LP First GmbH, first contact)+(partnerDetails(Hamburg, RegNo123456789))");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void partnerTenant_canViewRelatedPartnersButWithoutDetails() {
|
||||
// given:
|
||||
context(
|
||||
"person-FirstGmbH@example.com",
|
||||
"hs_office.relation#HostsharingeG-with-PARTNER-FirstGmbH:TENANT");
|
||||
|
||||
// when:
|
||||
final var result = partnerRepo.findPartnerByOptionalNameLike(null);
|
||||
|
||||
// then:
|
||||
exactlyThesePartnersAreReturned(result, "partner(P-10001: LP First GmbH, first contact)+null");
|
||||
}
|
||||
}
|
||||
|
||||
@ -223,7 +243,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
||||
class FindByNameLike {
|
||||
|
||||
@Test
|
||||
public void globalAdmin_withoutAssumedRole_canViewAllPartners() {
|
||||
public void globalAdmin_withoutAssumedRole_canViewAllPartnersWithDetails() {
|
||||
// given
|
||||
context("superuser-alex@hostsharing.net");
|
||||
|
||||
@ -231,7 +251,8 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
||||
final var result = partnerRepo.findPartnerByOptionalNameLike("third contact");
|
||||
|
||||
// then
|
||||
exactlyThesePartnersAreReturned(result, "partner(P-10003: IF Third OHG, third contact)");
|
||||
exactlyThesePartnersAreReturned(result,
|
||||
"partner(P-10003: IF Third OHG, third contact)+(partnerDetails(Hamburg, RegNo123456789))");
|
||||
}
|
||||
}
|
||||
|
||||
@ -289,19 +310,20 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
||||
}
|
||||
|
||||
@Test
|
||||
public void partnerRelationAgent_canUpdateRelatedPartner() {
|
||||
public void partnerRelationAgent_canUpdateRelatedPartnerDetails() {
|
||||
// given
|
||||
context("superuser-alex@hostsharing.net");
|
||||
final var givenPartner = givenSomeTemporaryHostsharingPartner(20037, "Erben Bessler", "ninth");
|
||||
assertThatPartnerIsVisibleForUserWithRole(
|
||||
givenPartner,
|
||||
"hs_office.person#ErbenBesslerMelBessler:ADMIN");
|
||||
givenPartner.getPartnerRel().roleId(AGENT));
|
||||
assertThatPartnerActuallyInDatabase(givenPartner);
|
||||
|
||||
// when
|
||||
final var result = jpaAttempt.transacted(() -> {
|
||||
context("superuser-alex@hostsharing.net",
|
||||
"hs_office.person#ErbenBesslerMelBessler:ADMIN");
|
||||
context(
|
||||
"superuser-alex@hostsharing.net",
|
||||
givenPartner.getPartnerRel().roleId(AGENT));
|
||||
givenPartner.getDetails().setBirthName("new birthname");
|
||||
return partnerRepo.save(givenPartner);
|
||||
});
|
||||
@ -310,37 +332,17 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
||||
result.assertSuccessful();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void partnerRelationTenant_canNotUpdateRelatedPartner() {
|
||||
// given
|
||||
context("superuser-alex@hostsharing.net");
|
||||
final var givenPartner = givenSomeTemporaryHostsharingPartner(20037, "Erben Bessler", "ninth");
|
||||
assertThatPartnerIsVisibleForUserWithRole(
|
||||
givenPartner,
|
||||
"hs_office.person#ErbenBesslerMelBessler:ADMIN");
|
||||
assertThatPartnerActuallyInDatabase(givenPartner);
|
||||
|
||||
// when
|
||||
final var result = jpaAttempt.transacted(() -> {
|
||||
context("superuser-alex@hostsharing.net",
|
||||
"hs_office.relation#HostsharingeG-with-PARTNER-ErbenBesslerMelBessler:TENANT");
|
||||
givenPartner.getDetails().setBirthName("new birthname");
|
||||
return partnerRepo.save(givenPartner);
|
||||
});
|
||||
|
||||
// then
|
||||
result.assertExceptionWithRootCauseMessage(JpaSystemException.class,
|
||||
"ERROR: [403] insert into hs_office.partner_details ",
|
||||
" not allowed for current subjects {hs_office.relation#HostsharingeG-with-PARTNER-ErbenBesslerMelBessler:TENANT}");
|
||||
}
|
||||
|
||||
private void assertThatPartnerActuallyInDatabase(final HsOfficePartnerEntity saved) {
|
||||
private void assertThatPartnerActuallyInDatabase(final HsOfficePartnerRbacEntity saved) {
|
||||
final var found = partnerRepo.findByUuid(saved.getUuid());
|
||||
assertThat(found).isNotEmpty().get().isNotSameAs(saved).extracting(HsOfficePartnerEntity::toString).isEqualTo(saved.toString());
|
||||
assertThat(found).isNotEmpty()
|
||||
.get()
|
||||
.isNotSameAs(saved)
|
||||
.extracting(HsOfficePartnerRbacEntity::toString)
|
||||
.isEqualTo(saved.toString());
|
||||
}
|
||||
|
||||
private void assertThatPartnerIsVisibleForUserWithRole(
|
||||
final HsOfficePartnerEntity entity,
|
||||
final HsOfficePartnerRbacEntity entity,
|
||||
final String assumedRoles) {
|
||||
jpaAttempt.transacted(() -> {
|
||||
context("superuser-alex@hostsharing.net", assumedRoles);
|
||||
@ -349,7 +351,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
||||
}
|
||||
|
||||
private void assertThatPartnerIsNotVisibleForUserWithRole(
|
||||
final HsOfficePartnerEntity entity,
|
||||
final HsOfficePartnerRbacEntity entity,
|
||||
final String assumedRoles) {
|
||||
jpaAttempt.transacted(() -> {
|
||||
context("superuser-alex@hostsharing.net", assumedRoles);
|
||||
@ -437,7 +439,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
||||
select currentTask, targetTable, targetOp, targetdelta->>'partnernumber'
|
||||
from base.tx_journal_v
|
||||
where targettable = 'hs_office.partner';
|
||||
""");
|
||||
""");
|
||||
|
||||
// when
|
||||
@SuppressWarnings("unchecked") final List<Object[]> customerLogEntries = query.getResultList();
|
||||
@ -451,19 +453,22 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
||||
"[creating partner test-data , hs_office.partner, INSERT, 10010]");
|
||||
}
|
||||
|
||||
private HsOfficePartnerEntity givenSomeTemporaryHostsharingPartner(
|
||||
private HsOfficePartnerRbacEntity givenSomeTemporaryHostsharingPartner(
|
||||
final Integer partnerNumber, final String person, final String contact) {
|
||||
return jpaAttempt.transacted(() -> {
|
||||
context("superuser-alex@hostsharing.net");
|
||||
final var partnerRel = givenSomeTemporaryHostsharingPartnerRel(person, contact);
|
||||
|
||||
final var newPartner = HsOfficePartnerEntity.builder()
|
||||
final var newPartner = HsOfficePartnerRbacEntity.builder()
|
||||
.partnerNumber(partnerNumber)
|
||||
.partnerRel(partnerRel)
|
||||
.details(HsOfficePartnerDetailsEntity.builder().build())
|
||||
.build();
|
||||
|
||||
return partnerRepo.save(newPartner);
|
||||
final var savedPartner = partnerRepo.save(newPartner);
|
||||
em.flush();
|
||||
final var partner = em.find(savedPartner.getClass(), savedPartner.getUuid());
|
||||
return savedPartner;
|
||||
}).assertSuccessful().returnedValue();
|
||||
}
|
||||
|
||||
@ -482,21 +487,23 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
||||
return partnerRel;
|
||||
}
|
||||
|
||||
void exactlyThesePartnersAreReturned(final List<HsOfficePartnerEntity> actualResult, final String... partnerNames) {
|
||||
void exactlyThesePartnersAreReturned(final List<HsOfficePartnerRbacEntity> actualResult, final String... partnerNames) {
|
||||
assertThat(actualResult)
|
||||
.extracting(partnerEntity -> partnerEntity.toString())
|
||||
.extracting(partner ->
|
||||
partner.toString() + "+" +
|
||||
(partner.getDetails() != null ? ("(" + partner.getDetails() + ")") : "null"))
|
||||
.containsExactlyInAnyOrder(partnerNames);
|
||||
}
|
||||
|
||||
void allThesePartnersAreReturned(final List<HsOfficePartnerEntity> actualResult, final String... partnerNames) {
|
||||
void allThesePartnersAreReturned(final List<HsOfficePartnerRbacEntity> actualResult, final String... partnerNames) {
|
||||
assertThat(actualResult)
|
||||
.extracting(partnerEntity -> partnerEntity.toString())
|
||||
.extracting(HsOfficePartnerRbacEntity::toString)
|
||||
.contains(partnerNames);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void cleanup() {
|
||||
cleanupAllNew(HsOfficePartnerEntity.class);
|
||||
cleanupAllNew(HsOfficePartnerRbacEntity.class);
|
||||
}
|
||||
|
||||
private String[] distinct(final String[] strings) {
|
@ -7,12 +7,12 @@ import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType.LEGAL_PERSON;
|
||||
|
||||
public class TestHsOfficePartner {
|
||||
public class HsOfficeTestRealPartner {
|
||||
|
||||
public static final HsOfficePartnerEntity TEST_PARTNER = hsOfficePartnerWithLegalPerson("Test Ltd.");
|
||||
public static final HsOfficePartnerRealEntity TEST_PARTNER = hsOfficePartnerWithLegalPerson("Test Ltd.");
|
||||
|
||||
static public HsOfficePartnerEntity hsOfficePartnerWithLegalPerson(final String tradeName) {
|
||||
return HsOfficePartnerEntity.builder()
|
||||
static public HsOfficePartnerRealEntity hsOfficePartnerWithLegalPerson(final String tradeName) {
|
||||
return HsOfficePartnerRealEntity.builder()
|
||||
.partnerNumber(10001)
|
||||
.partnerRel(
|
||||
HsOfficeRelationRealEntity.builder()
|
@ -331,7 +331,6 @@ class HsOfficePersonControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
return jpaAttempt.transacted(() -> {
|
||||
context.define(creatingUser);
|
||||
final var newPerson = HsOfficePersonRealEntity.builder()
|
||||
.uuid(UUID.randomUUID())
|
||||
.personType(HsOfficePersonType.LEGAL_PERSON)
|
||||
.tradeName("Temp " + Context.getCallerMethodNameFromStackFrame(2))
|
||||
.familyName(RandomStringUtils.randomAlphabetic(10) + "@example.org")
|
||||
|
@ -11,7 +11,7 @@ import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
@ -46,7 +46,7 @@ class HsOfficePersonRbacRepositoryIntegrationTest extends ContextBasedTestWithCl
|
||||
@Autowired
|
||||
JpaAttempt jpaAttempt;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
HttpServletRequest request;
|
||||
|
||||
@Nested
|
||||
|
@ -10,7 +10,7 @@ import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
@ -44,7 +44,7 @@ class HsOfficePersonRealRepositoryIntegrationTest extends ContextBasedTestWithCl
|
||||
@Autowired
|
||||
JpaAttempt jpaAttempt;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
HttpServletRequest request;
|
||||
@Autowired
|
||||
private HsOfficePersonRealRepository hsOfficePersonRealRepository;
|
||||
|
@ -9,7 +9,7 @@ import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
@ -35,7 +35,7 @@ class HsOfficeRealRelationRepositoryIntegrationTest extends ContextBasedTestWith
|
||||
@PersistenceContext
|
||||
EntityManager em;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
HttpServletRequest request;
|
||||
|
||||
@Nested
|
||||
|
@ -13,7 +13,7 @@ import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.orm.jpa.JpaSystemException;
|
||||
|
||||
@ -58,7 +58,7 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
||||
@Autowired
|
||||
JpaAttempt jpaAttempt;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
HttpServletRequest request;
|
||||
|
||||
@Nested
|
||||
|
@ -180,10 +180,9 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
|
||||
void globalAdmin_canNotPostNewSepaMandateWhenDebitorUuidIsMissing() {
|
||||
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
final var givenDebitor = debitorRepo.findDebitorsByOptionalNameLike("Third").get(0);
|
||||
final var givenBankAccount = bankAccountRepo.findByIbanOrderByIbanAsc("DE02200505501015871393").get(0);
|
||||
|
||||
final var location = RestAssured // @formatter:off
|
||||
RestAssured // @formatter:off
|
||||
.given()
|
||||
.header("current-subject", "superuser-alex@hostsharing.net")
|
||||
.contentType(ContentType.JSON)
|
||||
@ -227,12 +226,12 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
|
||||
.post("http://localhost/api/hs/office/sepamandates")
|
||||
.then().log().all().assertThat()
|
||||
.statusCode(400)
|
||||
.body("message", is("ERROR: [400] Unable to find BankAccount with uuid 00000000-0000-0000-0000-000000000000"));
|
||||
.body("message", is("ERROR: [400] bankAccount.uuid='00000000-0000-0000-0000-000000000000' not found or not accessible"));
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
void globalAdmin_canNotPostNewSepaMandate_ifPersonDoesNotExist() {
|
||||
void globalAdmin_canNotPostNewSepaMandate_ifDebitorDoesNotExist() {
|
||||
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
final var givenDebitorUuid = UUID.fromString("00000000-0000-0000-0000-000000000000");
|
||||
@ -257,7 +256,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
|
||||
.post("http://localhost/api/hs/office/sepamandates")
|
||||
.then().log().all().assertThat()
|
||||
.statusCode(400)
|
||||
.body("message", is("ERROR: [400] Unable to find Debitor with uuid 00000000-0000-0000-0000-000000000000"));
|
||||
.body("message", is("ERROR: [400] debitor.uuid='00000000-0000-0000-0000-000000000000' not found or not accessible"));
|
||||
// @formatter:on
|
||||
}
|
||||
}
|
||||
@ -529,7 +528,6 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
|
||||
.orElse(givenDebitor.getPartner().getPartnerRel().getHolder().getFamilyName());
|
||||
final var givenBankAccount = bankAccountRepo.findByOptionalHolderLike(bankAccountHolder).get(0);
|
||||
final var newSepaMandate = HsOfficeSepaMandateEntity.builder()
|
||||
.uuid(UUID.randomUUID())
|
||||
.debitor(givenDebitor)
|
||||
.bankAccount(givenBankAccount)
|
||||
.reference("temp ref CAT Z")
|
||||
|
@ -13,7 +13,7 @@ import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.orm.jpa.JpaSystemException;
|
||||
|
||||
@ -55,7 +55,7 @@ class HsOfficeSepaMandateRepositoryIntegrationTest extends ContextBasedTestWithC
|
||||
@PersistenceContext
|
||||
EntityManager em;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
HttpServletRequest request;
|
||||
|
||||
@Nested
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user