finalize PrivateCloud, Cloud- and ManagedServer and ManagedWebspace Billingtems and HostingAssets #63

Merged
hsh-michaelhoennig merged 9 commits from cloud-server-and-webspace-billing-items-and-hosting-assets into master 2024-06-20 11:03:59 +02:00
6 changed files with 32 additions and 11 deletions
Showing only changes of commit de9f5b617f - Show all commits

View File

@ -8,7 +8,11 @@ import static java.lang.String.join;
public class MultiValidationException extends ValidationException { public class MultiValidationException extends ValidationException {
private MultiValidationException(final List<String> violations) { private MultiValidationException(final List<String> violations) {
super("[\n" + join(",\n", violations) + "\n]"); super(
violations.size() > 1
? "[\n" + join(",\n", violations) + "\n]"
: "[" + join(",\n", violations) + "]"
);
} }
public static void throwInvalid(final List<String> violations) { public static void throwInvalid(final List<String> violations) {

View File

@ -1,5 +1,6 @@
package net.hostsharing.hsadminng.hs.hosting.asset; package net.hostsharing.hsadminng.hs.hosting.asset;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRepository;
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.api.HsHostingAssetsApi; import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.api.HsHostingAssetsApi;
import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.context.Context;
@ -34,6 +35,9 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
@Autowired @Autowired
private HsHostingAssetRepository assetRepo; private HsHostingAssetRepository assetRepo;
@Autowired
private HsBookingItemRepository bookingItemRepo;
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<List<HsHostingAssetResource>> listAssets( public ResponseEntity<List<HsHostingAssetResource>> listAssets(
@ -124,6 +128,11 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
final BiConsumer<HsHostingAssetInsertResource, HsHostingAssetEntity> RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> { final BiConsumer<HsHostingAssetInsertResource, HsHostingAssetEntity> RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
entity.putConfig(KeyValueMap.from(resource.getConfig())); entity.putConfig(KeyValueMap.from(resource.getConfig()));
if (resource.getBookingItemUuid() != null) {
entity.setBookingItem(bookingItemRepo.findByUuid(resource.getBookingItemUuid())
.orElseThrow(() -> new EntityNotFoundException("ERROR: [400] bookingItemUuid %s not found".formatted(
resource.getBookingItemUuid()))));
}
if (resource.getParentAssetUuid() != null) { if (resource.getParentAssetUuid() != null) {
entity.setParentAsset(assetRepo.findByUuid(resource.getParentAssetUuid()) entity.setParentAsset(assetRepo.findByUuid(resource.getParentAssetUuid())
.orElseThrow(() -> new EntityNotFoundException("ERROR: [400] parentAssetUuid %s not found".formatted( .orElseThrow(() -> new EntityNotFoundException("ERROR: [400] parentAssetUuid %s not found".formatted(

View File

@ -27,6 +27,7 @@ import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn; import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne; import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany; import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table; import jakarta.persistence.Table;
import jakarta.persistence.Transient; import jakarta.persistence.Transient;
import jakarta.persistence.Version; import jakarta.persistence.Version;
@ -78,7 +79,7 @@ public class HsHostingAssetEntity implements Stringifyable, RbacObject {
@Version @Version
private int version; private int version;
@ManyToOne(fetch = FetchType.LAZY) @OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "bookingitemuuid") @JoinColumn(name = "bookingitemuuid")
private HsBookingItemEntity bookingItem; private HsBookingItemEntity bookingItem;

View File

@ -332,9 +332,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
.body("", lenientlyEquals(""" .body("", lenientlyEquals("""
{ {
"statusPhrase": "Bad Request", "statusPhrase": "Bad Request",
"message": "[ "message": "['D-1000111:D-1000111 default project:separate ManagedWebspace.resources.Multi=1 allows at maximum 25 unix users, but 26 found]"
<<<'D-1000111:D-1000111 default project:separate ManagedWebspace.resources.Multi=1 allows at maximum 25 unix users, but 26 found
<<<]"
} }
""".replaceAll(" +<<<", ""))); // @formatter:on """.replaceAll(" +<<<", ""))); // @formatter:on
} }

View File

@ -109,9 +109,9 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
assertThat(debitorRepo.count()).isEqualTo(count + 1); assertThat(debitorRepo.count()).isEqualTo(count + 1);
} }
@Transactional
@ParameterizedTest @ParameterizedTest
@ValueSource(strings = {"", "a", "ab", "a12", "123", "12a"}) @ValueSource(strings = {"", "a", "ab", "a12", "123", "12a"})
@Transactional
public void canNotCreateNewDebitorWithInvalidDefaultPrefix(final String givenPrefix) { public void canNotCreateNewDebitorWithInvalidDefaultPrefix(final String givenPrefix) {
// given // given
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");

View File

@ -14,6 +14,7 @@ import org.junit.jupiter.api.TestInfo;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository; import org.springframework.data.repository.Repository;
import org.springframework.transaction.PlatformTransactionManager;
import jakarta.persistence.*; import jakarta.persistence.*;
import java.util.*; import java.util.*;
@ -28,9 +29,13 @@ import static org.assertj.core.api.Assertions.assertThat;
public abstract class ContextBasedTestWithCleanup extends ContextBasedTest { public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
private static final boolean DETAILED_BUT_SLOW_CHECK = true; private static final boolean DETAILED_BUT_SLOW_CHECK = true;
@PersistenceContext @PersistenceContext
protected EntityManager em; protected EntityManager em;
@Autowired
private PlatformTransactionManager tm;
@Autowired @Autowired
RbacGrantRepository rbacGrantRepo; RbacGrantRepository rbacGrantRepo;
@ -166,12 +171,16 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
@AfterEach @AfterEach
void cleanupAndCheckCleanup(final TestInfo testInfo) { void cleanupAndCheckCleanup(final TestInfo testInfo) {
out.println(ContextBasedTestWithCleanup.class.getSimpleName() + ".cleanupAndCheckCleanup"); // If the whole test method has its own transaction, cleanup makes no sense.
cleanupTemporaryTestData(); // If that transaction even failed, cleaunup would cause an exception.
deleteLeakedRbacObjects(); if (!tm.getTransaction(null).isRollbackOnly()) {
long rbacObjectCount = assertNoNewRbacObjectsRolesAndGrantsLeaked(); out.println(ContextBasedTestWithCleanup.class.getSimpleName() + ".cleanupAndCheckCleanup");
cleanupTemporaryTestData();
deleteLeakedRbacObjects();
out.println("TOTAL OBJECT COUNT (after): " + rbacObjectCount); long rbacObjectCount = assertNoNewRbacObjectsRolesAndGrantsLeaked();
out.println("TOTAL OBJECT COUNT (after): " + rbacObjectCount);
}
} }
private void cleanupTemporaryTestData() { private void cleanupTemporaryTestData() {