introduce-booking-module #41
@ -1,11 +1,11 @@
|
|||||||
package net.hostsharing.hsadminng.hs.booking.item;
|
package net.hostsharing.hsadminng.hs.booking.item;
|
||||||
|
|
||||||
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.api.HsBookingItemsApi;
|
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.api.HsBookingItemsApi;
|
||||||
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingItemInsertResource;
|
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingItemInsertResource;
|
||||||
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingItemPatchResource;
|
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingItemPatchResource;
|
||||||
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingItemResource;
|
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingItemResource;
|
||||||
import net.hostsharing.hsadminng.mapper.Mapper;
|
import net.hostsharing.hsadminng.mapper.Mapper;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@ -76,10 +76,10 @@ public class HsBookingItemController implements HsBookingItemsApi {
|
|||||||
context.define(currentUser, assumedRoles);
|
context.define(currentUser, assumedRoles);
|
||||||
|
|
||||||
final var result = bookingItemRepo.findByUuid(bookingItemUuid);
|
final var result = bookingItemRepo.findByUuid(bookingItemUuid);
|
||||||
if (result.isEmpty()) {
|
return result
|
||||||
return ResponseEntity.notFound().build();
|
.map(bookingItemEntity -> ResponseEntity.ok(
|
||||||
}
|
mapper.map(bookingItemEntity, HsBookingItemResource.class, ENTITY_TO_RESOURCE_POSTMAPPER)))
|
||||||
return ResponseEntity.ok(mapper.map(result.get(), HsBookingItemResource.class, ENTITY_TO_RESOURCE_POSTMAPPER));
|
.orElseGet(() -> ResponseEntity.notFound().build());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -91,11 +91,9 @@ public class HsBookingItemController implements HsBookingItemsApi {
|
|||||||
context.define(currentUser, assumedRoles);
|
context.define(currentUser, assumedRoles);
|
||||||
|
|
||||||
final var result = bookingItemRepo.deleteByUuid(bookingItemUuid);
|
final var result = bookingItemRepo.deleteByUuid(bookingItemUuid);
|
||||||
if (result == 0) {
|
return result == 0
|
||||||
return ResponseEntity.notFound().build();
|
? ResponseEntity.notFound().build()
|
||||||
}
|
: ResponseEntity.noContent().build();
|
||||||
|
|
||||||
return ResponseEntity.noContent().build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -122,7 +120,6 @@ public class HsBookingItemController implements HsBookingItemsApi {
|
|||||||
if (entity.getValidity().hasUpperBound()) {
|
if (entity.getValidity().hasUpperBound()) {
|
||||||
resource.setValidTo(entity.getValidity().upper().minusDays(1));
|
resource.setValidTo(entity.getValidity().upper().minusDays(1));
|
||||||
}
|
}
|
||||||
resource.getDebitor().setDebitorNumber(entity.getDebitor().getDebitorNumber());
|
|
||||||
};
|
};
|
||||||
|
|
||||||
final BiConsumer<HsBookingItemInsertResource, HsBookingItemEntity> RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
|
final BiConsumer<HsBookingItemInsertResource, HsBookingItemEntity> RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
|
||||||
|
@ -118,6 +118,7 @@ public class HsBookingItemEntity implements Stringifyable, RbacObject {
|
|||||||
public static RbacView rbac() {
|
public static RbacView rbac() {
|
||||||
return rbacViewFor("bookingItem", HsBookingItemEntity.class)
|
return rbacViewFor("bookingItem", HsBookingItemEntity.class)
|
||||||
.withIdentityView(SQL.projection("caption")) // FIXME: use memberNumber:caption
|
.withIdentityView(SQL.projection("caption")) // FIXME: use memberNumber:caption
|
||||||
|
.withRestrictedViewOrderBy(SQL.expression("validity"))
|
||||||
.withUpdatableColumns("version", "validity", "resources")
|
.withUpdatableColumns("version", "validity", "resources")
|
||||||
|
|
||||||
.importEntityAlias("debitor", HsOfficeDebitorEntity.class,
|
.importEntityAlias("debitor", HsOfficeDebitorEntity.class,
|
||||||
|
@ -74,11 +74,11 @@ public class HsOfficeBankAccountController implements HsOfficeBankAccountsApi {
|
|||||||
public ResponseEntity<HsOfficeBankAccountResource> getBankAccountByUuid(
|
public ResponseEntity<HsOfficeBankAccountResource> getBankAccountByUuid(
|
||||||
final String currentUser,
|
final String currentUser,
|
||||||
final String assumedRoles,
|
final String assumedRoles,
|
||||||
final UUID BankAccountUuid) {
|
final UUID bankAccountUuid) {
|
||||||
|
|
||||||
context.define(currentUser, assumedRoles);
|
context.define(currentUser, assumedRoles);
|
||||||
|
|
||||||
final var result = bankAccountRepo.findByUuid(BankAccountUuid);
|
final var result = bankAccountRepo.findByUuid(bankAccountUuid);
|
||||||
if (result.isEmpty()) {
|
if (result.isEmpty()) {
|
||||||
return ResponseEntity.notFound().build();
|
return ResponseEntity.notFound().build();
|
||||||
}
|
}
|
||||||
|
@ -14,5 +14,5 @@ map:
|
|||||||
- type: string:format => java.lang.String
|
- type: string:format => java.lang.String
|
||||||
|
|
||||||
paths:
|
paths:
|
||||||
/api/hs/booking/items/{itemUUID}:
|
/api/hs/booking/items/{bookingItemUuid}:
|
||||||
null: org.openapitools.jackson.nullable.JsonNullable
|
null: org.openapitools.jackson.nullable.JsonNullable
|
||||||
|
@ -9,8 +9,6 @@ components:
|
|||||||
uuid:
|
uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
debitor:
|
|
||||||
$ref: '../hs-office/hs-office-debitor-schemas.yaml#/components/schemas/HsOfficeDebitor'
|
|
||||||
caption:
|
caption:
|
||||||
type: string
|
type: string
|
||||||
validFrom:
|
validFrom:
|
||||||
@ -44,7 +42,6 @@ components:
|
|||||||
nullable: true
|
nullable: true
|
||||||
resources:
|
resources:
|
||||||
$ref: '#/components/schemas/ArbitraryBookingResourcesJson'
|
$ref: '#/components/schemas/ArbitraryBookingResourcesJson'
|
||||||
additionalProperties: false
|
|
||||||
|
|
||||||
HsBookingItemInsert:
|
HsBookingItemInsert:
|
||||||
type: object
|
type: object
|
||||||
|
@ -6,7 +6,7 @@ get:
|
|||||||
parameters:
|
parameters:
|
||||||
- $ref: './auth.yaml#/components/parameters/currentUser'
|
- $ref: './auth.yaml#/components/parameters/currentUser'
|
||||||
- $ref: './auth.yaml#/components/parameters/assumedRoles'
|
- $ref: './auth.yaml#/components/parameters/assumedRoles'
|
||||||
- name: bookingItemUUID
|
- name: bookingItemUuid
|
||||||
in: path
|
in: path
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
@ -34,7 +34,7 @@ patch:
|
|||||||
parameters:
|
parameters:
|
||||||
- $ref: './auth.yaml#/components/parameters/currentUser'
|
- $ref: './auth.yaml#/components/parameters/currentUser'
|
||||||
- $ref: './auth.yaml#/components/parameters/assumedRoles'
|
- $ref: './auth.yaml#/components/parameters/assumedRoles'
|
||||||
- name: bookingItemUUID
|
- name: bookingItemUuid
|
||||||
in: path
|
in: path
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
@ -65,7 +65,7 @@ delete:
|
|||||||
parameters:
|
parameters:
|
||||||
- $ref: './auth.yaml#/components/parameters/currentUser'
|
- $ref: './auth.yaml#/components/parameters/currentUser'
|
||||||
- $ref: './auth.yaml#/components/parameters/assumedRoles'
|
- $ref: './auth.yaml#/components/parameters/assumedRoles'
|
||||||
- name: bookingItemUUID
|
- name: bookingItemUuid
|
||||||
in: path
|
in: path
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
get:
|
get:
|
||||||
summary: Returns a list of (optionally filtered) booking items.
|
summary: Returns a list of all booking items for a specified debitor.
|
||||||
description: Returns the list of (optionally filtered) booking items which are visible to the current user or any of it's assumed roles.
|
description: Returns the list of all booking items for a specified debitor which are visible to the current user or any of it's assumed roles.
|
||||||
tags:
|
tags:
|
||||||
- hs-booking-items
|
- hs-booking-items
|
||||||
operationId: listBookingItemsByDebitorUuid
|
operationId: listBookingItemsByDebitorUuid
|
||||||
@ -9,7 +9,7 @@ get:
|
|||||||
- $ref: './auth.yaml#/components/parameters/assumedRoles'
|
- $ref: './auth.yaml#/components/parameters/assumedRoles'
|
||||||
- name: debitorUuid
|
- name: debitorUuid
|
||||||
in: query
|
in: query
|
||||||
required: false
|
required: true
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
|
@ -13,5 +13,5 @@ paths:
|
|||||||
/api/hs/booking/items:
|
/api/hs/booking/items:
|
||||||
$ref: "./hs-booking-items.yaml"
|
$ref: "./hs-booking-items.yaml"
|
||||||
|
|
||||||
/api/hs/booking/items/{itemUUID}:
|
/api/hs/booking/items/{bookingItemUuid}:
|
||||||
$ref: "./hs-booking-items-with-uuid.yaml"
|
$ref: "./hs-booking-items-with-uuid.yaml"
|
||||||
|
@ -10,8 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
create or replace procedure createHsBookingItemTransactionTestData(
|
create or replace procedure createHsBookingItemTransactionTestData(
|
||||||
givenPartnerNumber numeric,
|
givenPartnerNumber numeric,
|
||||||
givenDebitorSuffix char(2),
|
givenDebitorSuffix char(2)
|
||||||
givenCaption varchar
|
|
||||||
)
|
)
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
declare
|
declare
|
||||||
@ -33,7 +32,9 @@ begin
|
|||||||
raise notice '- using debitor (%): %', relatedDebitor.uuid, relatedDebitor;
|
raise notice '- using debitor (%): %', relatedDebitor.uuid, relatedDebitor;
|
||||||
insert
|
insert
|
||||||
into hs_booking_item (uuid, debitoruuid, caption, validity, resources)
|
into hs_booking_item (uuid, debitoruuid, caption, validity, resources)
|
||||||
values (uuid_generate_v4(), relatedDebitor.uuid, givenCaption, daterange('20221001' , null, '[]'), '{ "CPUs": 2, "HDD-storage": 512 }'::jsonb);
|
values (uuid_generate_v4(), relatedDebitor.uuid, 'some ManagedServer', daterange('20221001', null, '[]'), '{ "CPUs": 2, "SDD-storage": 512 }'::jsonb),
|
||||||
|
(uuid_generate_v4(), relatedDebitor.uuid, 'some CloudServer', daterange('20230115', '20240415', '[)'), '{ "CPUs": 2, "HDD-storage": 1024 }'::jsonb),
|
||||||
|
(uuid_generate_v4(), relatedDebitor.uuid, 'some Whatever', daterange('20240401', null, '[]'), '{ "CPUs": 1, "SDD-storage": 512, "HDD-storage": 2048 }'::jsonb);
|
||||||
end; $$;
|
end; $$;
|
||||||
--//
|
--//
|
||||||
|
|
||||||
@ -44,8 +45,8 @@ end; $$;
|
|||||||
|
|
||||||
do language plpgsql $$
|
do language plpgsql $$
|
||||||
begin
|
begin
|
||||||
call createHsBookingItemTransactionTestData(10001, '11', 'some booking 1');
|
call createHsBookingItemTransactionTestData(10001, '11');
|
||||||
call createHsBookingItemTransactionTestData(10002, '12', 'some booking 2');
|
call createHsBookingItemTransactionTestData(10002, '12');
|
||||||
call createHsBookingItemTransactionTestData(10003, '13', 'some booking 3');
|
call createHsBookingItemTransactionTestData(10003, '13');
|
||||||
end;
|
end;
|
||||||
$$;
|
$$;
|
||||||
|
@ -50,6 +50,7 @@ public class ArchitectureTest {
|
|||||||
"..hs.office.person",
|
"..hs.office.person",
|
||||||
"..hs.office.relation",
|
"..hs.office.relation",
|
||||||
"..hs.office.sepamandate",
|
"..hs.office.sepamandate",
|
||||||
|
"..hs.booking.item",
|
||||||
"..errors",
|
"..errors",
|
||||||
"..mapper",
|
"..mapper",
|
||||||
"..ping",
|
"..ping",
|
||||||
@ -123,11 +124,22 @@ public class ArchitectureTest {
|
|||||||
|
|
||||||
@ArchTest
|
@ArchTest
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public static final ArchRule hsAdminPackagesRule = classes()
|
public static final ArchRule hsOfficePackageAccessRule = classes()
|
||||||
.that().resideInAPackage("..hs.office.(*)..")
|
.that().resideInAPackage("..hs.office.(*)..")
|
||||||
.should().onlyBeAccessed().byClassesThat()
|
.should().onlyBeAccessed().byClassesThat()
|
||||||
.resideInAnyPackage(
|
.resideInAnyPackage(
|
||||||
"..hs.office.(*)..",
|
"..hs.office.(*)..",
|
||||||
|
"..hs.booking.(*)..",
|
||||||
|
"..rbac.rbacgrant" // TODO.test: just because of RbacGrantsDiagramServiceIntegrationTest
|
||||||
|
);
|
||||||
|
|
||||||
|
@ArchTest
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public static final ArchRule hsBookingPackageAccessRule = classes()
|
||||||
|
.that().resideInAPackage("..hs.booking.(*)..")
|
||||||
|
.should().onlyBeAccessed().byClassesThat()
|
||||||
|
.resideInAnyPackage(
|
||||||
|
"..hs.booking.(*)..",
|
||||||
"..rbac.rbacgrant" // TODO.test: just because of RbacGrantsDiagramServiceIntegrationTest
|
"..rbac.rbacgrant" // TODO.test: just because of RbacGrantsDiagramServiceIntegrationTest
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -19,8 +19,10 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
import jakarta.persistence.PersistenceContext;
|
import jakarta.persistence.PersistenceContext;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static java.util.Map.entry;
|
||||||
import static net.hostsharing.test.JsonMatcher.lenientlyEquals;
|
import static net.hostsharing.test.JsonMatcher.lenientlyEquals;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.hamcrest.Matchers.startsWith;
|
import static org.hamcrest.Matchers.startsWith;
|
||||||
@ -62,7 +64,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
.header("current-user", "superuser-alex@hostsharing.net")
|
.header("current-user", "superuser-alex@hostsharing.net")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/booking/items?debitorUuid" + givenDebitor.getUuid())
|
.get("http://localhost/api/hs/booking/items?debitorUuid=" + givenDebitor.getUuid())
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType("application/json")
|
.contentType("application/json")
|
||||||
@ -70,19 +72,22 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"debitor": { "debitorNumber": 1000111 },
|
"caption": "some ManagedServer",
|
||||||
"validFrom": "2022-10-01",
|
"validFrom": "2022-10-01",
|
||||||
"validTo": "2026-12-31"
|
"validTo": null,
|
||||||
|
"resources": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"debitor": { "debitorNumber": 1000212 },
|
"caption": "some CloudServer",
|
||||||
"validFrom": "2022-10-01",
|
"validFrom": "2023-01-15",
|
||||||
"validTo": "2026-12-31"
|
"validTo": "2024-04-14",
|
||||||
|
"resources": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"debitor": { "debitorNumber": 1000313 },
|
"caption": "some Whatever",
|
||||||
"validFrom": "2022-10-01",
|
"validFrom": "2024-04-01",
|
||||||
"validTo": "2026-12-31"
|
"validTo": null,
|
||||||
|
"resources": null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
"""));
|
"""));
|
||||||
@ -97,7 +102,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
void globalAdmin_canAddBookingItem() {
|
void globalAdmin_canAddBookingItem() {
|
||||||
|
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenDebitor = debitorRepo.findDebitorByOptionalNameLike("Third").get(0);
|
final var givenDebitor = debitorRepo.findDebitorByDebitorNumber(1000111).get(0);
|
||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
@ -106,20 +111,25 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"debitorUuid": "%s",
|
"debitorUuid": "%s",
|
||||||
|
"caption": "some new booking",
|
||||||
|
"resources": {
|
||||||
|
"something": 12
|
||||||
|
},
|
||||||
"validFrom": "2022-10-13"
|
"validFrom": "2022-10-13"
|
||||||
}
|
}
|
||||||
""".formatted(givenDebitor.getUuid()))
|
""".formatted(givenDebitor.getUuid()))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.post("http://localhost/api/hs/office/BookingItems")
|
.post("http://localhost/api/hs/booking/items")
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(201)
|
.statusCode(201)
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
{
|
{
|
||||||
"debitor": { "debitorNumber": 1000111 },
|
"caption": "some new booking",
|
||||||
"validFrom": "2022-10-01",
|
"validFrom": "2022-10-13",
|
||||||
"validTo": "2026-12-31"
|
"validTo": null,
|
||||||
|
"resources": null
|
||||||
}
|
}
|
||||||
"""))
|
"""))
|
||||||
.header("Location", startsWith("http://localhost"))
|
.header("Location", startsWith("http://localhost"))
|
||||||
@ -139,7 +149,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
void globalAdmin_canGetArbitraryBookingItem() {
|
void globalAdmin_canGetArbitraryBookingItem() {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenBookingItemUuid = bookingItemRepo.findAll().stream()
|
final var givenBookingItemUuid = bookingItemRepo.findAll().stream()
|
||||||
.filter(bi -> bi.getDebitor().getDebitorNumber() == 1000101)
|
.filter(bi -> bi.getDebitor().getDebitorNumber() == 1000111)
|
||||||
.findAny().orElseThrow().getUuid();
|
.findAny().orElseThrow().getUuid();
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
@ -148,14 +158,15 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/booking/items/" + givenBookingItemUuid)
|
.get("http://localhost/api/hs/booking/items/" + givenBookingItemUuid)
|
||||||
.then().log().body().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType("application/json")
|
.contentType("application/json")
|
||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
{
|
{
|
||||||
"debitor": { "debitorNumber": 1000111 },
|
"caption": "some CloudServer",
|
||||||
"validFrom": "2022-10-01",
|
"validFrom": "2023-01-15",
|
||||||
"validTo": "2026-12-31"
|
"validTo": "2024-04-14",
|
||||||
|
"resources": null
|
||||||
}
|
}
|
||||||
""")); // @formatter:on
|
""")); // @formatter:on
|
||||||
}
|
}
|
||||||
@ -164,8 +175,9 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
void normalUser_canNotGetUnrelatedBookingItem() {
|
void normalUser_canNotGetUnrelatedBookingItem() {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenBookingItemUuid = bookingItemRepo.findAll().stream()
|
final var givenBookingItemUuid = bookingItemRepo.findAll().stream()
|
||||||
.filter(bi -> bi.getDebitor().getDebitorNumber() == 1000101)
|
.filter(bi -> bi.getDebitor().getDebitorNumber() == 1000212)
|
||||||
.findAny().orElseThrow().getUuid();
|
.map(HsBookingItemEntity::getUuid)
|
||||||
|
.findAny().orElseThrow();
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
@ -181,23 +193,25 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
void debitorAgentUser_canGetRelatedBookingItem() {
|
void debitorAgentUser_canGetRelatedBookingItem() {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenBookingItemUuid = bookingItemRepo.findAll().stream()
|
final var givenBookingItemUuid = bookingItemRepo.findAll().stream()
|
||||||
.filter(bi -> bi.getDebitor().getDebitorNumber() == 1000101)
|
.filter(bi -> bi.getDebitor().getDebitorNumber() == 1000313)
|
||||||
.findAny().orElseThrow().getUuid();
|
.findAny().orElseThrow().getUuid();
|
||||||
|
generateRbacDiagramForObjectPermission(givenBookingItemUuid, "SELECT", "booking-item-of-debitor-1000313");
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("current-user", "person-FirbySusan@example.com")
|
.header("current-user", "person-TuckerJack@example.com")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/booking/items/" + givenBookingItemUuid)
|
.get("http://localhost/api/hs/booking/items/" + givenBookingItemUuid)
|
||||||
.then().log().body().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType("application/json")
|
.contentType("application/json")
|
||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
{
|
{
|
||||||
"debitor": { "debitorNumber": 1000111 },
|
"caption": "some CloudServer",
|
||||||
"validFrom": "2022-10-01",
|
"validFrom": "2023-01-15",
|
||||||
"validTo": "2026-12-31"
|
"validTo": "2024-04-14",
|
||||||
|
"resources": null
|
||||||
}
|
}
|
||||||
""")); // @formatter:on
|
""")); // @formatter:on
|
||||||
}
|
}
|
||||||
@ -227,15 +241,16 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
""")
|
""")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.patch("http://localhost/api/hs/office/BookingItems/" + givenBookingItem.getUuid())
|
.patch("http://localhost/api/hs/booking/items/" + givenBookingItem.getUuid())
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
{
|
{
|
||||||
"debitor": { "debitorNumber": 1000111 },
|
"caption": "some test-booking",
|
||||||
"validFrom": "2022-10-01",
|
"validFrom": "2020-06-05",
|
||||||
"validTo": "2026-12-31"
|
"validTo": "2022-12-31",
|
||||||
|
"resources": null
|
||||||
}
|
}
|
||||||
""")); // @formatter:on
|
""")); // @formatter:on
|
||||||
|
|
||||||
@ -267,15 +282,16 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
""")
|
""")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.patch("http://localhost/api/hs/office/BookingItems/" + givenBookingItem.getUuid())
|
.patch("http://localhost/api/hs/booking/items/" + givenBookingItem.getUuid())
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
{
|
{
|
||||||
"debitor": { "debitorNumber": 1000111 },
|
"caption": "some test-booking",
|
||||||
"validFrom": "2022-10-01",
|
"validFrom": "2022-11-01",
|
||||||
"validTo": "2026-12-31"
|
"validTo": "2022-12-31",
|
||||||
|
"resources": null
|
||||||
}
|
}
|
||||||
""")); // @formatter:on
|
""")); // @formatter:on
|
||||||
|
|
||||||
@ -305,7 +321,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
""")
|
""")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.patch("http://localhost/api/hs/office/BookingItems/" + givenBookingItem.getUuid())
|
.patch("http://localhost/api/hs/booking/items/" + givenBookingItem.getUuid())
|
||||||
.then().assertThat()
|
.then().assertThat()
|
||||||
// TODO.impl: I'd prefer a 400,
|
// TODO.impl: I'd prefer a 400,
|
||||||
// but OpenApi Spring Code Gen does not convert additonalProperties=false into a validation
|
// but OpenApi Spring Code Gen does not convert additonalProperties=false into a validation
|
||||||
@ -333,7 +349,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
.header("current-user", "superuser-alex@hostsharing.net")
|
.header("current-user", "superuser-alex@hostsharing.net")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/BookingItems/" + givenBookingItem.getUuid())
|
.delete("http://localhost/api/hs/booking/items/" + givenBookingItem.getUuid())
|
||||||
.then().log().body().assertThat()
|
.then().log().body().assertThat()
|
||||||
.statusCode(204); // @formatter:on
|
.statusCode(204); // @formatter:on
|
||||||
|
|
||||||
@ -351,7 +367,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
.header("current-user", "bankaccount-admin@FirstGmbH.example.com")
|
.header("current-user", "bankaccount-admin@FirstGmbH.example.com")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/BookingItems/" + givenBookingItem.getUuid())
|
.delete("http://localhost/api/hs/booking/items/" + givenBookingItem.getUuid())
|
||||||
.then().log().body().assertThat()
|
.then().log().body().assertThat()
|
||||||
.statusCode(403); // @formatter:on
|
.statusCode(403); // @formatter:on
|
||||||
|
|
||||||
@ -370,7 +386,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
.header("current-user", "selfregistered-user-drew@hostsharing.org")
|
.header("current-user", "selfregistered-user-drew@hostsharing.org")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/BookingItems/" + givenBookingItem.getUuid())
|
.delete("http://localhost/api/hs/booking/items/" + givenBookingItem.getUuid())
|
||||||
.then().log().body().assertThat()
|
.then().log().body().assertThat()
|
||||||
.statusCode(404); // @formatter:on
|
.statusCode(404); // @formatter:on
|
||||||
|
|
||||||
@ -386,6 +402,8 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
final var newBookingItem = HsBookingItemEntity.builder()
|
final var newBookingItem = HsBookingItemEntity.builder()
|
||||||
.uuid(UUID.randomUUID())
|
.uuid(UUID.randomUUID())
|
||||||
.debitor(givenDebitor)
|
.debitor(givenDebitor)
|
||||||
|
.caption("some test-booking")
|
||||||
|
.resources(Map.ofEntries(entry("something", 1)))
|
||||||
.validity(Range.closedOpen(
|
.validity(Range.closedOpen(
|
||||||
LocalDate.parse("2022-11-01"), LocalDate.parse("2023-03-31")))
|
LocalDate.parse("2022-11-01"), LocalDate.parse("2023-03-31")))
|
||||||
.build();
|
.build();
|
||||||
|
@ -148,7 +148,7 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
|
|||||||
public void globalAdmin_withoutAssumedRole_canViewAllBookingItemsOfArbitraryDebitor() {
|
public void globalAdmin_withoutAssumedRole_canViewAllBookingItemsOfArbitraryDebitor() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var debitorUuid = debitorRepo.findDebitorByDebitorNumber(1000111).stream().findAny().orElseThrow().getUuid();
|
final var debitorUuid = debitorRepo.findDebitorByDebitorNumber(1000212).stream().findAny().orElseThrow().getUuid();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = bookingItemRepo.findAllByDebitorUuid(debitorUuid);
|
final var result = bookingItemRepo.findAllByDebitorUuid(debitorUuid);
|
||||||
@ -156,7 +156,9 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
|
|||||||
// then
|
// then
|
||||||
allTheseBookingItemsAreReturned(
|
allTheseBookingItemsAreReturned(
|
||||||
result,
|
result,
|
||||||
"HsBookingItemEntity(D-1000111, some booking 1, [2022-10-01,), {CPUs=2, HDD-storage=512})");
|
"HsBookingItemEntity(D-1000212, some CloudServer, [2023-01-15,2024-04-15), {CPUs=2, HDD-storage=1024})",
|
||||||
|
"HsBookingItemEntity(D-1000212, some ManagedServer, [2022-10-01,), {CPUs=2, SDD-storage=512})",
|
||||||
|
"HsBookingItemEntity(D-1000212, some Whatever, [2024-04-01,), {CPUs=1, HDD-storage=2048, SDD-storage=512})");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -171,7 +173,9 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
|
|||||||
// then:
|
// then:
|
||||||
exactlyTheseBookingItemsAreReturned(
|
exactlyTheseBookingItemsAreReturned(
|
||||||
result,
|
result,
|
||||||
"HsBookingItemEntity(D-1000111, some booking 1, [2022-10-01,), {CPUs=2, HDD-storage=512})");
|
"HsBookingItemEntity(D-1000111, some CloudServer, [2023-01-15,2024-04-15), {CPUs=2, HDD-storage=1024})",
|
||||||
|
"HsBookingItemEntity(D-1000111, some ManagedServer, [2022-10-01,), {CPUs=2, SDD-storage=512})",
|
||||||
|
"HsBookingItemEntity(D-1000111, some Whatever, [2024-04-01,), {CPUs=1, HDD-storage=2048, SDD-storage=512})");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,6 +181,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
.containsExactlyInAnyOrder(Array.fromFormatted(
|
.containsExactlyInAnyOrder(Array.fromFormatted(
|
||||||
initialGrantNames,
|
initialGrantNames,
|
||||||
"{ grant perm:relation#FirstGmbH-with-DEBITOR-FourtheG:INSERT>sepamandate to role:relation#FirstGmbH-with-DEBITOR-FourtheG:ADMIN by system and assume }",
|
"{ grant perm:relation#FirstGmbH-with-DEBITOR-FourtheG:INSERT>sepamandate to role:relation#FirstGmbH-with-DEBITOR-FourtheG:ADMIN by system and assume }",
|
||||||
|
"{ grant perm:relation#FirstGmbH-with-DEBITOR-FourtheG:INSERT>hs_booking_item to role:relation#FirstGmbH-with-DEBITOR-FourtheG:ADMIN by system and assume }",
|
||||||
|
|
||||||
// owner
|
// owner
|
||||||
"{ grant perm:debitor#D-1000122:DELETE to role:relation#FirstGmbH-with-DEBITOR-FourtheG:OWNER by system and assume }",
|
"{ grant perm:debitor#D-1000122:DELETE to role:relation#FirstGmbH-with-DEBITOR-FourtheG:OWNER by system and assume }",
|
||||||
|
Loading…
Reference in New Issue
Block a user