introduce-booking-module #41
@ -26,7 +26,7 @@ import java.util.UUID;
|
||||
import java.util.function.BinaryOperator;
|
||||
|
||||
import static java.util.Optional.ofNullable;
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.lowerInclusiveFromPostgresDateRange;
|
||||
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateRange;
|
||||
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.upperInclusiveFromPostgresDateRange;
|
||||
@ -51,9 +51,18 @@ public class HsBookingItemEntity implements Stringifyable, RbacObject {
|
||||
.withProp(e -> e.getDebitor().toShortString())
|
||||
.withProp(e -> e.getValidity().asString())
|
||||
.withProp(HsBookingItemEntity::getCaption)
|
||||
.withProp(HsBookingItemEntity::getResources)
|
||||
.withProp(HsBookingItemEntity::getResourcesAsString)
|
||||
.quotedValues(false);
|
||||
|
||||
private String getResourcesAsString() {
|
||||
return "{ " +
|
||||
(
|
||||
resources.keySet().stream().sorted()
|
||||
.map(k -> k + ": " + resources.get(k)))
|
||||
.collect(joining(", ")
|
||||
) + " }";
|
||||
}
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private UUID uuid;
|
||||
@ -78,11 +87,6 @@ public class HsBookingItemEntity implements Stringifyable, RbacObject {
|
||||
@Column(columnDefinition = "resources")
|
||||
private Map<String, Object> resources = new TreeMap<>();
|
||||
|
||||
public Map<String, Object> getResources() {
|
||||
return resources.entrySet().stream()
|
||||
.collect(toMap(Map.Entry::getKey, Map.Entry::getValue, HsBookingItemEntity::thereIsOnlyOneValuePerKey, TreeMap::new));
|
||||
}
|
||||
|
||||
public void setValidFrom(final LocalDate validFrom) {
|
||||
setValidity(toPostgresDateRange(validFrom, getValidTo()));
|
||||
}
|
||||
|
@ -4,10 +4,11 @@ import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.ArbitraryBook
|
||||
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingItemPatchResource;
|
||||
import net.hostsharing.hsadminng.mapper.EntityPatcher;
|
||||
import net.hostsharing.hsadminng.mapper.OptionalFromJson;
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.Arrays.stream;
|
||||
|
||||
@ -38,16 +39,24 @@ public class HsBookingItemEntityPatcher implements EntityPatcher<HsBookingItemPa
|
||||
}
|
||||
|
||||
static Map<String, Object> objectToMap(final Object obj) {
|
||||
final var map = stream(obj.getClass().getDeclaredFields())
|
||||
return stream(obj.getClass().getDeclaredFields())
|
||||
.map(field -> {
|
||||
try {
|
||||
field.setAccessible(true);
|
||||
return Map.entry(field.getName(), field.get(obj));
|
||||
return new ImmutablePair<>(field.getName(), field.get(obj));
|
||||
} catch (final IllegalAccessException exc) {
|
||||
throw new RuntimeException(exc);
|
||||
}
|
||||
})
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
.reduce(
|
||||
new HashMap<>(),
|
||||
(map, pair) -> {
|
||||
map.put(pair.getKey(), pair.getValue());
|
||||
return map;
|
||||
},
|
||||
(map1, map2) -> {
|
||||
map1.putAll(map2);
|
||||
return map1;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ import jakarta.persistence.*;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static java.util.Optional.ofNullable;
|
||||
|
@ -2,9 +2,7 @@ package net.hostsharing.hsadminng.hs.office.coopshares;
|
||||
|
||||
import jakarta.persistence.EntityNotFoundException;
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.hs.office.coopassets.HsOfficeCoopAssetsTransactionEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeCoopSharesApi;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopAssetsTransactionInsertResource;
|
||||
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.mapper.Mapper;
|
||||
|
@ -6,7 +6,6 @@ import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||
import net.hostsharing.hsadminng.hs.office.coopassets.HsOfficeCoopAssetsTransactionEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||
|
@ -148,6 +148,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
final var givenBookingItemUuid = bookingItemRepo.findAll().stream()
|
||||
.filter(bi -> bi.getDebitor().getDebitorNumber() == 1000111)
|
||||
.filter(item -> item.getCaption().equals("some CloudServer"))
|
||||
.findAny().orElseThrow().getUuid();
|
||||
|
||||
RestAssured // @formatter:off
|
||||
@ -192,8 +193,8 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
final var givenBookingItemUuid = bookingItemRepo.findAll().stream()
|
||||
.filter(bi -> bi.getDebitor().getDebitorNumber() == 1000313)
|
||||
.filter(item -> item.getCaption().equals("some CloudServer"))
|
||||
.findAny().orElseThrow().getUuid();
|
||||
generateRbacDiagramForObjectPermission(givenBookingItemUuid, "SELECT", "booking-item-of-debitor-1000313");
|
||||
|
||||
RestAssured // @formatter:off
|
||||
.given()
|
||||
|
@ -35,12 +35,17 @@ class HsBookingItemEntityPatcherUnitTest extends PatchUnitTestBase<
|
||||
private static final LocalDate PATCHED_VALID_FROM = LocalDate.parse("2022-10-30");
|
||||
private static final LocalDate PATCHED_VALID_TO = LocalDate.parse("2022-12-31");
|
||||
|
||||
private static final ArbitraryBookingResourcesJsonResource PATCHED_RESOURCES = new ArbitraryBookingResourcesJsonResource() {
|
||||
int cpus = 2;
|
||||
int sddStorage = 256;
|
||||
int hddStorage = 2048;
|
||||
private static final ArbitraryBookingResourcesJsonResource INITIAL_RESOURCES = new ArbitraryBookingResourcesJsonResource() {
|
||||
Integer cpus = 1;
|
||||
Integer hddStorage = 1024;
|
||||
};
|
||||
private static final String PATCHED_CAPTION = "caption-patched";
|
||||
private static final ArbitraryBookingResourcesJsonResource PATCHED_RESOURCES = new ArbitraryBookingResourcesJsonResource() {
|
||||
Integer cpus = 2;
|
||||
Integer sddStorage = 256;
|
||||
Integer hddStorage = null;
|
||||
};
|
||||
private static final String INITIAL_CAPTION = "initial caption";
|
||||
private static final String PATCHED_CAPTION = "patched caption";
|
||||
|
||||
@Mock
|
||||
private EntityManager em;
|
||||
@ -58,8 +63,8 @@ class HsBookingItemEntityPatcherUnitTest extends PatchUnitTestBase<
|
||||
final var entity = new HsBookingItemEntity();
|
||||
entity.setUuid(INITIAL_BOOKING_ITEM_UUID);
|
||||
entity.setDebitor(TEST_DEBITOR);
|
||||
entity.setResources(objectToMap(PATCHED_RESOURCES));
|
||||
entity.setCaption(PATCHED_CAPTION);
|
||||
entity.setResources(objectToMap(INITIAL_RESOURCES));
|
||||
entity.setCaption(INITIAL_CAPTION);
|
||||
entity.setValidity(Range.closedInfinite(GIVEN_VALID_FROM));
|
||||
return entity;
|
||||
}
|
||||
@ -82,13 +87,13 @@ class HsBookingItemEntityPatcherUnitTest extends PatchUnitTestBase<
|
||||
HsBookingItemPatchResource::setCaption,
|
||||
PATCHED_CAPTION,
|
||||
HsBookingItemEntity::setCaption),
|
||||
// FIXME
|
||||
// new JsonNullableProperty<>(
|
||||
// "resources",
|
||||
// HsBookingItemPatchResource::setResources,
|
||||
// PATCHED_RESOURCES,
|
||||
// HsBookingItemEntity::setResources,
|
||||
// objectToMap(PATCHED_RESOURCES)),
|
||||
new SimpleProperty<>(
|
||||
"resources",
|
||||
HsBookingItemPatchResource::setResources,
|
||||
PATCHED_RESOURCES,
|
||||
HsBookingItemEntity::setResources,
|
||||
objectToMap(PATCHED_RESOURCES))
|
||||
.notNullable(),
|
||||
new JsonNullableProperty<>(
|
||||
"validfrom",
|
||||
HsBookingItemPatchResource::setValidFrom,
|
||||
|
@ -28,7 +28,7 @@ class HsBookingItemEntityUnitTest {
|
||||
void toStringContainsAllPropertiesAndResourcesSortedByKey() {
|
||||
final var result = givenBookingItem.toString();
|
||||
|
||||
assertThat(result).isEqualTo("HsBookingItemEntity(D-1000100, [2020-01-01,2031-01-01), some caption, {CPUs=2, HDD-storage=2048, SSD-storage=512})");
|
||||
assertThat(result).isEqualTo("HsBookingItemEntity(D-1000100, [2020-01-01,2031-01-01), some caption, { CPUs: 2, HDD-storage: 2048, SSD-storage: 512 })");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -109,16 +109,16 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
|
||||
final var all = rawRoleRepo.findAll();
|
||||
assertThat(distinctRoleNamesOf(all)).containsExactlyInAnyOrder(Array.from(
|
||||
initialRoleNames,
|
||||
"hs_booking_item#somenewbookingitem:ADMIN",
|
||||
"hs_booking_item#somenewbookingitem:OWNER",
|
||||
"hs_booking_item#somenewbookingitem:TENANT"));
|
||||
"hs_booking_item#D-1000111:some new booking item:ADMIN",
|
||||
"hs_booking_item#D-1000111:some new booking item:OWNER",
|
||||
"hs_booking_item#D-1000111:some new booking item:TENANT"));
|
||||
assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll()))
|
||||
.map(s -> s.replace("hs_office_", ""))
|
||||
.containsExactlyInAnyOrder(fromFormatted(
|
||||
initialGrantNames,
|
||||
|
||||
// insert+delete
|
||||
"{ grant perm:hs_booking_item#somenewbookingitem:DELETE to role:global#global:ADMIN by system and assume }",
|
||||
"{ grant perm:hs_booking_item#D-1000111:some new booking item:DELETE to role:global#global:ADMIN by system and assume }",
|
||||
|
||||
// owner
|
||||
|
||||
@ -126,12 +126,12 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
|
||||
|
||||
// tenant
|
||||
|
||||
"{ grant perm:hs_booking_item#somenewbookingitem:SELECT to role:hs_booking_item#somenewbookingitem:TENANT by system and assume }",
|
||||
"{ grant perm:hs_booking_item#somenewbookingitem:UPDATE to role:hs_booking_item#somenewbookingitem:OWNER by system and assume }",
|
||||
"{ grant role:hs_booking_item#somenewbookingitem:ADMIN to role:hs_booking_item#somenewbookingitem:OWNER by system and assume }",
|
||||
"{ grant role:hs_booking_item#somenewbookingitem:OWNER to role:relation#FirstGmbH-with-DEBITOR-FirstGmbH:AGENT by system and assume }",
|
||||
"{ grant role:hs_booking_item#somenewbookingitem:TENANT to role:hs_booking_item#somenewbookingitem:ADMIN by system and assume }",
|
||||
"{ grant role:relation#FirstGmbH-with-DEBITOR-FirstGmbH:TENANT to role:hs_booking_item#somenewbookingitem:TENANT by system and assume }",
|
||||
"{ grant perm:hs_booking_item#D-1000111:some new booking item:SELECT to role:hs_booking_item#D-1000111:some new booking item:TENANT by system and assume }",
|
||||
"{ grant perm:hs_booking_item#D-1000111:some new booking item:UPDATE to role:hs_booking_item#D-1000111:some new booking item:OWNER by system and assume }",
|
||||
"{ grant role:hs_booking_item#D-1000111:some new booking item:ADMIN to role:hs_booking_item#D-1000111:some new booking item:OWNER by system and assume }",
|
||||
"{ grant role:hs_booking_item#D-1000111:some new booking item:OWNER to role:relation#FirstGmbH-with-DEBITOR-FirstGmbH:AGENT by system and assume }",
|
||||
"{ grant role:hs_booking_item#D-1000111:some new booking item:TENANT to role:hs_booking_item#D-1000111:some new booking item:ADMIN by system and assume }",
|
||||
"{ grant role:relation#FirstGmbH-with-DEBITOR-FirstGmbH:TENANT to role:hs_booking_item#D-1000111:some new booking item:TENANT by system and assume }",
|
||||
null));
|
||||
}
|
||||
|
||||
@ -148,7 +148,8 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
|
||||
public void globalAdmin_withoutAssumedRole_canViewAllBookingItemsOfArbitraryDebitor() {
|
||||
// given
|
||||
context("superuser-alex@hostsharing.net");
|
||||
final var debitorUuid = debitorRepo.findDebitorByDebitorNumber(1000212).stream().findAny().orElseThrow().getUuid();
|
||||
final var debitorUuid = debitorRepo.findDebitorByDebitorNumber(1000212).stream()
|
||||
.findAny().orElseThrow().getUuid();
|
||||
|
||||
// when
|
||||
final var result = bookingItemRepo.findAllByDebitorUuid(debitorUuid);
|
||||
@ -156,9 +157,9 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
|
||||
// then
|
||||
allTheseBookingItemsAreReturned(
|
||||
result,
|
||||
"HsBookingItemEntity(D-1000212, [2023-01-15,2024-04-15), some CloudServer, {CPUs=2, HDD-storage=1024})",
|
||||
"HsBookingItemEntity(D-1000212, [2022-10-01,), some ManagedServer, {CPUs=2, SDD-storage=512})",
|
||||
"HsBookingItemEntity(D-1000212, [2024-04-01,), some Whatever, {CPUs=1, HDD-storage=2048, SDD-storage=512})");
|
||||
"HsBookingItemEntity(D-1000212, [2022-10-01,), some ManagedServer, { CPUs: 2, SDD-storage: 512 })",
|
||||
"HsBookingItemEntity(D-1000212, [2023-01-15,2024-04-15), some CloudServer, { CPUs: 2, HDD-storage: 1024 })",
|
||||
"HsBookingItemEntity(D-1000212, [2024-04-01,), some Whatever, { CPUs: 1, HDD-storage: 2048, SDD-storage: 512 })");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -173,9 +174,9 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
|
||||
// then:
|
||||
exactlyTheseBookingItemsAreReturned(
|
||||
result,
|
||||
"HsBookingItemEntity(D-1000111, [2023-01-15,2024-04-15), some CloudServer, {CPUs=2, HDD-storage=1024})",
|
||||
"HsBookingItemEntity(D-1000111, [2022-10-01,), some ManagedServer, {CPUs=2, SDD-storage=512})",
|
||||
"HsBookingItemEntity(D-1000111, [2024-04-01,), some Whatever, {CPUs=1, HDD-storage=2048, SDD-storage=512})");
|
||||
"HsBookingItemEntity(D-1000111, [2022-10-01,), some ManagedServer, { CPUs: 2, SDD-storage: 512 })",
|
||||
"HsBookingItemEntity(D-1000111, [2023-01-15,2024-04-15), some CloudServer, { CPUs: 2, HDD-storage: 1024 })",
|
||||
"HsBookingItemEntity(D-1000111, [2024-04-01,), some Whatever, { CPUs: 1, HDD-storage: 2048, SDD-storage: 512 })");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,7 @@
|
||||
package net.hostsharing.hsadminng.hs.office.coopshares;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.office.coopassets.HsOfficeCoopAssetsTransactionEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.coopassets.HsOfficeCoopAssetsTransactionType;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.office.membership.TestHsMembership.TEST_MEMBERSHIP;
|
||||
|
Loading…
Reference in New Issue
Block a user