db-migration #10

Merged
hsh-michaelhoennig merged 74 commits from db-migration into master 2024-01-23 15:11:24 +01:00
24 changed files with 207 additions and 140 deletions
Showing only changes of commit 31141ad4c3 - Show all commits

View File

@ -74,3 +74,5 @@ alias pg-sql-restore='gunzip --stdout | docker exec -i hsadmin-ng-postgres psql
alias fp='grep -r '@Accepts' src | sed -e 's/^.*@/@/g' | sort -u | wc -l'
alias spotless='./gradlew spotlessApply -x pitest -x test -x :processResources'

View File

@ -100,6 +100,7 @@ dependencies {
testImplementation 'io.rest-assured:spring-mock-mvc'
testImplementation 'org.hamcrest:hamcrest-core:2.2'
testImplementation 'org.pitest:pitest-junit5-plugin:1.2.1'
testImplementation 'org.junit.jupiter:junit-jupiter-api'
}
dependencyManagement {
@ -237,12 +238,9 @@ test {
excludes = [
'net.hostsharing.hsadminng.**.generated.**',
]
test {
systemProperty "my_variable", System.getenv("MY_VARIABLE")
useJUnitPlatform {
excludeTags 'import'
}
}
jacocoTestReport {
dependsOn test
@ -303,6 +301,17 @@ jacocoTestCoverageVerification {
}
}
tasks.register('importTest', Test) {
useJUnitPlatform {
includeTags 'import'
}
group 'verification'
description 'run the import jobs as tests'
}
test.dependsOn tasks.importTest
// pitest mutation testing
pitest {
targetClasses = ['net.hostsharing.hsadminng.**']

View File

@ -1,23 +1,26 @@
# Beispiel: juristische Person (GmbH)
```mermaid
classDiagram
direction RL
direction TD
namespace Geschäftspartner {
class partner-MeierGmbH
class partnerDetails-MeierGmbH
class contact-MeierGmbH
class person-MeierGmbH
class debitor-MeierGmbH
class contact-MeierGmbH-Buha
class person-FrankMeier
class contact-FrankMeier
class rel-MeierGmbH-FrankMeier
class role-MeierGmbH-FrankMeier
class person-SabineMeier
class contact-SabineMeier
class rel-MeierGmbH-SabineMeier
class role-MeierGmbH-SabineMeier
class debitor-MeierGmbH
class contact-MeierGmbH-Buha
class role-MeierGmbH-Buha
}
class partner-MeierGmbH {
@ -27,20 +30,17 @@ classDiagram
}
partner-MeierGmbH o-- person-MeierGmbH
partner-MeierGmbH o-- contact-MeierGmbH
partner-MeierGmbH *-- partnerDetails-MeierGmbH
class partnerDetails-MeierGmbH {
+registrationOffice
+registrationNumber
+birthName
+dateOfDeath
}
class person-MeierGmbH {
+ personType: LEGAL
+ tradeName: Meier GmbH
+ familyName
+ givenName
+personType: LEGAL
+tradeName: Meier GmbH
+familyName
+givenName
+registrationOffice: AG Hamburg
+registrationNumber: ABC123434
+birthName
+birthPlace
+dateOfDeath
}
class contact-MeierGmbH {
@ -51,8 +51,8 @@ classDiagram
class debitor-MeierGmbH {
+Partner partner
+Numeric(2) debitorNumberSuffix: 00
+Contact billingContact
+Numeric[2] debitorNumberSuffix: 00
+Role billingRole
+boolean billable: true
+String vatId: ID123456789
+String vatCountryCode: DE
@ -62,7 +62,7 @@ classDiagram
+String defaultPrefix: mei
}
debitor-MeierGmbH o-- partner-MeierGmbH
debitor-MeierGmbH o-- contact-MeierGmbH-Buha
debitor-MeierGmbH o-- role-MeierGmbH-Buha
class contact-MeierGmbH-Buha {
+postalAddress: Hauptstraße 5, 22345 Hamburg
@ -70,6 +70,16 @@ classDiagram
+emailAddresses: buha@meier-gmbh.de
}
class role-MeierGmbH-Buha {
+RelType relType ACCOUNTING
+Person relAnchor
+Person relHolder
+Contact contact
}
role-MeierGmbH-Buha o-- person-MeierGmbH : relAnchor
role-MeierGmbH-Buha o-- person-MeierGmbH : relHolder
role-MeierGmbH-Buha o-- contact-MeierGmbH-Buha
class person-FrankMeier {
+ personType: NATURAL
+ tradeName
@ -80,18 +90,18 @@ classDiagram
class contact-FrankMeier {
+postalAddress
+phoneNumbers: +49 40 12345-22
+emailAddresses: sabine.meier@meier-gmbh.de
+emailAddresses: frank.meier@meier-gmbh.de
}
class rel-MeierGmbH-FrankMeier {
class role-MeierGmbH-FrankMeier {
+RelType relType REPRESENTATIVE
+Person relAnchor
+Person relHolder
+Contact contact
}
rel-MeierGmbH-FrankMeier o-- person-MeierGmbH : relAnchor
rel-MeierGmbH-FrankMeier o-- person-FrankMeier : relHolder
rel-MeierGmbH-FrankMeier o-- contact-FrankMeier
role-MeierGmbH-FrankMeier o-- person-MeierGmbH : relAnchor
role-MeierGmbH-FrankMeier o-- person-FrankMeier : relHolder
role-MeierGmbH-FrankMeier o-- contact-FrankMeier
class person-SabineMeier {
+personType: NATURAL
@ -106,15 +116,15 @@ classDiagram
+emailAddresses: sabine.meier@meier-gmbh.de
}
class rel-MeierGmbH-SabineMeier {
class role-MeierGmbH-SabineMeier {
+RelType relType OPERATIONAL
+Person relAnchor
+Person relHolder
+Contact contact
}
rel-MeierGmbH-SabineMeier o-- person-MeierGmbH : relAnchor
rel-MeierGmbH-SabineMeier o-- person-SabineMeier : relHolder
rel-MeierGmbH-SabineMeier o-- contact-SabineMeier
role-MeierGmbH-SabineMeier o-- person-MeierGmbH : relAnchor
role-MeierGmbH-SabineMeier o-- person-SabineMeier : relHolder
role-MeierGmbH-SabineMeier o-- contact-SabineMeier
namespace Enums {
@ -128,24 +138,13 @@ classDiagram
class PersonType {
<<enumeration>>
UNKNOWN
NATURAL
LEGAL
SOLE_REPRESENTATION
JOINT_REPRESENTATION
UNKNOWN: nur für Import
NATURAL_PERSON: natürliche Person
LEGAL_PERSON: z.B. GmbH, e.K., eG, e.V.
INCORORATED_FIRM: z.B. OHG, Partnerschaftsgesellschaft
UNINCORPORATED_FIRM: z.B. GbR, ARGE, Erbengemeinschaft
PUBLIC_INSTITUTION: KdöR, AöR [ohne Registergericht/Registernummer]
}
}
}
```
```mermaid
classDiagram
classA --|> classB : Inheritance
classC --* classD : Composition
classE --o classF : Aggregation
classG --> classH : Association
classI -- classJ : Link(Solid)
classK ..> classL : Dependency
classM ..|> classN : Realization
classO .. classP : Link(Dashed)
```

View File

@ -51,7 +51,7 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable {
@ManyToOne
@JoinColumn(name = "billingcontactuuid")
private HsOfficeContactEntity billingContact;
private HsOfficeContactEntity billingContact; // TODO: migrate to billingPerson
@Column(name = "billable")
private boolean billable;

View File

@ -27,8 +27,9 @@ public class HsOfficePartnerDetailsEntity implements HasUuid, Stringifyable {
"partnerDetails")
.withProp(HsOfficePartnerDetailsEntity::getRegistrationOffice)
.withProp(HsOfficePartnerDetailsEntity::getRegistrationNumber)
.withProp(HsOfficePartnerDetailsEntity::getBirthPlace)
.withProp(HsOfficePartnerDetailsEntity::getBirthday)
.withProp(HsOfficePartnerDetailsEntity::getBirthday)
.withProp(HsOfficePartnerDetailsEntity::getBirthName)
.withProp(HsOfficePartnerDetailsEntity::getDateOfDeath)
.withSeparator(", ")
.quotedValues(false);
@ -40,6 +41,7 @@ public class HsOfficePartnerDetailsEntity implements HasUuid, Stringifyable {
private @Column(name = "registrationoffice") String registrationOffice;
private @Column(name = "registrationnumber") String registrationNumber;
private @Column(name = "birthname") String birthName;
private @Column(name = "birthplace") String birthPlace;
private @Column(name = "birthday") LocalDate birthday;
private @Column(name = "dateofdeath") LocalDate dateOfDeath;

View File

@ -54,6 +54,7 @@ public class HsOfficePersonEntity implements HasUuid, Stringifyable {
@Override
public String toShortString() {
return !StringUtils.isEmpty(tradeName) ? tradeName : (familyName + ", " + givenName);
return personType + " " +
(!StringUtils.isEmpty(tradeName) ? tradeName : (familyName + ", " + givenName));
}
}

View File

@ -0,0 +1,18 @@
--liquibase formatted sql
-- ============================================================================
-- NUMERIC-HASH-FUNCTIONS
--changeset hash:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
do $$
begin
if starts_with ('${HSADMINNG_POSTGRES_ADMIN_USERNAME}', '$') then
RAISE EXCEPTION 'environment variable HSADMINNG_POSTGRES_ADMIN_USERNAME not set';
end if;
if starts_with ('${HSADMINNG_POSTGRES_RESTRICTED_USERNAME}', '$') then
RAISE EXCEPTION 'environment variable HSADMINNG_POSTGRES_RESTRICTED_USERNAME not set';
end if;
end $$
--//

View File

@ -1,12 +0,0 @@
--liquibase formatted sql
-- ============================================================================
-- NUMERIC-HASH-FUNCTIONS
--changeset hash:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
create function postgresAdminUserName() returns text as $$
if
$$ language sql;
--//

View File

@ -10,6 +10,7 @@ create table hs_office_partner_details
uuid uuid unique references RbacObject (uuid) initially deferred,
registrationOffice varchar(96),
registrationNumber varchar(96),
birthPlace varchar(96),
birthName varchar(96),
birthday date,
dateOfDeath date

View File

@ -29,6 +29,7 @@ call generateRbacRestrictedView('hs_office_partner_details',
$updates$
registrationOffice = new.registrationOffice,
registrationNumber = new.registrationNumber,
birthPlace = new.birthPlace,
birthName = new.birthName,
birthday = new.birthday,
dateOfDeath = new.dateOfDeath

View File

@ -11,6 +11,8 @@ databaseChangeLog:
file: db/changelog/005-uuid-ossp-extension.sql
- include:
file: db/changelog/006-numeric-hash-functions.sql
- include:
file: db/changelog/009-check-environment.sql
- include:
file: db/changelog/010-context.sql
- include:

View File

@ -4,6 +4,7 @@ import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerDetailsEntity;
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
@ -16,6 +17,7 @@ class HsOfficeDebitorEntityUnitTest {
.debitorNumberSuffix((byte)67)
.partner(HsOfficePartnerEntity.builder()
.person(HsOfficePersonEntity.builder()
.personType(HsOfficePersonType.LEGAL)
.tradeName("some trade name")
.build())
.details(HsOfficePartnerDetailsEntity.builder().birthName("some birth name").build())
@ -27,7 +29,7 @@ class HsOfficeDebitorEntityUnitTest {
final var result = given.toString();
assertThat(result).isEqualTo("debitor(1234567: some trade name: som)");
assertThat(result).isEqualTo("debitor(1234567: LEGAL some trade name: som)");
}
@Test

View File

@ -215,9 +215,9 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
// then
allTheseDebitorsAreReturned(
result,
"debitor(1000111: First GmbH: fir)",
"debitor(1000212: Second e.K.: sec)",
"debitor(1000313: Third OHG: thi)");
"debitor(1000111: LEGAL First GmbH: fir)",
"debitor(1000212: LEGAL Second e.K.: sec)",
"debitor(1000313: SOLE_REPRESENTATION Third OHG: thi)");
}
@ParameterizedTest
@ -235,8 +235,8 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
// then:
exactlyTheseDebitorsAreReturned(result,
"debitor(1000111: First GmbH: fir)",
"debitor(1000120: First GmbH: fif)");
"debitor(1000111: LEGAL First GmbH: fir)",
"debitor(1000120: LEGAL First GmbH: fif)");
}
@Test
@ -264,7 +264,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
final var result = debitorRepo.findDebitorByDebitorNumber(1000313);
// then
exactlyTheseDebitorsAreReturned(result, "debitor(1000313: Third OHG: thi)");
exactlyTheseDebitorsAreReturned(result, "debitor(1000313: SOLE_REPRESENTATION Third OHG: thi)");
}
}
@ -280,7 +280,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest {
final var result = debitorRepo.findDebitorByOptionalNameLike("third contact");
// then
exactlyTheseDebitorsAreReturned(result, "debitor(1000313: Third OHG: thi)");
exactlyTheseDebitorsAreReturned(result, "debitor(1000313: SOLE_REPRESENTATION Third OHG: thi)");
}
}

View File

@ -287,7 +287,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
// finally, the Membership is actually updated
assertThat(membershipRepo.findByUuid(givenMembership.getUuid())).isPresent().get()
.matches(mandate -> {
assertThat(mandate.getPartner().toShortString()).isEqualTo("First GmbH");
assertThat(mandate.getPartner().toShortString()).isEqualTo("LEGAL First GmbH");
assertThat(mandate.getMainDebitor().toString()).isEqualTo(givenMembership.getMainDebitor().toString());
assertThat(mandate.getMemberNumber()).isEqualTo(givenMembership.getMemberNumber());
assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,2024-01-01)");
@ -330,7 +330,7 @@ class HsOfficeMembershipControllerAcceptanceTest {
// finally, the Membership is actually updated
assertThat(membershipRepo.findByUuid(givenMembership.getUuid())).isPresent().get()
.matches(mandate -> {
assertThat(mandate.getPartner().toShortString()).isEqualTo("First GmbH");
assertThat(mandate.getPartner().toShortString()).isEqualTo("LEGAL First GmbH");
assertThat(mandate.getMainDebitor().toString()).isEqualTo(givenMembership.getMainDebitor().toString());
assertThat(mandate.getMemberNumber()).isEqualTo(givenMembership.getMemberNumber());
assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,)");

View File

@ -27,8 +27,7 @@ class HsOfficeMembershipEntityUnitTest {
void toStringContainsAllProps() {
final var result = givenMembership.toString();
assertThat(result).isEqualTo("Membership(10001, Test Ltd., 1000100, [2020-01-01,))");
// assertThat(result).isEqualTo("Membership(10001, Test Ltd., 1000100, [2020-01-01,))");
assertThat(result).isEqualTo("Membership(10001, LEGAL Test Ltd., 1000100, [2020-01-01,))");
}
@Test

View File

@ -185,9 +185,9 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
// then
exactlyTheseMembershipsAreReturned(
result,
"Membership(10001, First GmbH, 1000111, [2022-10-01,), NONE)",
"Membership(10002, Second e.K., 1000212, [2022-10-01,), NONE)",
"Membership(10003, Third OHG, 1000313, [2022-10-01,), NONE)");
"Membership(10001, LEGAL First GmbH, 1000111, [2022-10-01,), NONE)",
"Membership(10002, LEGAL Second e.K., 1000212, [2022-10-01,), NONE)",
"Membership(10003, SOLE_REPRESENTATION Third OHG, 1000313, [2022-10-01,), NONE)");
}
@Test
@ -202,7 +202,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
null);
// then
exactlyTheseMembershipsAreReturned(result, "Membership(10001, First GmbH, 1000111, [2022-10-01,), NONE)");
exactlyTheseMembershipsAreReturned(result, "Membership(10001, LEGAL First GmbH, 1000111, [2022-10-01,), NONE)");
}
@Test
@ -214,7 +214,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest {
final var result = membershipRepo.findMembershipsByOptionalPartnerUuidAndOptionalMemberNumber(null, 10002);
// then
exactlyTheseMembershipsAreReturned(result, "Membership(10002, Second e.K., 1000212, [2022-10-01,), NONE)");
exactlyTheseMembershipsAreReturned(result, "Membership(10002, LEGAL Second e.K., 1000212, [2022-10-01,), NONE)");
}
}

View File

@ -23,6 +23,10 @@ import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipType
import net.hostsharing.hsadminng.hs.office.sepamandate.HsOfficeSepaMandateEntity;
import net.hostsharing.test.JpaAttempt;
import org.junit.jupiter.api.*;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.TestWatcher;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
@ -48,6 +52,7 @@ import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateR
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assumptions.assumeThat;
import static org.assertj.core.api.Fail.fail;
/*
@ -91,7 +96,7 @@ import static org.assertj.core.api.Fail.fail;
*
* import-office-tables # comes from .aliases file
*/
//@Disabled
@Tag("import")
@DataJpaTest(properties = {
"spring.datasource.url=${HSADMINNG_POSTGRES_JDBC_URL:jdbc:tc:postgresql:15.5-bookworm:///spring_boot_testcontainers}",
"spring.datasource.username=${HSADMINNG_POSTGRES_ADMIN_USERNAME:admin}",
@ -99,6 +104,7 @@ import static org.assertj.core.api.Fail.fail;
})
@Import({ Context.class, JpaAttempt.class })
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@ExtendWith(OrderedDependedTestsExtension.class)
public class ImportOfficeTables extends ContextBasedTest {
@Value("${spring.datasource.username}")
@ -151,23 +157,23 @@ public class ImportOfficeTables extends ContextBasedTest {
// no contacts yet => mostly null values
assertThat(partners.toString()).isEqualToIgnoringWhitespace("""
{
7=partner(null, null),
10=partner(null, null),
12=partner(null, null)
7=partner(UNKNOWN null, null),
10=partner(UNKNOWN null, null),
12=partner(UNKNOWN null, null)
}
""");
assertThat(contacts.toString()).isEqualTo("{}");
assertThat(debitors.toString()).isEqualToIgnoringWhitespace("""
{
7=debitor(1000700: null, null: mih),
10=debitor(1001000: null, null: xyz),
12=debitor(1101200: null, null: xxx)}
7=debitor(1000700: UNKNOWN null, null: mih),
10=debitor(1001000: UNKNOWN null, null: xyz),
12=debitor(1101200: UNKNOWN null, null: xxx)}
""");
assertThat(memberships.toString()).isEqualToIgnoringWhitespace("""
{
7=Membership(10007, null, null, 1000700, [2000-12-06,), NONE),
10=Membership(10010, null, null, 1001000, [2000-12-06,2016-01-01), UNKNOWN),
12=Membership(11012, null, null, 1101200, [2021-04-01,), NONE)
7=Membership(10007, UNKNOWN null, null, 1000700, [2000-12-06,), NONE),
10=Membership(10010, UNKNOWN null, null, 1001000, [2000-12-06,2016-01-01), UNKNOWN),
12=Membership(11012, UNKNOWN null, null, 1101200, [2021-04-01,), NONE)
}
""");
}
@ -189,9 +195,9 @@ public class ImportOfficeTables extends ContextBasedTest {
assertThat(partners.toString()).isEqualToIgnoringWhitespace("""
{
7=partner(Mellies, Michael: Herr Michael Mellies ),
10=partner(JM e.K.: Herr Philip Meyer-Contract , JM e.K.),
12=partner(Test PS: Petra Schmidt , Test PS)
7=partner(NATURAL Mellies, Michael: Herr Michael Mellies ),
10=partner(LEGAL JM e.K.: Herr Philip Meyer-Contract , JM e.K.),
12=partner(LEGAL Test PS: Petra Schmidt , Test PS)
}
""");
assertThat(contacts.toString()).isEqualToIgnoringWhitespace("""
@ -205,31 +211,31 @@ public class ImportOfficeTables extends ContextBasedTest {
""");
assertThat(persons.toString()).isEqualToIgnoringWhitespace("""
{
900000=person(personType='UNKNOWN', tradeName='', familyName='Mellies', givenName='Michael'),
900001=person(personType='UNKNOWN', tradeName='JM e.K.', familyName='Meyer-Contract', givenName='Philip'),
900002=person(personType='UNKNOWN', tradeName='Test PS', familyName='Schmidt', givenName='Petra')
900000=person(personType='NATURAL', tradeName='', familyName='Mellies', givenName='Michael'),
900001=person(personType='LEGAL', tradeName='JM e.K.', familyName='Meyer-Contract', givenName='Philip'),
900002=person(personType='LEGAL', tradeName='Test PS', familyName='Schmidt', givenName='Petra')
}
""");
assertThat(debitors.toString()).isEqualToIgnoringWhitespace("""
{
7=debitor(1000700: Mellies, Michael: mih),
10=debitor(1001000: JM e.K.: xyz),
12=debitor(1101200: Test PS: xxx)
7=debitor(1000700: NATURAL Mellies, Michael: mih),
10=debitor(1001000: LEGAL JM e.K.: xyz),
12=debitor(1101200: LEGAL Test PS: xxx)
}
""");
assertThat(memberships.toString()).isEqualToIgnoringWhitespace("""
{
7=Membership(10007, Mellies, Michael, 1000700, [2000-12-06,), NONE),
10=Membership(10010, JM e.K., 1001000, [2000-12-06,2016-01-01), UNKNOWN),
12=Membership(11012, Test PS, 1101200, [2021-04-01,), NONE)
7=Membership(10007, NATURAL Mellies, Michael, 1000700, [2000-12-06,), NONE),
10=Membership(10010, LEGAL JM e.K., 1001000, [2000-12-06,2016-01-01), UNKNOWN),
12=Membership(11012, LEGAL Test PS, 1101200, [2021-04-01,), NONE)
}
""");
assertThat(relationships.toString()).isEqualToIgnoringWhitespace("""
{
1101=rel(relAnchor='Mellies, Michael', relType='OPERATIONS', relHolder='Mellies, Michael', contact='Herr Michael Mellies '),
1202=rel(relAnchor='JM e.K.', relType='OPERATIONS', relHolder='JM e.K.', contact='Herr Andrew Meyer-Operation , JM e.K.'),
1203=rel(relAnchor='JM e.K.', relType='REPRESENTATIVE', relHolder='JM e.K.', contact='Herr Philip Meyer-Contract , JM e.K.'),
1301=rel(relAnchor='Test PS', relType='REPRESENTATIVE', relHolder='Test PS', contact='Petra Schmidt , Test PS')
1101=rel(relAnchor='NATURAL Mellies, Michael', relType='OPERATIONS', relHolder='NATURAL Mellies, Michael', contact='Herr Michael Mellies '),
1202=rel(relAnchor='LEGAL JM e.K.', relType='OPERATIONS', relHolder='LEGAL JM e.K.', contact='Herr Andrew Meyer-Operation , JM e.K.'),
1203=rel(relAnchor='LEGAL JM e.K.', relType='REPRESENTATIVE', relHolder='LEGAL JM e.K.', contact='Herr Philip Meyer-Contract , JM e.K.'),
1301=rel(relAnchor='LEGAL Test PS', relType='REPRESENTATIVE', relHolder='LEGAL Test PS', contact='Petra Schmidt , Test PS')
}
""");
}
@ -520,7 +526,6 @@ public class ImportOfficeTables extends ContextBasedTest {
final var person = HsOfficePersonEntity.builder()
.personType(HsOfficePersonType.UNKNOWN) // TODO
.build();
// persons.put(rec.getInteger("bp_id"), person);
persons.put(personId++, person);
final var partner = HsOfficePartnerEntity.builder()
@ -684,6 +689,7 @@ public class ImportOfficeTables extends ContextBasedTest {
final var person = partner.getPerson();
person.setTradeName(rec.getString("firma"));
determinePersonType(person);
// TODO: title+salutation: add to person
person.setGivenName(rec.getString("first_name"));
person.setFamilyName(rec.getString("last_name"));
@ -734,6 +740,14 @@ public class ImportOfficeTables extends ContextBasedTest {
});
}
private void determinePersonType(final HsOfficePersonEntity person) {
if (person.getTradeName().isBlank()) {
person.setPersonType(HsOfficePersonType.NATURAL);
} else {
person.setPersonType(HsOfficePersonType.LEGAL); // TODO: add rules if we distinguish
}
}
private HsOfficeContactEntity initContact(final HsOfficeContactEntity contact, final Record rec) {
contacts.put(rec.getInteger("contact_id"), contact);
@ -916,3 +930,20 @@ class Record {
return null;
}
}
class OrderedDependedTestsExtension implements TestWatcher, BeforeEachCallback {
private static boolean previousTestsPassed = true;
public void testAborted(ExtensionContext context, Throwable cause) {
previousTestsPassed = false;
}
public void testFailed(ExtensionContext context, Throwable cause) {
previousTestsPassed = false;
}
@Override
public void beforeEach(final ExtensionContext extensionContext) throws Exception {
assumeThat(previousTestsPassed).isTrue();
}
}

View File

@ -21,7 +21,8 @@ class HsOfficePartnerDetailsEntityUnitTest {
final var result = given.toString();
assertThat(result).isEqualTo("partnerDetails(Hamburg, 12345, 2002-01-15, 2002-01-15, 2081-12-21)");
assertThat(result).isEqualTo(
"partnerDetails(Hamburg, 12345, 2002-01-15, Melly Miller, 2081-12-21)");
}
@Test

View File

@ -2,6 +2,7 @@ package net.hostsharing.hsadminng.hs.office.partner;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
@ -11,24 +12,30 @@ class HsOfficePartnerEntityUnitTest {
@Test
void toStringContainsPersonAndContact() {
final var given = HsOfficePartnerEntity.builder()
.person(HsOfficePersonEntity.builder().tradeName("some trade name").build())
.person(HsOfficePersonEntity.builder()
.personType(HsOfficePersonType.LEGAL)
.tradeName("some trade name")
.build())
.contact(HsOfficeContactEntity.builder().label("some label").build())
.build();
final var result = given.toString();
assertThat(result).isEqualTo("partner(some trade name: some label)");
assertThat(result).isEqualTo("partner(LEGAL some trade name: some label)");
}
@Test
void toShortStringContainsPersonAndContact() {
final var given = HsOfficePartnerEntity.builder()
.person(HsOfficePersonEntity.builder().tradeName("some trade name").build())
.person(HsOfficePersonEntity.builder()
.personType(HsOfficePersonType.LEGAL)
.tradeName("some trade name")
.build())
.contact(HsOfficeContactEntity.builder().label("some label").build())
.build();
final var result = given.toShortString();
assertThat(result).isEqualTo("some trade name");
assertThat(result).isEqualTo("LEGAL some trade name");
}
}

View File

@ -177,9 +177,9 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
// then
allThesePartnersAreReturned(
result,
"partner(Third OHG: third contact)",
"partner(Second e.K.: second contact)",
"partner(First GmbH: first contact)");
"partner(SOLE_REPRESENTATION Third OHG: third contact)",
"partner(LEGAL Second e.K.: second contact)",
"partner(LEGAL First GmbH: first contact)");
}
@Test
@ -191,7 +191,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
final var result = partnerRepo.findPartnerByOptionalNameLike(null);
// then:
exactlyThesePartnersAreReturned(result, "partner(First GmbH: first contact)");
exactlyThesePartnersAreReturned(result, "partner(LEGAL First GmbH: first contact)");
}
}
@ -207,7 +207,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest {
final var result = partnerRepo.findPartnerByOptionalNameLike("third contact");
// then
exactlyThesePartnersAreReturned(result, "partner(Third OHG: third contact)");
exactlyThesePartnersAreReturned(result, "partner(SOLE_REPRESENTATION Third OHG: third contact)");
}
}

View File

@ -11,29 +11,32 @@ class HsOfficePersonEntityUnitTest {
@Test
void getDisplayReturnsTradeNameIfAvailable() {
final var givenPersonEntity = HsOfficePersonEntity.builder()
.personType(HsOfficePersonType.LEGAL)
.tradeName("some trade name")
.build();
final var actualDisplay = givenPersonEntity.toShortString();
assertThat(actualDisplay).isEqualTo("some trade name");
assertThat(actualDisplay).isEqualTo("LEGAL some trade name");
}
@Test
void getDisplayReturnsFamilyAndGivenNameIfNoTradeNameAvailable() {
final var givenPersonEntity = HsOfficePersonEntity.builder()
.personType(HsOfficePersonType.NATURAL)
.familyName("some family name")
.givenName("some given name")
.build();
final var actualDisplay = givenPersonEntity.toShortString();
assertThat(actualDisplay).isEqualTo("some family name, some given name");
assertThat(actualDisplay).isEqualTo("NATURAL some family name, some given name");
}
@Test
void toShortStringWithTradeNameReturnsTradeName() {
final var givenPersonEntity = HsOfficePersonEntity.builder()
.personType(HsOfficePersonType.LEGAL)
.tradeName("some trade name")
.familyName("some family name")
.givenName("some given name")
@ -41,19 +44,20 @@ class HsOfficePersonEntityUnitTest {
final var actualDisplay = givenPersonEntity.toShortString();
assertThat(actualDisplay).isEqualTo("some trade name");
assertThat(actualDisplay).isEqualTo("LEGAL some trade name");
}
@Test
void toShortStringWithoutTradeNameReturnsFamilyAndGivenName() {
final var givenPersonEntity = HsOfficePersonEntity.builder()
.personType(HsOfficePersonType.NATURAL)
.familyName("some family name")
.givenName("some given name")
.build();
final var actualDisplay = givenPersonEntity.toShortString();
assertThat(actualDisplay).isEqualTo("some family name, some given name");
assertThat(actualDisplay).isEqualTo("NATURAL some family name, some given name");
}
@Test

View File

@ -144,10 +144,10 @@ class HsOfficePersonRepositoryIntegrationTest extends ContextBasedTest {
// then
allThesePersonsAreReturned(
result,
"Smith, Peter",
"Second e.K.",
"Third OHG",
"Erben Bessler");
"NATURAL Smith, Peter",
"LEGAL Second e.K.",
"SOLE_REPRESENTATION Third OHG",
"JOINT_REPRESENTATION Erben Bessler");
}
@Test

View File

@ -159,9 +159,9 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTest {
// then
allTheseRelationshipsAreReturned(
result,
"rel(relAnchor='First GmbH', relType='REPRESENTATIVE', relHolder='Smith, Peter', contact='first contact')",
"rel(relAnchor='Third OHG', relType='REPRESENTATIVE', relHolder='Smith, Peter', contact='third contact')",
"rel(relAnchor='Second e.K.', relType='REPRESENTATIVE', relHolder='Smith, Peter', contact='second contact')");
"rel(relAnchor='LEGAL First GmbH', relType='REPRESENTATIVE', relHolder='NATURAL Smith, Peter', contact='first contact')",
"rel(relAnchor='SOLE_REPRESENTATION Third OHG', relType='REPRESENTATIVE', relHolder='NATURAL Smith, Peter', contact='third contact')",
"rel(relAnchor='LEGAL Second e.K.', relType='REPRESENTATIVE', relHolder='NATURAL Smith, Peter', contact='second contact')");
}
@Test
@ -176,7 +176,7 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTest {
// then:
exactlyTheseRelationshipsAreReturned(
result,
"rel(relAnchor='First GmbH', relType='REPRESENTATIVE', relHolder='Smith, Peter', contact='first contact')");
"rel(relAnchor='LEGAL First GmbH', relType='REPRESENTATIVE', relHolder='NATURAL Smith, Peter', contact='first contact')");
}
}

View File

@ -376,7 +376,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest {
context.define("superuser-alex@hostsharing.net");
assertThat(sepaMandateRepo.findByUuid(givenSepaMandate.getUuid())).isPresent().get()
.matches(mandate -> {
assertThat(mandate.getDebitor().toString()).isEqualTo("debitor(1000111: First GmbH: fir)");
assertThat(mandate.getDebitor().toString()).isEqualTo("debitor(1000111: LEGAL First GmbH: fir)");
assertThat(mandate.getBankAccount().toShortString()).isEqualTo("First GmbH");
assertThat(mandate.getReference()).isEqualTo("temp ref CAT Z - patched");
assertThat(mandate.getValidFrom()).isEqualTo("2020-06-05");
@ -417,7 +417,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest {
// finally, the sepaMandate is actually updated
assertThat(sepaMandateRepo.findByUuid(givenSepaMandate.getUuid())).isPresent().get()
.matches(mandate -> {
assertThat(mandate.getDebitor().toString()).isEqualTo("debitor(1000111: First GmbH: fir)");
assertThat(mandate.getDebitor().toString()).isEqualTo("debitor(1000111: LEGAL First GmbH: fir)");
assertThat(mandate.getBankAccount().toShortString()).isEqualTo("First GmbH");
assertThat(mandate.getReference()).isEqualTo("temp ref CAT Z");
assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,2023-01-01)");