properly split up HsBookingProjectEntity into HsBookingProjectReal+RbacEntity extending HsBookingProject

This commit is contained in:
Michael Hoennig 2024-08-15 14:05:16 +02:00
parent 23c45c0bd8
commit 06784e03f4
32 changed files with 315 additions and 180 deletions

View File

@ -9,8 +9,9 @@ import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProject;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
import net.hostsharing.hsadminng.hs.validation.PropertiesProvider;
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
@ -90,7 +91,7 @@ public class HsBookingItemEntity implements Stringifyable, BaseEntity<HsBookingI
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "projectuuid")
private HsBookingProjectEntity project;
private HsBookingProjectRealEntity project;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parentitemuuid")
@ -120,7 +121,7 @@ public class HsBookingItemEntity implements Stringifyable, BaseEntity<HsBookingI
private List<HsBookingItemEntity> subBookingItems;
@OneToOne(mappedBy="bookingItem")
private HsHostingAssetRbacEntity relatedHostingAsset;
private HsHostingAssetRealEntity relatedHostingAsset;
@Transient
private PatchableMapWrapper<Object> resourcesWrapper;
@ -181,18 +182,18 @@ public class HsBookingItemEntity implements Stringifyable, BaseEntity<HsBookingI
@Override
public String toShortString() {
return ofNullable(relatedProject()).map(HsBookingProjectEntity::toShortString).orElse("D-???????-?") +
return ofNullable(relatedProject()).map(HsBookingProject::toShortString).orElse("D-???????-?") +
":" + caption;
}
private HsBookingProjectEntity relatedProject() {
private HsBookingProject relatedProject() {
if (project != null) {
return project;
}
return parentItem == null ? null : parentItem.relatedProject();
}
public HsBookingProjectEntity getRelatedProject() {
public HsBookingProject getRelatedProject() {
return project != null ? project
: parentItem != null ? parentItem.getRelatedProject()
: null; // can be the case for technical assets like IP-numbers
@ -206,7 +207,7 @@ public class HsBookingItemEntity implements Stringifyable, BaseEntity<HsBookingI
.toRole("global", ADMIN).grantPermission(INSERT) // TODO.impl: Why is this necessary to insert test data?
.toRole("global", ADMIN).grantPermission(DELETE)
.importEntityAlias("project", HsBookingProjectEntity.class, usingDefaultCase(),
.importEntityAlias("project", HsBookingProject.class, usingDefaultCase(),
dependsOnColumn("projectUuid"),
directlyFetchedByDependsOnColumn(),
NULLABLE)

View File

@ -1,6 +1,7 @@
package net.hostsharing.hsadminng.hs.booking.project;
import lombok.*;
import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
@ -27,18 +28,17 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.fetchedBySql;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Builder
@Entity
@Table(name = "hs_booking_project_rv")
@MappedSuperclass
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class HsBookingProjectEntity implements Stringifyable, BaseEntity<HsBookingProjectEntity> {
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@SuperBuilder(builderMethodName = "baseBuilder", toBuilder = true)
public class HsBookingProject implements Stringifyable, BaseEntity<HsBookingProject> {
private static Stringify<HsBookingProjectEntity> stringify = stringify(HsBookingProjectEntity.class)
.withProp(HsBookingProjectEntity::getDebitor)
.withProp(HsBookingProjectEntity::getCaption)
private static Stringify<HsBookingProject> stringify = stringify(HsBookingProject.class)
.withProp(HsBookingProject::getDebitor)
.withProp(HsBookingProject::getCaption)
.quotedValues(false);
@Id
@ -67,7 +67,7 @@ public class HsBookingProjectEntity implements Stringifyable, BaseEntity<HsBooki
}
public static RbacView rbac() {
return rbacViewFor("project", HsBookingProjectEntity.class)
return rbacViewFor("project", HsBookingProject.class)
.withIdentityView(SQL.query("""
SELECT bookingProject.uuid as uuid, debitorIV.idName || '-' || cleanIdentifier(bookingProject.caption) as idName
FROM hs_booking_project bookingProject

View File

@ -28,7 +28,7 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
private Mapper mapper;
@Autowired
private HsBookingProjectRepository bookingProjectRepo;
private HsBookingProjectRbacRepository bookingProjectRepo;
@Autowired
private HsBookingDebitorRepository debitorRepo;
@ -56,7 +56,7 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
context.define(currentUser, assumedRoles);
final var entityToSave = mapper.map(body, HsBookingProjectEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
final var entityToSave = mapper.map(body, HsBookingProjectRbacEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
final var saved = bookingProjectRepo.save(entityToSave);
@ -118,7 +118,7 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
return ResponseEntity.ok(mapped);
}
final BiConsumer<HsBookingProjectInsertResource, HsBookingProjectEntity> RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
final BiConsumer<HsBookingProjectInsertResource, HsBookingProjectRbacEntity> RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
if (resource.getDebitorUuid() != null) {
entity.setDebitor(debitorRepo.findByUuid(resource.getDebitorUuid())
.orElseThrow(() -> new EntityNotFoundException("ERROR: [400] debitorUuid %s not found".formatted(

View File

@ -8,9 +8,9 @@ import net.hostsharing.hsadminng.mapper.OptionalFromJson;
public class HsBookingProjectEntityPatcher implements EntityPatcher<HsBookingProjectPatchResource> {
private final HsBookingProjectEntity entity;
private final HsBookingProject entity;
public HsBookingProjectEntityPatcher(final HsBookingProjectEntity entity) {
public HsBookingProjectEntityPatcher(final HsBookingProject entity) {
this.entity = entity;
}

View File

@ -0,0 +1,86 @@
package net.hostsharing.hsadminng.hs.booking.project;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
import java.io.IOException;
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.DEBITOR;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingCase;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.DELETE;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.INSERT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.SELECT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.UPDATE;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.ADMIN;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.AGENT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.OWNER;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.TENANT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.fetchedBySql;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
@Entity
@Table(name = "hs_booking_project_rv")
@SuperBuilder(toBuilder = true)
@Getter
@Setter
@NoArgsConstructor
public class HsBookingProjectRbacEntity extends HsBookingProject {
public static RbacView rbac() {
return rbacViewFor("project", HsBookingProjectRbacEntity.class)
.withIdentityView(SQL.query("""
SELECT bookingProject.uuid as uuid, debitorIV.idName || '-' || cleanIdentifier(bookingProject.caption) as idName
FROM hs_booking_project bookingProject
JOIN hs_office_debitor_iv debitorIV ON debitorIV.uuid = bookingProject.debitorUuid
"""))
.withRestrictedViewOrderBy(SQL.expression("caption"))
.withUpdatableColumns("version", "caption")
.importEntityAlias("debitor", HsOfficeDebitorEntity.class, usingDefaultCase(),
dependsOnColumn("debitorUuid"),
directlyFetchedByDependsOnColumn(),
NOT_NULL)
.importEntityAlias("debitorRel", HsOfficeRelationRbacEntity.class, usingCase(DEBITOR),
dependsOnColumn("debitorUuid"),
fetchedBySql("""
SELECT ${columns}
FROM hs_office_relation debitorRel
JOIN hs_office_debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
WHERE debitor.uuid = ${REF}.debitorUuid
"""),
NOT_NULL)
.toRole("debitorRel", ADMIN).grantPermission(INSERT)
.toRole("global", ADMIN).grantPermission(DELETE)
.createRole(OWNER, (with) -> {
with.incomingSuperRole("debitorRel", AGENT).unassumed();
})
.createSubRole(ADMIN, (with) -> {
with.permission(UPDATE);
})
.createSubRole(AGENT)
.createSubRole(TENANT, (with) -> {
with.outgoingSubRole("debitorRel", TENANT);
with.permission(SELECT);
})
.limitDiagramTo("project", "debitorRel", "global");
}
public static void main(String[] args) throws IOException {
rbac().generateWithBaseFileName("6-hs-booking/620-booking-project/6203-hs-booking-project-rbac");
}
}

View File

@ -0,0 +1,21 @@
package net.hostsharing.hsadminng.hs.booking.project;
import org.springframework.data.repository.Repository;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
public interface HsBookingProjectRbacRepository extends Repository<HsBookingProjectRbacEntity, UUID> {
Optional<HsBookingProjectRbacEntity> findByUuid(final UUID bookingProjectUuid);
List<HsBookingProjectRbacEntity> findByCaption(final String projectCaption);
List<HsBookingProjectRbacEntity> findAllByDebitorUuid(final UUID bookingProjectUuid);
HsBookingProjectRbacEntity save(HsBookingProjectRbacEntity current);
int deleteByUuid(final UUID uuid);
long count();
}

View File

@ -0,0 +1,19 @@
package net.hostsharing.hsadminng.hs.booking.project;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
@Entity
@Table(name = "hs_booking_project")
@SuperBuilder(toBuilder = true)
@Getter
@Setter
@NoArgsConstructor
public class HsBookingProjectRealEntity extends HsBookingProject {
}

View File

@ -0,0 +1,21 @@
package net.hostsharing.hsadminng.hs.booking.project;
import org.springframework.data.repository.Repository;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
public interface HsBookingProjectRealRepository extends Repository<HsBookingProjectRealEntity, UUID> {
Optional<HsBookingProjectRealEntity> findByUuid(final UUID bookingProjectUuid);
List<HsBookingProjectRealEntity> findByCaption(final String projectCaption);
List<HsBookingProjectRealEntity> findAllByDebitorUuid(final UUID bookingProjectUuid);
HsBookingProjectRealEntity save(HsBookingProjectRealEntity current);
int deleteByUuid(final UUID uuid);
long count();
}

View File

@ -1,21 +0,0 @@
package net.hostsharing.hsadminng.hs.booking.project;
import org.springframework.data.repository.Repository;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
public interface HsBookingProjectRepository extends Repository<HsBookingProjectEntity, UUID> {
Optional<HsBookingProjectEntity> findByUuid(final UUID bookingProjectUuid);
List<HsBookingProjectEntity> findByCaption(final String projectCaption);
List<HsBookingProjectEntity> findAllByDebitorUuid(final UUID bookingProjectUuid);
HsBookingProjectEntity save(HsBookingProjectEntity current);
int deleteByUuid(final UUID uuid);
long count();
}

View File

@ -9,7 +9,7 @@ import lombok.Setter;
import lombok.Getter;
import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProject;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
import net.hostsharing.hsadminng.hs.validation.PropertiesProvider;
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
@ -127,7 +127,7 @@ public class HsHostingAsset implements Stringifyable, BaseEntity<HsHostingAsset>
return getConfig();
}
public HsBookingProjectEntity getRelatedProject() {
public HsBookingProject getRelatedProject() {
return Optional.ofNullable(getBookingItem())
.map(HsBookingItemEntity::getRelatedProject)
.orElseGet(() -> Optional.ofNullable(getParentAsset())

View File

@ -4,7 +4,7 @@ import io.hypersistence.utils.hibernate.type.range.Range;
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import net.hostsharing.hsadminng.HsadminNgApplication;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRepository;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealRepository;
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository;
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
@ -47,7 +47,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
HsBookingItemRepository bookingItemRepo;
@Autowired
HsBookingProjectRepository projectRepo;
HsBookingProjectRealRepository realProjectRepo;
@Autowired
HsOfficeDebitorRepository debitorRepo;
@ -65,7 +65,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
// given
context("superuser-alex@hostsharing.net");
final var givenProject = debitorRepo.findDebitorByDebitorNumber(1000111).stream()
.map(d -> projectRepo.findAllByDebitorUuid(d.getUuid()))
.map(d -> realProjectRepo.findAllByDebitorUuid(d.getUuid()))
.flatMap(List::stream)
.findFirst()
.orElseThrow();
@ -133,7 +133,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
context.define("superuser-alex@hostsharing.net");
final var givenProject = debitorRepo.findDebitorByDebitorNumber(1000111).stream()
.map(d -> projectRepo.findAllByDebitorUuid(d.getUuid()))
.map(d -> realProjectRepo.findAllByDebitorUuid(d.getUuid()))
.flatMap(List::stream)
.findFirst()
.orElseThrow();
@ -386,7 +386,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
final HsBookingItemType hsBookingItemType, final Map.Entry<String, Object>... resources) {
return jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net");
final var givenProject = projectRepo.findByCaption(projectCaption).stream()
final var givenProject = realProjectRepo.findByCaption(projectCaption).stream()
.findAny().orElseThrow();
final var newBookingItem = HsBookingItemEntity.builder()
.uuid(UUID.randomUUID())

View File

@ -1,8 +1,8 @@
package net.hostsharing.hsadminng.hs.booking.item;
import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRepository;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealRepository;
import net.hostsharing.hsadminng.mapper.Mapper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
@ -51,7 +51,7 @@ class HsBookingItemControllerRestTest {
EntityManagerFactory emf;
@MockBean
HsBookingProjectRepository bookingProjectRepo;
HsBookingProjectRealRepository realProjectRepo;
@MockBean
HsBookingItemRepository bookingItemRepo;
@ -73,8 +73,8 @@ class HsBookingItemControllerRestTest {
final var givenProjectUuid = UUID.randomUUID();
// given
when(em.find(HsBookingProjectEntity.class, givenProjectUuid)).thenAnswer(invocation ->
HsBookingProjectEntity.builder()
when(em.find(HsBookingProjectRealEntity.class, givenProjectUuid)).thenAnswer(invocation ->
HsBookingProjectRealEntity.builder()
.uuid(invocation.getArgument(1))
.build()
);
@ -123,8 +123,8 @@ class HsBookingItemControllerRestTest {
final var givenProjectUuid = UUID.randomUUID();
// given
when(em.find(HsBookingProjectEntity.class, givenProjectUuid)).thenAnswer(invocation ->
HsBookingProjectEntity.builder()
when(em.find(HsBookingProjectRealEntity.class, givenProjectUuid)).thenAnswer(invocation ->
HsBookingProjectRealEntity.builder()
.uuid(invocation.getArgument(1))
.build()
);

View File

@ -17,7 +17,7 @@ import java.util.Map;
import java.util.UUID;
import java.util.stream.Stream;
import static net.hostsharing.hsadminng.hs.booking.project.TestHsBookingProject.TEST_PROJECT;
import static net.hostsharing.hsadminng.hs.booking.project.TestHsBookingProject.PROJECT_TEST_ENTITY;
import static net.hostsharing.hsadminng.mapper.PatchMap.entry;
import static net.hostsharing.hsadminng.mapper.PatchMap.patchMap;
import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;
@ -70,7 +70,7 @@ class HsBookingItemEntityPatcherUnitTest extends PatchUnitTestBase<
protected HsBookingItemEntity newInitialEntity() {
final var entity = new HsBookingItemEntity();
entity.setUuid(INITIAL_BOOKING_ITEM_UUID);
entity.setProject(TEST_PROJECT);
entity.setProject(PROJECT_TEST_ENTITY);
entity.getResources().putAll(KeyValueMap.from(INITIAL_RESOURCES));
entity.setCaption(INITIAL_CAPTION);
entity.setValidity(Range.closedInfinite(GIVEN_VALID_FROM));

View File

@ -10,7 +10,7 @@ import java.time.Month;
import java.util.Map;
import static java.util.Map.entry;
import static net.hostsharing.hsadminng.hs.booking.project.TestHsBookingProject.TEST_PROJECT;
import static net.hostsharing.hsadminng.hs.booking.project.TestHsBookingProject.PROJECT_TEST_ENTITY;
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateRange;
import static org.assertj.core.api.Assertions.assertThat;
@ -21,7 +21,7 @@ class HsBookingItemEntityUnitTest {
private MockedStatic<LocalDate> localDateMockedStatic = Mockito.mockStatic(LocalDate.class, Mockito.CALLS_REAL_METHODS);
final HsBookingItemEntity givenBookingItem = HsBookingItemEntity.builder()
.project(TEST_PROJECT)
.project(PROJECT_TEST_ENTITY)
.type(HsBookingItemType.CLOUD_SERVER)
.caption("some caption")
.resources(Map.ofEntries(

View File

@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.hs.booking.item;
import io.hypersistence.utils.hibernate.type.range.Range;
import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRepository;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealRepository;
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository;
import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository;
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
@ -42,7 +42,7 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
HsBookingItemRepository bookingItemRepo;
@Autowired
HsBookingProjectRepository projectRepo;
HsBookingProjectRealRepository realProjectRepo;
@Autowired
HsOfficeDebitorRepository debitorRepo;
@ -71,7 +71,7 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
context("superuser-alex@hostsharing.net");
final var count = bookingItemRepo.count();
final var givenDebitor = debitorRepo.findDebitorByOptionalNameLike("First").get(0);
final var givenProject = projectRepo.findAllByDebitorUuid(givenDebitor.getUuid()).get(0);
final var givenProject = realProjectRepo.findAllByDebitorUuid(givenDebitor.getUuid()).get(0);
// when
final var result = attempt(em, () -> {
@ -102,7 +102,7 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
// when
attempt(em, () -> {
final var givenDebitor = debitorRepo.findDebitorByOptionalNameLike("First").get(0);
final var givenProject = projectRepo.findAllByDebitorUuid(givenDebitor.getUuid()).get(0);
final var givenProject = realProjectRepo.findAllByDebitorUuid(givenDebitor.getUuid()).get(0);
final var newBookingItem = HsBookingItemEntity.builder()
.project(givenProject)
.type(MANAGED_WEBSPACE)
@ -160,7 +160,7 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
// given
context("superuser-alex@hostsharing.net");
final var projectUuid = debitorRepo.findDebitorByDebitorNumber(1000212).stream()
.map(d -> projectRepo.findAllByDebitorUuid(d.getUuid()))
.map(d -> realProjectRepo.findAllByDebitorUuid(d.getUuid()))
.flatMap(List::stream)
.findAny().orElseThrow().getUuid();
@ -185,7 +185,7 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
final var debitor = debitorRepo.findDebitorByDebitorNumber(1000111);
context("person-FirbySusan@example.com", "hs_booking_project#D-1000111-D-1000111defaultproject:OWNER");
final var projectUuid = debitor.stream()
.map(d -> projectRepo.findAllByDebitorUuid(d.getUuid()))
.map(d -> realProjectRepo.findAllByDebitorUuid(d.getUuid()))
.flatMap(List::stream)
.findAny().orElseThrow().getUuid();
@ -329,7 +329,7 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
private HsBookingItemEntity givenSomeTemporaryBookingItem(final String projectCaption) {
return jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
final var givenProject = projectRepo.findByCaption(projectCaption).stream()
final var givenProject = realProjectRepo.findByCaption(projectCaption).stream()
.findAny().orElseThrow();
final var newBookingItem = HsBookingItemEntity.builder()
.project(givenProject)

View File

@ -7,13 +7,13 @@ import java.time.LocalDate;
import java.util.Map;
import static java.util.Map.entry;
import static net.hostsharing.hsadminng.hs.booking.project.TestHsBookingProject.TEST_PROJECT;
import static net.hostsharing.hsadminng.hs.booking.project.TestHsBookingProject.PROJECT_TEST_ENTITY;
@UtilityClass
public class TestHsBookingItem {
public static final HsBookingItemEntity TEST_CLOUD_SERVER_BOOKING_ITEM = HsBookingItemEntity.builder()
.project(TEST_PROJECT)
.project(PROJECT_TEST_ENTITY)
.type(HsBookingItemType.CLOUD_SERVER)
.caption("test cloud server booking item")
.resources(Map.ofEntries(
@ -26,7 +26,7 @@ public class TestHsBookingItem {
.build();
public static final HsBookingItemEntity TEST_MANAGED_SERVER_BOOKING_ITEM = HsBookingItemEntity.builder()
.project(TEST_PROJECT)
.project(PROJECT_TEST_ENTITY)
.type(HsBookingItemType.MANAGED_SERVER)
.caption("test project booking item")
.resources(Map.ofEntries(

View File

@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.hs.booking.item.validators;
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealEntity;
import org.junit.jupiter.api.Test;
import jakarta.validation.ValidationException;
@ -18,13 +18,13 @@ class HsBookingItemEntityValidatorUnitTest {
final HsBookingDebitorEntity debitor = HsBookingDebitorEntity.builder()
.debitorNumber(12345)
.build();
final HsBookingProjectEntity project = HsBookingProjectEntity.builder()
final HsBookingProjectRealEntity project = HsBookingProjectRealEntity.builder()
.debitor(debitor)
.caption("test project")
.build();
@Test
void validThrowsException() {
void rejectsInvalidEntity() {
// given
final var cloudServerBookingItemEntity = HsBookingItemEntity.builder()
.type(CLOUD_SERVER)

View File

@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.hs.booking.item.validators;
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealEntity;
import org.junit.jupiter.api.Test;
import java.util.Map;
@ -20,7 +20,7 @@ class HsCloudServerBookingItemValidatorUnitTest {
final HsBookingDebitorEntity debitor = HsBookingDebitorEntity.builder()
.debitorNumber(12345)
.build();
final HsBookingProjectEntity project = HsBookingProjectEntity.builder()
final HsBookingProjectRealEntity project = HsBookingProjectRealEntity.builder()
.debitor(debitor)
.caption("Test-Project")
.build();

View File

@ -2,8 +2,7 @@ package net.hostsharing.hsadminng.hs.booking.item.validators;
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
import org.junit.jupiter.api.Test;
@ -29,7 +28,7 @@ class HsManagedServerBookingItemValidatorUnitTest {
final HsBookingDebitorEntity debitor = HsBookingDebitorEntity.builder()
.debitorNumber(12345)
.build();
final HsBookingProjectEntity project = HsBookingProjectEntity.builder()
final HsBookingProjectRealEntity project = HsBookingProjectRealEntity.builder()
.debitor(debitor)
.caption("Test-Project")
.build();
@ -141,7 +140,7 @@ class HsManagedServerBookingItemValidatorUnitTest {
entry("Traffic", 1000),
entry("Multi", 1)
))
.relatedHostingAsset(HsHostingAssetRbacEntity.builder()
.relatedHostingAsset(HsHostingAssetRealEntity.builder()
.type(HsHostingAssetType.MANAGED_WEBSPACE)
.identifier("abc00")
.subHostingAssets(concat(

View File

@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.hs.booking.item.validators;
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealEntity;
import org.junit.jupiter.api.Test;
import java.util.Map;
@ -16,7 +16,7 @@ class HsManagedWebspaceBookingItemValidatorUnitTest {
final HsBookingDebitorEntity debitor = HsBookingDebitorEntity.builder()
.debitorNumber(12345)
.build();
final HsBookingProjectEntity project = HsBookingProjectEntity.builder()
final HsBookingProjectRealEntity project = HsBookingProjectRealEntity.builder()
.debitor(debitor)
.caption("Test-Project")
.build();

View File

@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.hs.booking.item.validators;
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealEntity;
import org.junit.jupiter.api.Test;
import static java.util.List.of;
@ -11,7 +11,7 @@ import static java.util.Map.ofEntries;
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.CLOUD_SERVER;
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_SERVER;
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.PRIVATE_CLOUD;
import static net.hostsharing.hsadminng.hs.booking.project.TestHsBookingProject.TEST_PROJECT;
import static net.hostsharing.hsadminng.hs.booking.project.TestHsBookingProject.PROJECT_TEST_ENTITY;
import static org.assertj.core.api.Assertions.assertThat;
class HsPrivateCloudBookingItemValidatorUnitTest {
@ -19,7 +19,7 @@ class HsPrivateCloudBookingItemValidatorUnitTest {
final HsBookingDebitorEntity debitor = HsBookingDebitorEntity.builder()
.debitorNumber(12345)
.build();
final HsBookingProjectEntity project = HsBookingProjectEntity.builder()
final HsBookingProjectRealEntity project = HsBookingProjectRealEntity.builder()
.debitor(debitor)
.caption("Test-Project")
.build();
@ -29,7 +29,7 @@ class HsPrivateCloudBookingItemValidatorUnitTest {
// given
final var privateCloudBookingItemEntity = HsBookingItemEntity.builder()
.type(PRIVATE_CLOUD)
.project(TEST_PROJECT)
.project(PROJECT_TEST_ENTITY)
.caption("myPC")
.resources(ofEntries(
entry("CPU", 4),

View File

@ -32,10 +32,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
private Integer port;
@Autowired
HsBookingProjectRepository bookingProjectRepo;
@Autowired
HsBookingProjectRepository projectRepo;
HsBookingProjectRealRepository realProjectRepo;
@Autowired
HsBookingDebitorRepository debitorRepo;
@ -126,7 +123,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
@Test
void globalAdmin_canGetArbitraryBookingProject() {
context.define("superuser-alex@hostsharing.net");
final var givenBookingProjectUuid = bookingProjectRepo.findByCaption("D-1000111 default project").stream()
final var givenBookingProjectUuid = realProjectRepo.findByCaption("D-1000111 default project").stream()
.findAny().orElseThrow().getUuid();
RestAssured // @formatter:off
@ -148,8 +145,8 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
@Test
void normalUser_canNotGetUnrelatedBookingProject() {
context.define("superuser-alex@hostsharing.net");
final var givenBookingProjectUuid = bookingProjectRepo.findByCaption("D-1000212 default project").stream()
.map(HsBookingProjectEntity::getUuid)
final var givenBookingProjectUuid = realProjectRepo.findByCaption("D-1000212 default project").stream()
.map(HsBookingProject::getUuid)
.findAny().orElseThrow();
RestAssured // @formatter:off
@ -165,7 +162,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
@Test
void projectAgentUser_canGetRelatedBookingProject() {
context.define("superuser-alex@hostsharing.net");
final var givenBookingProjectUuid = bookingProjectRepo.findByCaption("D-1000313 default project").stream()
final var givenBookingProjectUuid = realProjectRepo.findByCaption("D-1000313 default project").stream()
.findAny().orElseThrow().getUuid();
RestAssured // @formatter:off
@ -217,7 +214,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
// finally, the bookingProject is actually updated
context.define("superuser-alex@hostsharing.net");
assertThat(bookingProjectRepo.findByUuid(givenBookingProject.getUuid())).isPresent().get()
assertThat(realProjectRepo.findByUuid(givenBookingProject.getUuid())).isPresent().get()
.matches(mandate -> {
assertThat(mandate.getDebitor().toString()).isEqualTo("booking-debitor(D-1000111: fir)");
return true;
@ -243,7 +240,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
.statusCode(204); // @formatter:on
// then the given bookingProject is gone
assertThat(bookingProjectRepo.findByUuid(givenBookingProject.getUuid())).isEmpty();
assertThat(realProjectRepo.findByUuid(givenBookingProject.getUuid())).isEmpty();
}
@Test
@ -261,21 +258,21 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
.statusCode(404); // @formatter:on
// then the given bookingProject is still there
assertThat(bookingProjectRepo.findByUuid(givenBookingProject.getUuid())).isNotEmpty();
assertThat(realProjectRepo.findByUuid(givenBookingProject.getUuid())).isNotEmpty();
}
}
private HsBookingProjectEntity givenSomeBookingProject(final int debitorNumber, final String caption) {
private HsBookingProjectRealEntity givenSomeBookingProject(final int debitorNumber, final String caption) {
return jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net");
final var givenDebitor = debitorRepo.findByDebitorNumber(debitorNumber).stream().findAny().orElseThrow();
final var newBookingProject = HsBookingProjectEntity.builder()
final var newBookingProject = HsBookingProjectRealEntity.builder()
.uuid(UUID.randomUUID())
.debitor(givenDebitor)
.caption(caption)
.build();
return bookingProjectRepo.save(newBookingProject);
return realProjectRepo.save(newBookingProject);
}).assertSuccessful().returnedValue();
}
}

View File

@ -23,7 +23,7 @@ import static org.mockito.Mockito.lenient;
@ExtendWith(MockitoExtension.class)
class HsBookingProjectEntityPatcherUnitTest extends PatchUnitTestBase<
HsBookingProjectPatchResource,
HsBookingProjectEntity
HsBookingProject
> {
private static final UUID INITIAL_BOOKING_PROJECT_UUID = UUID.randomUUID();
@ -38,13 +38,14 @@ class HsBookingProjectEntityPatcherUnitTest extends PatchUnitTestBase<
void initMocks() {
lenient().when(em.getReference(eq(HsOfficeDebitorEntity.class), any())).thenAnswer(invocation ->
HsOfficeDebitorEntity.builder().uuid(invocation.getArgument(1)).build());
lenient().when(em.getReference(eq(HsBookingProjectEntity.class), any())).thenAnswer(invocation ->
HsBookingProjectEntity.builder().uuid(invocation.getArgument(1)).build());
// FIXME
// lenient().when(em.getReference(eq(HsBookingProject.class), any())).thenAnswer(invocation ->
// HsBookingProject.builder().uuid(invocation.getArgument(1)).build());
}
@Override
protected HsBookingProjectEntity newInitialEntity() {
final var entity = new HsBookingProjectEntity();
protected HsBookingProject newInitialEntity() {
final var entity = new HsBookingProject();
entity.setUuid(INITIAL_BOOKING_PROJECT_UUID);
entity.setDebitor(TEST_BOOKING_DEBITOR);
entity.setCaption(INITIAL_CAPTION);
@ -57,7 +58,7 @@ class HsBookingProjectEntityPatcherUnitTest extends PatchUnitTestBase<
}
@Override
protected HsBookingProjectEntityPatcher createPatcher(final HsBookingProjectEntity bookingProject) {
protected HsBookingProjectEntityPatcher createPatcher(final HsBookingProject bookingProject) {
return new HsBookingProjectEntityPatcher(bookingProject);
}
@ -68,7 +69,7 @@ class HsBookingProjectEntityPatcherUnitTest extends PatchUnitTestBase<
"caption",
HsBookingProjectPatchResource::setCaption,
PATCHED_CAPTION,
HsBookingProjectEntity::setCaption)
HsBookingProject::setCaption)
);
}
}

View File

@ -2,26 +2,22 @@ package net.hostsharing.hsadminng.hs.booking.project;
import org.junit.jupiter.api.Test;
import static net.hostsharing.hsadminng.hs.booking.debitor.TestHsBookingDebitor.TEST_BOOKING_DEBITOR;
import static net.hostsharing.hsadminng.hs.booking.project.TestHsBookingProject.PROJECT_TEST_ENTITY;
import static org.assertj.core.api.Assertions.assertThat;
class HsBookingProjectEntityUnitTest {
final HsBookingProjectEntity givenBookingProject = HsBookingProjectEntity.builder()
.debitor(TEST_BOOKING_DEBITOR)
.caption("some caption")
.build();
@Test
void toStringContainsAllPropertiesAndResourcesSortedByKey() {
final var result = givenBookingProject.toString();
final var result = PROJECT_TEST_ENTITY.toString();
assertThat(result).isEqualTo("HsBookingProjectEntity(D-1234500, some caption)");
assertThat(result).isEqualTo("HsBookingProject(D-1234500, test project)");
}
@Test
void toShortStringContainsOnlyMemberNumberAndCaption() {
final var result = givenBookingProject.toShortString();
final var result = PROJECT_TEST_ENTITY.toShortString();
assertThat(result).isEqualTo("D-1234500:some caption");
assertThat(result).isEqualTo("D-1234500:test project");
}
}

View File

@ -29,13 +29,13 @@ import static org.assertj.core.api.Assertions.assertThat;
@DataJpaTest
@Import({ Context.class, JpaAttempt.class })
class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithCleanup {
class HsBookingProjectRbacRepositoryIntegrationTest extends ContextBasedTestWithCleanup {
@Autowired
HsBookingProjectRepository bookingProjectRepo;
HsBookingProjectRealRepository realProjectRepo;
@Autowired
HsBookingProjectRepository projectRepo;
HsBookingProjectRbacRepository rbacProjectRepo;
@Autowired
HsBookingDebitorRepository debitorRepo;
@ -61,24 +61,24 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
@Test
public void testHostsharingAdmin_withoutAssumedRole_canCreateNewBookingProject() {
// given
context("superuser-alex@hostsharing.net");
final var count = bookingProjectRepo.count();
context("superuser-alex@hostsharing.net"); // TODO.test: remove once we have a realDebitorRepo
final var count = realProjectRepo.count();
final var givenDebitor = debitorRepo.findByDebitorNumber(1000111).get(0);
// when
final var result = attempt(em, () -> {
final var newBookingProject = HsBookingProjectEntity.builder()
final var newBookingProject = HsBookingProjectRbacEntity.builder()
.debitor(givenDebitor)
.caption("some new booking project")
.build();
return toCleanup(bookingProjectRepo.save(newBookingProject));
return toCleanup(rbacProjectRepo.save(newBookingProject));
});
// then
result.assertSuccessful();
assertThat(result.returnedValue()).isNotNull().extracting(HsBookingProjectEntity::getUuid).isNotNull();
assertThat(result.returnedValue()).isNotNull().extracting(HsBookingProject::getUuid).isNotNull();
assertThatBookingProjectIsPersisted(result.returnedValue());
assertThat(bookingProjectRepo.count()).isEqualTo(count + 1);
assertThat(realProjectRepo.count()).isEqualTo(count + 1);
}
@Test
@ -93,11 +93,11 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
// when
attempt(em, () -> {
final var givenDebitor = debitorRepo.findByDebitorNumber(1000111).get(0);
final var newBookingProject = HsBookingProjectEntity.builder()
final var newBookingProject = HsBookingProjectRbacEntity.builder()
.debitor(givenDebitor)
.caption("some new booking project")
.build();
return toCleanup(bookingProjectRepo.save(newBookingProject));
return toCleanup(rbacProjectRepo.save(newBookingProject));
});
// then
@ -135,9 +135,9 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
null));
}
private void assertThatBookingProjectIsPersisted(final HsBookingProjectEntity saved) {
final var found = bookingProjectRepo.findByUuid(saved.getUuid());
assertThat(found).isNotEmpty().map(HsBookingProjectEntity::toString).get().isEqualTo(saved.toString());
private void assertThatBookingProjectIsPersisted(final HsBookingProject saved) {
final var found = rbacProjectRepo.findByUuid(saved.getUuid());
assertThat(found).isNotEmpty().map(HsBookingProject::toString).get().isEqualTo(saved.toString());
}
}
@ -152,12 +152,12 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
.findAny().orElseThrow().getUuid();
// when
final var result = bookingProjectRepo.findAllByDebitorUuid(debitorUuid);
final var result = rbacProjectRepo.findAllByDebitorUuid(debitorUuid);
// then
allTheseBookingProjectsAreReturned(
result,
"HsBookingProjectEntity(D-1000212, D-1000212 default project)");
"HsBookingProject(D-1000212, D-1000212 default project)");
}
@Test
@ -169,12 +169,12 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
.findAny().orElseThrow().getUuid();
// when:
final var result = bookingProjectRepo.findAllByDebitorUuid(debitorUuid);
final var result = rbacProjectRepo.findAllByDebitorUuid(debitorUuid);
// then:
exactlyTheseBookingProjectsAreReturned(
result,
"HsBookingProjectEntity(D-1000111, D-1000111 default project)");
"HsBookingProject(D-1000111, D-1000111 default project)");
}
}
@ -182,29 +182,30 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
class UpdateBookingProject {
@Test
public void hostsharingAdmin_canUpdateArbitraryBookingProject() {
public void bookingProjectAdmin_canUpdateArbitraryBookingProject() {
// given
final var givenBookingProjectUuid = givenSomeTemporaryBookingProject(1000111).getUuid();
// when
final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
final var foundBookingProject = em.find(HsBookingProjectEntity.class, givenBookingProjectUuid);
return toCleanup(bookingProjectRepo.save(foundBookingProject));
context("superuser-alex@hostsharing.net", "hs_booking_project#D-1000111-sometempproject:ADMIN");
final var foundBookingProject = em.find(HsBookingProjectRbacEntity.class, givenBookingProjectUuid);
foundBookingProject.setCaption("updated caption");
return toCleanup(rbacProjectRepo.save(foundBookingProject));
});
// then
result.assertSuccessful();
jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
assertThatBookingProjectActuallyInDatabase(result.returnedValue());
}).assertSuccessful();
assertThat(result.returnedValue().getCaption()).isEqualTo("updated caption");
assertThatBookingProjectActuallyInDatabase(result.returnedValue());
}
private void assertThatBookingProjectActuallyInDatabase(final HsBookingProjectEntity saved) {
final var found = bookingProjectRepo.findByUuid(saved.getUuid());
assertThat(found).isNotEmpty().get().isNotSameAs(saved)
.extracting(Object::toString).isEqualTo(saved.toString());
private void assertThatBookingProjectActuallyInDatabase(final HsBookingProject saved) {
jpaAttempt.transacted(() -> {
final var found = realProjectRepo.findByUuid(saved.getUuid());
assertThat(found).isNotEmpty().get().isNotSameAs(saved)
.extracting(Object::toString).isEqualTo(saved.toString());
}).assertSuccessful();
}
}
@ -220,14 +221,14 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
// when
final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
bookingProjectRepo.deleteByUuid(givenBookingProject.getUuid());
rbacProjectRepo.deleteByUuid(givenBookingProject.getUuid());
});
// then
result.assertSuccessful();
assertThat(jpaAttempt.transacted(() -> {
context("superuser-fran@hostsharing.net", null);
return bookingProjectRepo.findByUuid(givenBookingProject.getUuid());
return rbacProjectRepo.findByUuid(givenBookingProject.getUuid());
}).assertSuccessful().returnedValue()).isEmpty();
}
@ -239,9 +240,9 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
// when
final var result = jpaAttempt.transacted(() -> {
context("person-FirbySusan@example.com", "hs_booking_project#D-1000111-sometempproject:AGENT");
assertThat(bookingProjectRepo.findByUuid(givenBookingProject.getUuid())).isPresent();
assertThat(rbacProjectRepo.findByUuid(givenBookingProject.getUuid())).isPresent();
bookingProjectRepo.deleteByUuid(givenBookingProject.getUuid());
rbacProjectRepo.deleteByUuid(givenBookingProject.getUuid());
});
// then
@ -250,7 +251,7 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
"[403] Subject ", " is not allowed to delete hs_booking_project");
assertThat(jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
return bookingProjectRepo.findByUuid(givenBookingProject.getUuid());
return rbacProjectRepo.findByUuid(givenBookingProject.getUuid());
}).assertSuccessful().returnedValue()).isPresent(); // still there
}
@ -265,7 +266,7 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
// when
final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
return bookingProjectRepo.deleteByUuid(givenBookingProject.getUuid());
return rbacProjectRepo.deleteByUuid(givenBookingProject.getUuid());
});
// then
@ -295,32 +296,32 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
"[creating booking-project test-data 1000313, hs_booking_project, INSERT]");
}
private HsBookingProjectEntity givenSomeTemporaryBookingProject(final int debitorNumber) {
private HsBookingProjectRealEntity givenSomeTemporaryBookingProject(final int debitorNumber) {
return jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
final var givenDebitor = debitorRepo.findByDebitorNumber(debitorNumber).get(0);
final var newBookingProject = HsBookingProjectEntity.builder()
final var newBookingProject = HsBookingProjectRealEntity.builder()
.debitor(givenDebitor)
.caption("some temp project")
.build();
return toCleanup(bookingProjectRepo.save(newBookingProject));
return toCleanup(realProjectRepo.save(newBookingProject));
}).assertSuccessful().returnedValue();
}
void exactlyTheseBookingProjectsAreReturned(
final List<HsBookingProjectEntity> actualResult,
final List<HsBookingProjectRbacEntity> actualResult,
final String... bookingProjectNames) {
assertThat(actualResult)
.extracting(HsBookingProjectEntity::toString)
.extracting(HsBookingProject::toString)
.containsExactlyInAnyOrder(bookingProjectNames);
}
void allTheseBookingProjectsAreReturned(
final List<HsBookingProjectEntity> actualResult,
final List<HsBookingProjectRbacEntity> actualResult,
final String... bookingProjectNames) {
assertThat(actualResult)
.extracting(HsBookingProjectEntity::toString)
.extracting(HsBookingProject::toString)
.contains(bookingProjectNames);
}
}

View File

@ -7,8 +7,7 @@ import static net.hostsharing.hsadminng.hs.booking.debitor.TestHsBookingDebitor.
@UtilityClass
public class TestHsBookingProject {
public static final HsBookingProjectEntity TEST_PROJECT = HsBookingProjectEntity.builder()
public static final HsBookingProjectRealEntity PROJECT_TEST_ENTITY = HsBookingProjectRealEntity.builder()
.debitor(TEST_BOOKING_DEBITOR)
.caption("test project")
.build();

View File

@ -7,7 +7,7 @@ import net.hostsharing.hsadminng.hash.HashGenerator;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRepository;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRepository;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealRepository;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository;
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository;
@ -59,7 +59,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
HsBookingItemRepository bookingItemRepo;
@Autowired
HsBookingProjectRepository projectRepo;
HsBookingProjectRealRepository realProjectRepo;
@Autowired
HsOfficeDebitorRepository debitorRepo;
@ -79,7 +79,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
// given
context("superuser-alex@hostsharing.net");
final var givenProject = projectRepo.findByCaption("D-1000111 default project").stream()
final var givenProject = realProjectRepo.findByCaption("D-1000111 default project").stream()
.findAny().orElseThrow();
RestAssured // @formatter:off
@ -685,7 +685,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
final HsBookingItemType type, final String bookingItemCaption, final Map<String, Object> resources) {
return jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net");
final var project = projectRepo.findByCaption(projectCaption).stream()
final var project = realProjectRepo.findByCaption(projectCaption).stream()
.findAny().orElseThrow();
final var bookingItem = HsBookingItemEntity.builder()
.project(project)
@ -703,7 +703,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
final String bookingItemCaption) {
return jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net");
final var project = projectRepo.findByCaption(projectCaption).getFirst();
final var project = realProjectRepo.findByCaption(projectCaption).getFirst();
final var resources = switch (bookingItemType) {
case MANAGED_SERVER -> Map.<String, Object>ofEntries(entry("CPU", 1),
entry("RAM", 20),

View File

@ -4,7 +4,7 @@ import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRepository;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRepository;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRbacRepository;
import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository;
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
import net.hostsharing.hsadminng.mapper.Array;
@ -51,7 +51,7 @@ class HsHostingAssetRbacRepositoryIntegrationTest extends ContextBasedTestWithCl
HsBookingItemRepository bookingItemRepo;
@Autowired
HsBookingProjectRepository projectRepo;
HsBookingProjectRbacRepository projectRepo;
@Autowired
RawRbacRoleRepository rawRoleRepo;

View File

@ -14,12 +14,12 @@ import static java.util.Map.entry;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.CLOUD_SERVER;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_WEBSPACE;
import static org.assertj.core.api.Assertions.assertThat;
import static net.hostsharing.hsadminng.hs.booking.project.TestHsBookingProject.TEST_PROJECT;
import static net.hostsharing.hsadminng.hs.booking.project.TestHsBookingProject.PROJECT_TEST_ENTITY;
class HsManagedWebspaceHostingAssetValidatorUnitTest {
final HsBookingItemEntity managedServerBookingItem = HsBookingItemEntity.builder()
.project(TEST_PROJECT)
.project(PROJECT_TEST_ENTITY)
.type(HsBookingItemType.MANAGED_SERVER)
.caption("Test Managed-Server")
.resources(Map.ofEntries(
@ -126,7 +126,7 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
.type(MANAGED_WEBSPACE)
.bookingItem(HsBookingItemEntity.builder()
.type(HsBookingItemType.MANAGED_WEBSPACE)
.project(TEST_PROJECT)
.project(PROJECT_TEST_ENTITY)
.caption("some ManagedWebspace")
.resources(Map.ofEntries(entry("SSD", 25), entry("Traffic", 250)))
.build())

View File

@ -9,7 +9,7 @@ import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
import net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidatorRegistry;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
import net.hostsharing.hsadminng.hs.hosting.asset.validators.HostingAssetEntitySaveProcessor;
@ -131,7 +131,7 @@ public class ImportHostingAssets extends ImportOfficeData {
record Hive(int hive_id, String hive_name, int inet_addr_id, AtomicReference<HsHostingAssetRealEntity> serverRef) {}
static Map<Integer, HsBookingProjectEntity> bookingProjects = new WriteOnceMap<>();
static Map<Integer, HsBookingProjectRealEntity> bookingProjects = new WriteOnceMap<>();
static Map<Integer, HsBookingItemEntity> bookingItems = new WriteOnceMap<>();
static Map<Integer, Hive> hives = new WriteOnceMap<>();
@ -158,7 +158,7 @@ public class ImportHostingAssets extends ImportOfficeData {
@Order(11010)
void createBookingProjects() {
debitors.forEach((id, debitor) -> {
bookingProjects.put(id, HsBookingProjectEntity.builder()
bookingProjects.put(id, HsBookingProjectRealEntity.builder()
.caption(debitor.getDefaultPrefix() + " default project")
.debitor(em.find(HsBookingDebitorEntity.class, debitor.getUuid()))
.build());
@ -1118,7 +1118,7 @@ public class ImportHostingAssets extends ImportOfficeData {
&& managedWebspace.getRelatedProject().getDebitor().getDebitorNumber() == 10000_00 ) {
assertThat(managedWebspace.getIdentifier()).startsWith("xyz");
final var hshDebitor = managedWebspace.getBookingItem().getProject().getDebitor();
final var newProject = HsBookingProjectEntity.builder()
final var newProject = HsBookingProjectRealEntity.builder()
.debitor(hshDebitor)
.caption(parentAsset.getIdentifier() + " Monitor")
.build();

View File

@ -20,6 +20,7 @@ import jakarta.persistence.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
import java.util.regex.Pattern;
import static java.lang.System.out;
import static java.util.Comparator.comparing;
@ -290,6 +291,20 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
}).assertSuccessful().returnedValue();
}
/**
* @return an array of all RBAC roles matching the given pattern
*/
protected String[] roleNames(final String sqlLikeExpression) {
final var pattern = Pattern.compile(sqlLikeExpression);
//noinspection unchecked
final List<Object[]> rows = (List<Object[]>) em.createNativeQuery("select * from rbacrole_ev where roleidname like 'hs_booking_project#%'")
.getResultList();
return rows.stream()
.map(row -> (row[0]).toString())
.filter(roleName -> pattern.matcher(roleName).matches())
.toArray(String[]::new);
}
/**
* Generates a diagram of the RBAC-Grants to the current subjects (user or assumed roles).
*/

View File

@ -77,11 +77,11 @@ public class JpaAttempt {
public static class JpaResult<T> {
private final T result;
private final T value;
private final RuntimeException exception;
private JpaResult(final T result, final RuntimeException exception) {
this.result = result;
private JpaResult(final T value, final RuntimeException exception) {
this.value = value;
this.exception = exception;
}
@ -102,7 +102,7 @@ public class JpaAttempt {
}
public T returnedValue() {
return result;
return value;
}
public ObjectAssert<T> assertThatResult() {