use-case-test for create debitor
This commit is contained in:
parent
1516332f9f
commit
963bf89841
@ -17,10 +17,8 @@ components:
|
|||||||
minimum: 1000000
|
minimum: 1000000
|
||||||
maximum: 9999999
|
maximum: 9999999
|
||||||
debitorNumberSuffix:
|
debitorNumberSuffix:
|
||||||
type: integer
|
type: string
|
||||||
format: int8
|
pattern: '^[0-9][0-9]$'
|
||||||
minimum: 00
|
|
||||||
maximum: 99
|
|
||||||
partner:
|
partner:
|
||||||
$ref: 'hs-office-partner-schemas.yaml#/components/schemas/HsOfficePartner'
|
$ref: 'hs-office-partner-schemas.yaml#/components/schemas/HsOfficePartner'
|
||||||
billable:
|
billable:
|
||||||
@ -81,10 +79,8 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
debitorNumberSuffix:
|
debitorNumberSuffix:
|
||||||
type: integer
|
type: string
|
||||||
format: int8
|
pattern: '^[0-9][0-9]$'
|
||||||
minimum: 00
|
|
||||||
maximum: 99
|
|
||||||
billable:
|
billable:
|
||||||
type: boolean
|
type: boolean
|
||||||
vatId:
|
vatId:
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
package net.hostsharing.hsadminng.hs.office.usecases;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
|
import static io.restassured.http.Method.POST;
|
||||||
|
|
||||||
|
class HsOfficeDebitorUseCase extends UseCase {
|
||||||
|
|
||||||
|
public HsOfficeDebitorUseCase(final UseCaseTest testSuite) {
|
||||||
|
super(testSuite);
|
||||||
|
}
|
||||||
|
|
||||||
|
void shouldCreateSelfDebitorForPartner() {
|
||||||
|
|
||||||
|
http(POST, "/api/hs/office/bankaccounts", usingJsonBody("""
|
||||||
|
{
|
||||||
|
"holder": "Test AG - refund bank account",
|
||||||
|
"iban": "DE88100900001234567892",
|
||||||
|
"bic": "BEVODEBB"
|
||||||
|
}
|
||||||
|
"""))
|
||||||
|
.expecting(HttpStatus.CREATED)
|
||||||
|
.keepingAs("bankaccount:Test AG - refund bank account.uuid");
|
||||||
|
|
||||||
|
http(POST, "/api/hs/office/contacts", usingJsonBody("""
|
||||||
|
{
|
||||||
|
"caption": "Test AG - billing department",
|
||||||
|
"emailAddresses": {
|
||||||
|
"main": "billing@test-ag.example.org"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""))
|
||||||
|
.expecting(HttpStatus.CREATED)
|
||||||
|
.keepingAs("contact:Test AG - billing department.uuid");
|
||||||
|
|
||||||
|
http(POST, "/api/hs/office/debitors", usingJsonBody("""
|
||||||
|
{
|
||||||
|
"debitorRel": {
|
||||||
|
"type": "DEBITOR", // FIXME: should be defaulted to DEBITOR
|
||||||
|
"anchorUuid": "${person:Test AG.uuid}",
|
||||||
|
"holderUuid": "${person:Test AG.uuid}",
|
||||||
|
"contactUuid": "${contact:Test AG - billing department.uuid}"
|
||||||
|
},
|
||||||
|
"debitorNumberSuffix": "00",
|
||||||
|
"billable": "true",
|
||||||
|
"vatId": "VAT123456",
|
||||||
|
"vatCountryCode": "DE",
|
||||||
|
"vatBusiness": true,
|
||||||
|
"vatReverseCharge": "false",
|
||||||
|
"refundBankAccountUuid": "${bankaccount:Test AG - refund bank account.uuid}",
|
||||||
|
"defaultPrefix": "tst"
|
||||||
|
}
|
||||||
|
"""))
|
||||||
|
.expecting(HttpStatus.CREATED)
|
||||||
|
.keepingAs("debitor:Test AG - Hauptdebitor.uuid");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
package net.hostsharing.hsadminng.hs.office.usecases;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
|
import static io.restassured.http.Method.POST;
|
||||||
|
|
||||||
|
class HsOfficePartnerUseCase extends UseCase {
|
||||||
|
|
||||||
|
public HsOfficePartnerUseCase(final UseCaseTest testSuite) {
|
||||||
|
super(testSuite);
|
||||||
|
}
|
||||||
|
|
||||||
|
void shouldCreatePartner() {
|
||||||
|
|
||||||
|
http(POST, "/api/hs/office/persons", usingJsonBody("""
|
||||||
|
{
|
||||||
|
"personType": "LEGAL_PERSON",
|
||||||
|
"tradeName": "Test AG"
|
||||||
|
}
|
||||||
|
"""))
|
||||||
|
.expecting(HttpStatus.CREATED)
|
||||||
|
.keepingAs("person:Test AG.uuid");
|
||||||
|
|
||||||
|
http(POST, "/api/hs/office/contacts", usingJsonBody("""
|
||||||
|
{
|
||||||
|
"caption": "Test AG - Bord of Directors",
|
||||||
|
"emailAddresses": {
|
||||||
|
"main": "bord-of-directors@test-ag.example.org"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""))
|
||||||
|
.expecting(HttpStatus.CREATED)
|
||||||
|
.keepingAs("contact:Test AG - Bord of Directors.uuid");
|
||||||
|
|
||||||
|
http(POST, "/api/hs/office/partners", usingJsonBody("""
|
||||||
|
{
|
||||||
|
"partnerNumber": "30003",
|
||||||
|
"partnerRel": {
|
||||||
|
"anchorUuid": "${person:Hostsharing eG.uuid}",
|
||||||
|
"holderUuid": "${person:Test AG.uuid}",
|
||||||
|
"contactUuid": "${contact:Test AG - Bord of Directors.uuid}"
|
||||||
|
},
|
||||||
|
"details": {
|
||||||
|
"registrationOffice": "Registergericht Hamburg",
|
||||||
|
"registrationNumber": "1234567"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""))
|
||||||
|
.expecting(HttpStatus.CREATED)
|
||||||
|
.keepingAs("partner:Test AG.uuid");
|
||||||
|
}
|
||||||
|
}
|
@ -1,62 +0,0 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.usecases;
|
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.HsadminNgApplication;
|
|
||||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
|
||||||
import org.junit.jupiter.api.Order;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
|
|
||||||
import static io.restassured.http.Method.POST;
|
|
||||||
|
|
||||||
@SpringBootTest(
|
|
||||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
|
||||||
classes = { HsadminNgApplication.class, JpaAttempt.class }
|
|
||||||
)
|
|
||||||
// @Tag("useCaseTest") FIXME
|
|
||||||
@Order(1)
|
|
||||||
class HsOfficePartnerUseCaseTest extends UseCaseTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldCreatePartner() {
|
|
||||||
|
|
||||||
http(POST, "/api/hs/office/persons", usingJsonBody("""
|
|
||||||
{
|
|
||||||
"personType": "NATURAL_PERSON",
|
|
||||||
"familyName": "Tester",
|
|
||||||
"givenName": "Temp Testi"
|
|
||||||
}
|
|
||||||
"""))
|
|
||||||
.expecting(HttpStatus.CREATED)
|
|
||||||
.keepingAs("partnerPerson.uuid");
|
|
||||||
|
|
||||||
http(POST, "/api/hs/office/contacts", usingJsonBody("""
|
|
||||||
{
|
|
||||||
"caption": "Temp Contact",
|
|
||||||
"emailAddresses": {
|
|
||||||
"main": "test@example.org"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"""))
|
|
||||||
.expecting(HttpStatus.CREATED)
|
|
||||||
.keepingAs("contact.uuid");
|
|
||||||
|
|
||||||
http(POST, "/api/hs/office/partners", usingJsonBody("""
|
|
||||||
{
|
|
||||||
"partnerNumber": "20002",
|
|
||||||
"partnerRel": {
|
|
||||||
"anchorUuid": "${hostsharingPerson.uuid}",
|
|
||||||
"holderUuid": "${partnerPerson.uuid}",
|
|
||||||
"contactUuid": "${contact.uuid}"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"registrationOffice": "Registergericht Hamburg",
|
|
||||||
"registrationNumber": "1234567"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"""))
|
|
||||||
.expecting(HttpStatus.CREATED)
|
|
||||||
.keepingAs("partner20002.uuid");
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,31 @@
|
|||||||
|
package net.hostsharing.hsadminng.hs.office.usecases;
|
||||||
|
|
||||||
|
import net.hostsharing.hsadminng.HsadminNgApplication;
|
||||||
|
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||||
|
import org.junit.jupiter.api.ClassOrderer;
|
||||||
|
import org.junit.jupiter.api.Order;
|
||||||
|
import org.junit.jupiter.api.Tag;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.TestClassOrder;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
@SpringBootTest(
|
||||||
|
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||||
|
classes = { HsadminNgApplication.class, JpaAttempt.class }
|
||||||
|
)
|
||||||
|
@Tag("useCaseTest")
|
||||||
|
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
|
||||||
|
class HsOfficeUseCasesTest extends UseCaseTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(1010)
|
||||||
|
void shouldCreatePartner() {
|
||||||
|
new HsOfficePartnerUseCase(this).shouldCreatePartner();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(1020)
|
||||||
|
void shouldCreateSelfDebitorForPartner() {
|
||||||
|
new HsOfficeDebitorUseCase(this).shouldCreateSelfDebitorForPartner();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,97 @@
|
|||||||
|
package net.hostsharing.hsadminng.hs.office.usecases;
|
||||||
|
|
||||||
|
import io.restassured.RestAssured;
|
||||||
|
import io.restassured.http.ContentType;
|
||||||
|
import io.restassured.http.Method;
|
||||||
|
import io.restassured.response.Response;
|
||||||
|
import io.restassured.response.ValidatableResponse;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.startsWith;
|
||||||
|
|
||||||
|
public class UseCase {
|
||||||
|
|
||||||
|
private final UseCaseTest testSuite;
|
||||||
|
|
||||||
|
public UseCase(final UseCaseTest testSuite) {
|
||||||
|
this.testSuite = testSuite;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonTemplate usingJsonBody(final String jsonTemplate) {
|
||||||
|
return new JsonTemplate(jsonTemplate);
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpResponse http(final Method method, final String uriPath, final JsonTemplate bodyJsonTemplate) {
|
||||||
|
final var request = RestAssured.given()
|
||||||
|
.header("current-subject", UseCaseTest.RUN_AS_USER)
|
||||||
|
.contentType(ContentType.JSON)
|
||||||
|
.body(bodyJsonTemplate.with(UseCaseTest.aliases))
|
||||||
|
.port(testSuite.port);
|
||||||
|
final var response =
|
||||||
|
switch (method) {
|
||||||
|
case POST -> request.when().post("http://localhost" + uriPath);
|
||||||
|
default -> throw new IllegalStateException("HTTP method not implemented yet: " + method);
|
||||||
|
};
|
||||||
|
return new HttpResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class JsonTemplate {
|
||||||
|
|
||||||
|
private final String template;
|
||||||
|
|
||||||
|
private JsonTemplate(final String jsonTemplate) {
|
||||||
|
this.template = jsonTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
String with(final Map<String, String> aliases) {
|
||||||
|
var partiallyResolved = new AtomicReference<>(template);
|
||||||
|
aliases.forEach((k, v) ->
|
||||||
|
partiallyResolved.set(partiallyResolved.get().replace("${" + k + "}", v)));
|
||||||
|
verifyAllPlaceholdersResolved(partiallyResolved.get());
|
||||||
|
return partiallyResolved.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyAllPlaceholdersResolved(final String remainingTemplate) {
|
||||||
|
final var pattern = Pattern.compile("\\$\\{[^}]+\\}");
|
||||||
|
final var matcher = pattern.matcher(remainingTemplate);
|
||||||
|
|
||||||
|
final var unresolvedPlaceholders = new ArrayList<>();
|
||||||
|
while (matcher.find()) {
|
||||||
|
unresolvedPlaceholders.add(matcher.group());
|
||||||
|
}
|
||||||
|
|
||||||
|
assertThat(unresolvedPlaceholders).as("unresolved placeholders").hasSize(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class HttpResponse {
|
||||||
|
|
||||||
|
private final ValidatableResponse response;
|
||||||
|
|
||||||
|
public HttpResponse(final Response response) {
|
||||||
|
this.response = response.then().log().all().assertThat();
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpResponse expecting(final HttpStatus httpStatus) {
|
||||||
|
response.statusCode(httpStatus.value())
|
||||||
|
.contentType(ContentType.JSON);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void keepingAs(final String uuidAliasName) {
|
||||||
|
final var location = response.header("Location", startsWith("http://localhost"))
|
||||||
|
.extract().header("Location");
|
||||||
|
final var newSubjectUuid = UUID.fromString(
|
||||||
|
location.substring(location.lastIndexOf('/') + 1));
|
||||||
|
assertThat(newSubjectUuid).isNotNull();
|
||||||
|
UseCaseTest.aliases.put(uuidAliasName, newSubjectUuid.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,37 +1,25 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.usecases;
|
package net.hostsharing.hsadminng.hs.office.usecases;
|
||||||
|
|
||||||
import io.restassured.RestAssured;
|
|
||||||
import io.restassured.http.ContentType;
|
|
||||||
import io.restassured.http.Method;
|
|
||||||
import io.restassured.response.Response;
|
|
||||||
import io.restassured.response.ValidatableResponse;
|
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRepository;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
|
||||||
import net.hostsharing.hsadminng.lambda.Reducer;
|
import net.hostsharing.hsadminng.lambda.Reducer;
|
||||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
import net.hostsharing.hsadminng.rbac.context.ContextBasedTest;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.web.server.LocalServerPort;
|
import org.springframework.boot.test.web.server.LocalServerPort;
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
public abstract class UseCaseTest extends ContextBasedTest {
|
||||||
import static org.hamcrest.Matchers.startsWith;
|
|
||||||
|
|
||||||
public abstract class UseCaseTest extends ContextBasedTestWithCleanup {
|
|
||||||
|
|
||||||
final static String RUN_AS_USER = "superuser-alex@hostsharing.net"; // TODO.test: use global:AGENT when implemented
|
final static String RUN_AS_USER = "superuser-alex@hostsharing.net"; // TODO.test: use global:AGENT when implemented
|
||||||
|
|
||||||
|
final static Map<String, String> aliases = new HashMap<>();
|
||||||
|
|
||||||
@LocalServerPort
|
@LocalServerPort
|
||||||
private Integer port;
|
Integer port;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
HsOfficePersonRepository personRepo;
|
HsOfficePersonRepository personRepo;
|
||||||
@ -39,15 +27,13 @@ public abstract class UseCaseTest extends ContextBasedTestWithCleanup {
|
|||||||
@Autowired
|
@Autowired
|
||||||
JpaAttempt jpaAttempt;
|
JpaAttempt jpaAttempt;
|
||||||
|
|
||||||
Map<String, String> aliases = new HashMap<>();
|
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void init() {
|
void init() {
|
||||||
jpaAttempt.transacted(() ->
|
jpaAttempt.transacted(() ->
|
||||||
{
|
{
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
aliases.put(
|
aliases.put(
|
||||||
"hostsharingPerson.uuid",
|
"person:Hostsharing eG.uuid",
|
||||||
personRepo.findPersonByOptionalNameLike("Hostsharing eG")
|
personRepo.findPersonByOptionalNameLike("Hostsharing eG")
|
||||||
.stream()
|
.stream()
|
||||||
.map(HsOfficePersonEntity::getUuid)
|
.map(HsOfficePersonEntity::getUuid)
|
||||||
@ -56,70 +42,4 @@ public abstract class UseCaseTest extends ContextBasedTestWithCleanup {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterEach
|
|
||||||
void cleanup() {
|
|
||||||
cleanupAllNew(HsOfficePartnerEntity.class);
|
|
||||||
|
|
||||||
// TODO: should not be necessary anymore, once it's deleted via after delete trigger
|
|
||||||
cleanupAllNew(HsOfficeRelationRealEntity.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonTemplate usingJsonBody(final String jsonTemplate) {
|
|
||||||
return new JsonTemplate(jsonTemplate);
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpResponse http(final Method method, final String uriPath, final JsonTemplate bodyJsonTemplate) {
|
|
||||||
final var request = RestAssured.given()
|
|
||||||
.header("current-subject", RUN_AS_USER)
|
|
||||||
.contentType(ContentType.JSON)
|
|
||||||
.body(bodyJsonTemplate.with(aliases))
|
|
||||||
.port(port);
|
|
||||||
final var response =
|
|
||||||
switch (method) {
|
|
||||||
case POST -> request.when().post("http://localhost" + uriPath);
|
|
||||||
default -> throw new IllegalStateException("HTTP method not implemented yet: " + method);
|
|
||||||
};
|
|
||||||
return new HttpResponse(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
static class JsonTemplate {
|
|
||||||
|
|
||||||
private final String template;
|
|
||||||
|
|
||||||
private JsonTemplate(final String jsonTemplate) {
|
|
||||||
this.template = jsonTemplate;
|
|
||||||
}
|
|
||||||
|
|
||||||
String with(final Map<String, String> aliases) {
|
|
||||||
var resolved = new AtomicReference<String>(template);
|
|
||||||
aliases.forEach((k, v) ->
|
|
||||||
resolved.set(resolved.get().replace("${" + k + "}", v)));
|
|
||||||
return resolved.get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class HttpResponse {
|
|
||||||
|
|
||||||
private final ValidatableResponse response;
|
|
||||||
|
|
||||||
public HttpResponse(final Response response) {
|
|
||||||
this.response = response.then().log().all().assertThat();
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpResponse expecting(final HttpStatus httpStatus) {
|
|
||||||
response.statusCode(httpStatus.value())
|
|
||||||
.contentType(ContentType.JSON);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void keepingAs(final String uuidAliasName) {
|
|
||||||
final var location = response.header("Location", startsWith("http://localhost"))
|
|
||||||
.extract().header("Location");
|
|
||||||
final var newSubjectUuid = UUID.fromString(
|
|
||||||
location.substring(location.lastIndexOf('/') + 1));
|
|
||||||
assertThat(newSubjectUuid).isNotNull();
|
|
||||||
aliases.put(uuidAliasName, newSubjectUuid.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user