implements HsOfficePersonController
This commit is contained in:
		| @@ -0,0 +1,118 @@ | |||||||
|  | package net.hostsharing.hsadminng.hs.office.person; | ||||||
|  |  | ||||||
|  | import net.hostsharing.hsadminng.Mapper; | ||||||
|  | import net.hostsharing.hsadminng.context.Context; | ||||||
|  | import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficePersonsApi; | ||||||
|  | import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePersonInsertResource; | ||||||
|  | import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePersonPatchResource; | ||||||
|  | import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePersonResource; | ||||||
|  | import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntityPatch; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.http.ResponseEntity; | ||||||
|  | import org.springframework.transaction.annotation.Transactional; | ||||||
|  | import org.springframework.web.bind.annotation.RestController; | ||||||
|  | import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.UUID; | ||||||
|  |  | ||||||
|  | import static net.hostsharing.hsadminng.Mapper.map; | ||||||
|  |  | ||||||
|  | @RestController | ||||||
|  |  | ||||||
|  | public class HsOfficePersonController implements HsOfficePersonsApi { | ||||||
|  |  | ||||||
|  |     @Autowired | ||||||
|  |     private Context context; | ||||||
|  |  | ||||||
|  |     @Autowired | ||||||
|  |     private HsOfficePersonRepository personRepo; | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     @Transactional(readOnly = true) | ||||||
|  |     public ResponseEntity<List<HsOfficePersonResource>> listPersons( | ||||||
|  |             final String currentUser, | ||||||
|  |             final String assumedRoles, | ||||||
|  |             final String label) { | ||||||
|  |         context.define(currentUser, assumedRoles); | ||||||
|  |  | ||||||
|  |         final var entities = personRepo.findPersonByOptionalNameLike(label); | ||||||
|  |  | ||||||
|  |         final var resources = Mapper.mapList(entities, HsOfficePersonResource.class); | ||||||
|  |         return ResponseEntity.ok(resources); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     @Transactional | ||||||
|  |     public ResponseEntity<HsOfficePersonResource> addPerson( | ||||||
|  |             final String currentUser, | ||||||
|  |             final String assumedRoles, | ||||||
|  |             final HsOfficePersonInsertResource body) { | ||||||
|  |  | ||||||
|  |         context.define(currentUser, assumedRoles); | ||||||
|  |  | ||||||
|  |         final var entityToSave = map(body, HsOfficePersonEntity.class); | ||||||
|  |         entityToSave.setUuid(UUID.randomUUID()); | ||||||
|  |  | ||||||
|  |         final var saved = personRepo.save(entityToSave); | ||||||
|  |  | ||||||
|  |         final var uri = | ||||||
|  |                 MvcUriComponentsBuilder.fromController(getClass()) | ||||||
|  |                         .path("/api/hs/office/persons/{id}") | ||||||
|  |                         .buildAndExpand(entityToSave.getUuid()) | ||||||
|  |                         .toUri(); | ||||||
|  |         final var mapped = map(saved, HsOfficePersonResource.class); | ||||||
|  |         return ResponseEntity.created(uri).body(mapped); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     @Transactional(readOnly = true) | ||||||
|  |     public ResponseEntity<HsOfficePersonResource> getPersonByUuid( | ||||||
|  |             final String currentUser, | ||||||
|  |             final String assumedRoles, | ||||||
|  |             final UUID personUuid) { | ||||||
|  |  | ||||||
|  |         context.define(currentUser, assumedRoles); | ||||||
|  |  | ||||||
|  |         final var result = personRepo.findByUuid(personUuid); | ||||||
|  |         if (result.isEmpty()) { | ||||||
|  |             return ResponseEntity.notFound().build(); | ||||||
|  |         } | ||||||
|  |         return ResponseEntity.ok(map(result.get(), HsOfficePersonResource.class)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     @Transactional | ||||||
|  |     public ResponseEntity<Void> deletePersonByUuid( | ||||||
|  |             final String currentUser, | ||||||
|  |             final String assumedRoles, | ||||||
|  |             final UUID personUuid) { | ||||||
|  |         context.define(currentUser, assumedRoles); | ||||||
|  |  | ||||||
|  |         final var result = personRepo.deleteByUuid(personUuid); | ||||||
|  |         if (result == 0) { | ||||||
|  |             return ResponseEntity.notFound().build(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return ResponseEntity.noContent().build(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     @Transactional | ||||||
|  |     public ResponseEntity<HsOfficePersonResource> patchPerson( | ||||||
|  |             final String currentUser, | ||||||
|  |             final String assumedRoles, | ||||||
|  |             final UUID personUuid, | ||||||
|  |             final HsOfficePersonPatchResource body) { | ||||||
|  |  | ||||||
|  |         context.define(currentUser, assumedRoles); | ||||||
|  |  | ||||||
|  |         final var current = personRepo.findByUuid(personUuid).orElseThrow(); | ||||||
|  |  | ||||||
|  |         new HsOfficePersonEntityPatch(current).apply(body); | ||||||
|  |  | ||||||
|  |         final var saved = personRepo.save(current); | ||||||
|  |         final var mapped = map(saved, HsOfficePersonResource.class); | ||||||
|  |         return ResponseEntity.ok(mapped); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,26 @@ | |||||||
|  | package net.hostsharing.hsadminng.hs.office.person; | ||||||
|  |  | ||||||
|  | import net.hostsharing.hsadminng.OptionalFromJson; | ||||||
|  | import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePersonPatchResource; | ||||||
|  | import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePersonTypeResource; | ||||||
|  |  | ||||||
|  | import java.util.Optional; | ||||||
|  |  | ||||||
|  | class HsOfficePersonEntityPatch { | ||||||
|  |  | ||||||
|  |     private final HsOfficePersonEntity entity; | ||||||
|  |  | ||||||
|  |     HsOfficePersonEntityPatch(final HsOfficePersonEntity entity) { | ||||||
|  |         this.entity = entity; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void apply(final HsOfficePersonPatchResource resource) { | ||||||
|  |         Optional.ofNullable(resource.getPersonType()) | ||||||
|  |                 .map(HsOfficePersonTypeResource::getValue) | ||||||
|  |                 .map(HsOfficePersonType::valueOf) | ||||||
|  |                 .ifPresent(entity::setPersonType); | ||||||
|  |         OptionalFromJson.of(resource.getTradeName()).ifPresent(entity::setTradeName); | ||||||
|  |         OptionalFromJson.of(resource.getFamilyName()).ifPresent(entity::setFamilyName); | ||||||
|  |         OptionalFromJson.of(resource.getGivenName()).ifPresent(entity::setGivenName); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -16,3 +16,5 @@ map: | |||||||
|             null: org.openapitools.jackson.nullable.JsonNullable |             null: org.openapitools.jackson.nullable.JsonNullable | ||||||
|         /api/hs/office/contacts/{contactUUID}: |         /api/hs/office/contacts/{contactUUID}: | ||||||
|             null: org.openapitools.jackson.nullable.JsonNullable |             null: org.openapitools.jackson.nullable.JsonNullable | ||||||
|  |         /api/hs/office/persons/{personUUID}: | ||||||
|  |             null: org.openapitools.jackson.nullable.JsonNullable | ||||||
|   | |||||||
| @@ -3,16 +3,28 @@ components: | |||||||
|  |  | ||||||
|     schemas: |     schemas: | ||||||
|  |  | ||||||
|         HsOfficePersonBase: |         HsOfficePersonTypeValues: | ||||||
|             type: object |             - NATURAL               # a human | ||||||
|             properties: |             - LEGAL                 # e.g. Corp., Inc., AG, GmbH, eG | ||||||
|                 personType: |             - SOLE_REPRESENTATION   # e.g. OHG, GbR | ||||||
|  |             - JOINT_REPRESENTATION  # e.g. community of heirs | ||||||
|  |  | ||||||
|  |         HsOfficePersonType: | ||||||
|             type: string |             type: string | ||||||
|             enum: |             enum: | ||||||
|                 - NATURAL               # a human |                 - NATURAL               # a human | ||||||
|                 - LEGAL                 # e.g. Corp., Inc., AG, GmbH, eG |                 - LEGAL                 # e.g. Corp., Inc., AG, GmbH, eG | ||||||
|                 - SOLE_REPRESENTATION   # e.g. OHG, GbR |                 - SOLE_REPRESENTATION   # e.g. OHG, GbR | ||||||
|                 - JOINT_REPRESENTATION  # e.g. community of heirs |                 - JOINT_REPRESENTATION  # e.g. community of heirs | ||||||
|  |  | ||||||
|  |         HsOfficePerson: | ||||||
|  |             type: object | ||||||
|  |             properties: | ||||||
|  |                 uuid: | ||||||
|  |                     type: string | ||||||
|  |                     format: uuid | ||||||
|  |                 personType: | ||||||
|  |                     $ref: '#/components/schemas/HsOfficePersonType' | ||||||
|                 tradeName: |                 tradeName: | ||||||
|                     type: string |                     type: string | ||||||
|                 givenName: |                 givenName: | ||||||
| @@ -20,14 +32,32 @@ components: | |||||||
|                 familyName: |                 familyName: | ||||||
|                     type: string |                     type: string | ||||||
|  |  | ||||||
|         HsOfficePerson: |         HsOfficePersonInsert: | ||||||
|             allOf: |             type: object | ||||||
|                 - type: object |  | ||||||
|             properties: |             properties: | ||||||
|                       uuid: |                 personType: | ||||||
|  |                     $ref: '#/components/schemas/HsOfficePersonType' | ||||||
|  |                 tradeName: | ||||||
|                     type: string |                     type: string | ||||||
|                           format: uuid |                 givenName: | ||||||
|                 - $ref: '#/components/schemas/HsOfficePersonBase' |                     type: string | ||||||
|  |                 familyName: | ||||||
|  |                     type: string | ||||||
|  |             required: | ||||||
|  |                 - personType | ||||||
|  |  | ||||||
|         HsOfficePersonUpdate: |         HsOfficePersonPatch: | ||||||
|             $ref: '#/components/schemas/HsOfficePersonBase' |             type: object | ||||||
|  |             properties: | ||||||
|  |                 personType: | ||||||
|  |                     nullable: true | ||||||
|  |                     $ref: '#/components/schemas/HsOfficePersonType' | ||||||
|  |                 tradeName: | ||||||
|  |                     type: string | ||||||
|  |                     nullable: true | ||||||
|  |                 givenName: | ||||||
|  |                     type: string | ||||||
|  |                     nullable: true | ||||||
|  |                 familyName: | ||||||
|  |                     type: string | ||||||
|  |                     nullable: true | ||||||
|   | |||||||
| @@ -0,0 +1,83 @@ | |||||||
|  | get: | ||||||
|  |     tags: | ||||||
|  |         - hs-office-persons | ||||||
|  |     description: 'Fetch a single business person by its uuid, if visible for the current subject.' | ||||||
|  |     operationId: getPersonByUuid | ||||||
|  |     parameters: | ||||||
|  |         - $ref: './auth.yaml#/components/parameters/currentUser' | ||||||
|  |         - $ref: './auth.yaml#/components/parameters/assumedRoles' | ||||||
|  |         - name: personUUID | ||||||
|  |           in: path | ||||||
|  |           required: true | ||||||
|  |           schema: | ||||||
|  |               type: string | ||||||
|  |               format: uuid | ||||||
|  |           description: UUID of the person to fetch. | ||||||
|  |     responses: | ||||||
|  |         "200": | ||||||
|  |             description: OK | ||||||
|  |             content: | ||||||
|  |                 'application/json': | ||||||
|  |                     schema: | ||||||
|  |                         $ref: './hs-office-person-schemas.yaml#/components/schemas/HsOfficePerson' | ||||||
|  |  | ||||||
|  |         "401": | ||||||
|  |             $ref: './error-responses.yaml#/components/responses/Unauthorized' | ||||||
|  |         "403": | ||||||
|  |             $ref: './error-responses.yaml#/components/responses/Forbidden' | ||||||
|  |  | ||||||
|  | patch: | ||||||
|  |     tags: | ||||||
|  |         - hs-office-persons | ||||||
|  |     description: 'Updates a single person by its uuid, if permitted for the current subject.' | ||||||
|  |     operationId: patchPerson | ||||||
|  |     parameters: | ||||||
|  |         -   $ref: './auth.yaml#/components/parameters/currentUser' | ||||||
|  |         -   $ref: './auth.yaml#/components/parameters/assumedRoles' | ||||||
|  |         -   name: personUUID | ||||||
|  |             in: path | ||||||
|  |             required: true | ||||||
|  |             schema: | ||||||
|  |                 type: string | ||||||
|  |                 format: uuid | ||||||
|  |     requestBody: | ||||||
|  |         content: | ||||||
|  |             'application/json': | ||||||
|  |                 schema: | ||||||
|  |                     $ref: './hs-office-person-schemas.yaml#/components/schemas/HsOfficePersonPatch' | ||||||
|  |     responses: | ||||||
|  |         "200": | ||||||
|  |             description: OK | ||||||
|  |             content: | ||||||
|  |                 'application/json': | ||||||
|  |                     schema: | ||||||
|  |                         $ref: './hs-office-person-schemas.yaml#/components/schemas/HsOfficePerson' | ||||||
|  |         "401": | ||||||
|  |             $ref: './error-responses.yaml#/components/responses/Unauthorized' | ||||||
|  |         "403": | ||||||
|  |             $ref: './error-responses.yaml#/components/responses/Forbidden' | ||||||
|  |  | ||||||
|  | delete: | ||||||
|  |     tags: | ||||||
|  |         - hs-office-persons | ||||||
|  |     description: 'Delete a single business person by its uuid, if permitted for the current subject.' | ||||||
|  |     operationId: deletePersonByUuid | ||||||
|  |     parameters: | ||||||
|  |         - $ref: './auth.yaml#/components/parameters/currentUser' | ||||||
|  |         - $ref: './auth.yaml#/components/parameters/assumedRoles' | ||||||
|  |         - name: personUUID | ||||||
|  |           in: path | ||||||
|  |           required: true | ||||||
|  |           schema: | ||||||
|  |               type: string | ||||||
|  |               format: uuid | ||||||
|  |           description: UUID of the person to delete. | ||||||
|  |     responses: | ||||||
|  |         "204": | ||||||
|  |             description: No Content | ||||||
|  |         "401": | ||||||
|  |             $ref: './error-responses.yaml#/components/responses/Unauthorized' | ||||||
|  |         "403": | ||||||
|  |             $ref: './error-responses.yaml#/components/responses/Forbidden' | ||||||
|  |         "404": | ||||||
|  |             $ref: './error-responses.yaml#/components/responses/NotFound' | ||||||
| @@ -0,0 +1,56 @@ | |||||||
|  | get: | ||||||
|  |     summary: Returns a list of (optionally filtered) persons. | ||||||
|  |     description: Returns the list of (optionally filtered) persons which are visible to the current user or any of it's assumed roles. | ||||||
|  |     tags: | ||||||
|  |         - hs-office-persons | ||||||
|  |     operationId: listPersons | ||||||
|  |     parameters: | ||||||
|  |         - $ref: './auth.yaml#/components/parameters/currentUser' | ||||||
|  |         - $ref: './auth.yaml#/components/parameters/assumedRoles' | ||||||
|  |         - name: name | ||||||
|  |           in: query | ||||||
|  |           required: false | ||||||
|  |           schema: | ||||||
|  |               type: string | ||||||
|  |           description: Prefix of label to filter the results. | ||||||
|  |     responses: | ||||||
|  |         "200": | ||||||
|  |             description: OK | ||||||
|  |             content: | ||||||
|  |                 'application/json': | ||||||
|  |                     schema: | ||||||
|  |                         type: array | ||||||
|  |                         items: | ||||||
|  |                             $ref: './hs-office-person-schemas.yaml#/components/schemas/HsOfficePerson' | ||||||
|  |         "401": | ||||||
|  |             $ref: './error-responses.yaml#/components/responses/Unauthorized' | ||||||
|  |         "403": | ||||||
|  |             $ref: './error-responses.yaml#/components/responses/Forbidden' | ||||||
|  |  | ||||||
|  | post: | ||||||
|  |     summary: Adds a new person. | ||||||
|  |     tags: | ||||||
|  |         - hs-office-persons | ||||||
|  |     operationId: addPerson | ||||||
|  |     parameters: | ||||||
|  |         - $ref: './auth.yaml#/components/parameters/currentUser' | ||||||
|  |         - $ref: './auth.yaml#/components/parameters/assumedRoles' | ||||||
|  |     requestBody: | ||||||
|  |         content: | ||||||
|  |             'application/json': | ||||||
|  |                 schema: | ||||||
|  |                     $ref: './hs-office-person-schemas.yaml#/components/schemas/HsOfficePersonInsert' | ||||||
|  |         required: true | ||||||
|  |     responses: | ||||||
|  |         "201": | ||||||
|  |             description: Created | ||||||
|  |             content: | ||||||
|  |                 'application/json': | ||||||
|  |                     schema: | ||||||
|  |                         $ref: './hs-office-person-schemas.yaml#/components/schemas/HsOfficePerson' | ||||||
|  |         "401": | ||||||
|  |             $ref: './error-responses.yaml#/components/responses/Unauthorized' | ||||||
|  |         "403": | ||||||
|  |             $ref: './error-responses.yaml#/components/responses/Forbidden' | ||||||
|  |         "409": | ||||||
|  |             $ref: './error-responses.yaml#/components/responses/Conflict' | ||||||
| @@ -25,3 +25,12 @@ paths: | |||||||
|   /api/hs/office/contacts/{contactUUID}: |   /api/hs/office/contacts/{contactUUID}: | ||||||
|     $ref: "./hs-office-contacts-with-uuid.yaml" |     $ref: "./hs-office-contacts-with-uuid.yaml" | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   # Persons | ||||||
|  |  | ||||||
|  |   /api/hs/office/persons: | ||||||
|  |     $ref: "./hs-office-persons.yaml" | ||||||
|  |  | ||||||
|  |   /api/hs/office/persons/{personUUID}: | ||||||
|  |     $ref: "./hs-office-persons-with-uuid.yaml" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -0,0 +1,401 @@ | |||||||
|  | package net.hostsharing.hsadminng.hs.office.person; | ||||||
|  |  | ||||||
|  | import io.restassured.RestAssured; | ||||||
|  | import io.restassured.http.ContentType; | ||||||
|  | import net.hostsharing.hsadminng.Accepts; | ||||||
|  | import net.hostsharing.hsadminng.HsadminNgApplication; | ||||||
|  | import net.hostsharing.hsadminng.context.Context; | ||||||
|  | import net.hostsharing.test.JpaAttempt; | ||||||
|  | import org.apache.commons.lang3.RandomStringUtils; | ||||||
|  | import org.json.JSONException; | ||||||
|  | import org.junit.jupiter.api.AfterEach; | ||||||
|  | import org.junit.jupiter.api.BeforeEach; | ||||||
|  | import org.junit.jupiter.api.Nested; | ||||||
|  | import org.junit.jupiter.api.Test; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.boot.test.context.SpringBootTest; | ||||||
|  | import org.springframework.boot.test.web.server.LocalServerPort; | ||||||
|  | import org.springframework.transaction.annotation.Transactional; | ||||||
|  |  | ||||||
|  | import java.util.HashSet; | ||||||
|  | import java.util.Set; | ||||||
|  | import java.util.UUID; | ||||||
|  |  | ||||||
|  | import static net.hostsharing.test.IsValidUuidMatcher.isUuidValid; | ||||||
|  | import static net.hostsharing.test.JsonMatcher.lenientlyEquals; | ||||||
|  | import static org.assertj.core.api.Assertions.assertThat; | ||||||
|  | import static org.hamcrest.Matchers.is; | ||||||
|  | import static org.hamcrest.Matchers.startsWith; | ||||||
|  |  | ||||||
|  | @SpringBootTest( | ||||||
|  |         webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, | ||||||
|  |         classes = { HsadminNgApplication.class, JpaAttempt.class } | ||||||
|  | ) | ||||||
|  | @Transactional | ||||||
|  | class HsOfficePersonControllerAcceptanceTest { | ||||||
|  |  | ||||||
|  |     @LocalServerPort | ||||||
|  |     private Integer port; | ||||||
|  |  | ||||||
|  |     @Autowired | ||||||
|  |     Context context; | ||||||
|  |  | ||||||
|  |     @Autowired | ||||||
|  |     Context contextMock; | ||||||
|  |  | ||||||
|  |     @Autowired | ||||||
|  |     HsOfficePersonRepository personRepo; | ||||||
|  |  | ||||||
|  |     @Autowired | ||||||
|  |     JpaAttempt jpaAttempt; | ||||||
|  |  | ||||||
|  |     Set<UUID> tempPersonUuids = new HashSet<>(); | ||||||
|  |  | ||||||
|  |     @Nested | ||||||
|  |     @Accepts({ "Person:F(Find)" }) | ||||||
|  |     class ListPersons { | ||||||
|  |  | ||||||
|  |         @Test | ||||||
|  |         void globalAdmin_withoutAssumedRoles_canViewAllPersons_ifNoCriteriaGiven() throws JSONException { | ||||||
|  |  | ||||||
|  |             RestAssured // @formatter:off | ||||||
|  |                 .given() | ||||||
|  |                     .header("current-user", "superuser-alex@hostsharing.net") | ||||||
|  |                     .port(port) | ||||||
|  |                 .when() | ||||||
|  |                     .get("http://localhost/api/hs/office/persons") | ||||||
|  |                 .then().log().all().assertThat() | ||||||
|  |                     .statusCode(200) | ||||||
|  |                     .contentType("application/json") | ||||||
|  |                     .body("", lenientlyEquals(""" | ||||||
|  |                         [ | ||||||
|  |                              { | ||||||
|  |                                  "personType": "JOINT_REPRESENTATION", | ||||||
|  |                                  "tradeName": "Erben Bessler", | ||||||
|  |                                  "givenName": "Bessler", | ||||||
|  |                                  "familyName": "Mel" | ||||||
|  |                              }, | ||||||
|  |                              { | ||||||
|  |                                  "personType": "LEGAL", | ||||||
|  |                                  "tradeName": "First Impressions GmbH", | ||||||
|  |                                  "givenName": null, | ||||||
|  |                                  "familyName": null | ||||||
|  |                              }, | ||||||
|  |                              { | ||||||
|  |                                  "personType": "SOLE_REPRESENTATION", | ||||||
|  |                                  "tradeName": "Ostfriesische Kuhhandel OHG", | ||||||
|  |                                  "givenName": null, | ||||||
|  |                                  "familyName": null | ||||||
|  |                              }, | ||||||
|  |                              { | ||||||
|  |                                  "personType": "NATURAL", | ||||||
|  |                                  "tradeName": null, | ||||||
|  |                                  "givenName": "Smith", | ||||||
|  |                                  "familyName": "Peter" | ||||||
|  |                              }, | ||||||
|  |                              { | ||||||
|  |                                  "personType": "LEGAL", | ||||||
|  |                                  "tradeName": "Rockshop e.K.", | ||||||
|  |                                  "givenName": "Miller", | ||||||
|  |                                  "familyName": "Sandra" | ||||||
|  |                              } | ||||||
|  |                          ] | ||||||
|  |                         """ | ||||||
|  |                             )); | ||||||
|  |                 // @formatter:on | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Nested | ||||||
|  |     @Accepts({ "Person:C(Create)" }) | ||||||
|  |     class AddPerson { | ||||||
|  |  | ||||||
|  |         @Test | ||||||
|  |         void globalAdmin_withoutAssumedRole_canAddPerson() { | ||||||
|  |  | ||||||
|  |             context.define("superuser-alex@hostsharing.net"); | ||||||
|  |  | ||||||
|  |             final var location = RestAssured // @formatter:off | ||||||
|  |                     .given() | ||||||
|  |                         .header("current-user", "superuser-alex@hostsharing.net") | ||||||
|  |                         .contentType(ContentType.JSON) | ||||||
|  |                         .body(""" | ||||||
|  |                                { | ||||||
|  |                                    "personType": "NATURAL", | ||||||
|  |                                    "familyName": "Tester", | ||||||
|  |                                    "givenName": "Testi" | ||||||
|  |                                  } | ||||||
|  |                             """) | ||||||
|  |                         .port(port) | ||||||
|  |                     .when() | ||||||
|  |                         .post("http://localhost/api/hs/office/persons") | ||||||
|  |                     .then().assertThat() | ||||||
|  |                         .statusCode(201) | ||||||
|  |                         .contentType(ContentType.JSON) | ||||||
|  |                         .body("uuid", isUuidValid()) | ||||||
|  |                         .body("personType", is("NATURAL")) | ||||||
|  |                         .body("familyName", is("Tester")) | ||||||
|  |                         .body("givenName", is("Testi")) | ||||||
|  |                         .header("Location", startsWith("http://localhost")) | ||||||
|  |                     .extract().header("Location");  // @formatter:on | ||||||
|  |  | ||||||
|  |             // finally, the new person can be accessed under the generated UUID | ||||||
|  |             final var newUserUuid = toCleanup(UUID.fromString( | ||||||
|  |                     location.substring(location.lastIndexOf('/') + 1))); | ||||||
|  |             assertThat(newUserUuid).isNotNull(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Nested | ||||||
|  |     @Accepts({ "Person:R(Read)" }) | ||||||
|  |     class GetPerson { | ||||||
|  |  | ||||||
|  |         @Test | ||||||
|  |         void globalAdmin_withoutAssumedRole_canGetArbitraryPerson() { | ||||||
|  |             context.define("superuser-alex@hostsharing.net"); | ||||||
|  |             final var givenPersonUuid = personRepo.findPersonByOptionalNameLike("Erben").get(0).getUuid(); | ||||||
|  |  | ||||||
|  |             RestAssured // @formatter:off | ||||||
|  |                 .given() | ||||||
|  |                     .header("current-user", "superuser-alex@hostsharing.net") | ||||||
|  |                     .port(port) | ||||||
|  |                 .when() | ||||||
|  |                     .get("http://localhost/api/hs/office/persons/" + givenPersonUuid) | ||||||
|  |                 .then().log().body().assertThat() | ||||||
|  |                     .statusCode(200) | ||||||
|  |                     .contentType("application/json") | ||||||
|  |                     .body("", lenientlyEquals(""" | ||||||
|  |                     { | ||||||
|  |                         "tradeName": "Erben Bessler" | ||||||
|  |                     } | ||||||
|  |                     """)); // @formatter:on | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Test | ||||||
|  |         @Accepts({ "Person:X(Access Control)" }) | ||||||
|  |         void normalUser_canNotGetUnrelatedPerson() { | ||||||
|  |             context.define("superuser-alex@hostsharing.net"); | ||||||
|  |             final var givenPersonUuid = personRepo.findPersonByOptionalNameLike("Erben").get(0).getUuid(); | ||||||
|  |  | ||||||
|  |             RestAssured // @formatter:off | ||||||
|  |                 .given() | ||||||
|  |                     .header("current-user", "selfregistered-user-drew@hostsharing.org") | ||||||
|  |                     .port(port) | ||||||
|  |                 .when() | ||||||
|  |                     .get("http://localhost/api/hs/office/persons/" + givenPersonUuid) | ||||||
|  |                 .then().log().body().assertThat() | ||||||
|  |                     .statusCode(404); // @formatter:on | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Test | ||||||
|  |         @Accepts({ "Person:X(Access Control)" }) | ||||||
|  |         void personOwnerUser_canGetRelatedPerson() { | ||||||
|  |             context.define("superuser-alex@hostsharing.net"); | ||||||
|  |             final var givenPersonUuid = personRepo.findPersonByOptionalNameLike("Erben").get(0).getUuid(); | ||||||
|  |  | ||||||
|  |             RestAssured // @formatter:off | ||||||
|  |                 .given() | ||||||
|  |                     .header("current-user", "person-ErbenBesslerMelBessler@example.com") | ||||||
|  |                     .port(port) | ||||||
|  |                 .when() | ||||||
|  |                     .get("http://localhost/api/hs/office/persons/" + givenPersonUuid) | ||||||
|  |                 .then().log().body().assertThat() | ||||||
|  |                     .statusCode(200) | ||||||
|  |                     .contentType("application/json") | ||||||
|  |                     .body("", lenientlyEquals(""" | ||||||
|  |                     { | ||||||
|  |                         "personType": "JOINT_REPRESENTATION", | ||||||
|  |                         "tradeName": "Erben Bessler", | ||||||
|  |                         "givenName": "Bessler", | ||||||
|  |                         "familyName": "Mel" | ||||||
|  |                      } | ||||||
|  |                     """)); // @formatter:on | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Nested | ||||||
|  |     @Accepts({ "Person:U(Update)" }) | ||||||
|  |     class PatchPerson { | ||||||
|  |  | ||||||
|  |         @Test | ||||||
|  |         void globalAdmin_withoutAssumedRole_canPatchAllPropertiesOfArbitraryPerson() { | ||||||
|  |  | ||||||
|  |             context.define("superuser-alex@hostsharing.net"); | ||||||
|  |             final var givenPerson = givenSomeTemporaryPersonCreatedBy("selfregistered-test-user@hostsharing.org"); | ||||||
|  |  | ||||||
|  |             final var location = RestAssured // @formatter:off | ||||||
|  |                 .given() | ||||||
|  |                     .header("current-user", "superuser-alex@hostsharing.net") | ||||||
|  |                     .contentType(ContentType.JSON) | ||||||
|  |                     .body(""" | ||||||
|  |                        { | ||||||
|  |                            "personType": "JOINT_REPRESENTATION", | ||||||
|  |                            "tradeName": "Patched Trade Name", | ||||||
|  |                            "familyName": "Patched Family Name", | ||||||
|  |                            "givenName": "Patched Given Name" | ||||||
|  |                        } | ||||||
|  |                        """) | ||||||
|  |                     .port(port) | ||||||
|  |                 .when() | ||||||
|  |                     .patch("http://localhost/api/hs/office/persons/" + givenPerson.getUuid()) | ||||||
|  |                 .then().assertThat() | ||||||
|  |                     .statusCode(200) | ||||||
|  |                     .contentType(ContentType.JSON) | ||||||
|  |                     .body("uuid", isUuidValid()) | ||||||
|  |                     .body("personType", is("JOINT_REPRESENTATION")) | ||||||
|  |                     .body("tradeName", is("Patched Trade Name")) | ||||||
|  |                     .body("familyName", is("Patched Family Name")) | ||||||
|  |                     .body("givenName", is("Patched Given Name")); | ||||||
|  |                 // @formatter:on | ||||||
|  |  | ||||||
|  |             // finally, the person is actually updated | ||||||
|  |             context.define("superuser-alex@hostsharing.net"); | ||||||
|  |             assertThat(personRepo.findByUuid(givenPerson.getUuid())).isPresent().get() | ||||||
|  |                     .matches(person -> { | ||||||
|  |                         assertThat(person.getPersonType()).isEqualTo(HsOfficePersonType.JOINT_REPRESENTATION); | ||||||
|  |                         assertThat(person.getTradeName()).isEqualTo("Patched Trade Name"); | ||||||
|  |                         assertThat(person.getFamilyName()).isEqualTo("Patched Family Name"); | ||||||
|  |                         assertThat(person.getGivenName()).isEqualTo("Patched Given Name"); | ||||||
|  |                         return true; | ||||||
|  |                     }); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Test | ||||||
|  |         void globalAdmin_withoutAssumedRole_canPatchPartialPropertiesOfArbitraryPerson() { | ||||||
|  |  | ||||||
|  |             context.define("superuser-alex@hostsharing.net"); | ||||||
|  |             final var givenPerson = givenSomeTemporaryPersonCreatedBy("selfregistered-test-user@hostsharing.org"); | ||||||
|  |  | ||||||
|  |             final var location = RestAssured // @formatter:off | ||||||
|  |                 .given() | ||||||
|  |                     .header("current-user", "superuser-alex@hostsharing.net") | ||||||
|  |                     .contentType(ContentType.JSON) | ||||||
|  |                     .body(""" | ||||||
|  |                         { | ||||||
|  |                             "familyName": "Patched Family Name", | ||||||
|  |                             "givenName": "Patched Given Name" | ||||||
|  |                         } | ||||||
|  |                         """) | ||||||
|  |                     .port(port) | ||||||
|  |                 .when() | ||||||
|  |                     .patch("http://localhost/api/hs/office/persons/" + givenPerson.getUuid()) | ||||||
|  |                 .then().assertThat() | ||||||
|  |                     .statusCode(200) | ||||||
|  |                     .contentType(ContentType.JSON) | ||||||
|  |                     .body("uuid", isUuidValid()) | ||||||
|  |                     .body("personType", is(givenPerson.getPersonType().toString())) | ||||||
|  |                     .body("tradeName", is(givenPerson.getTradeName())) | ||||||
|  |                     .body("familyName", is("Patched Family Name")) | ||||||
|  |                     .body("givenName", is("Patched Given Name")); | ||||||
|  |             // @formatter:on | ||||||
|  |  | ||||||
|  |             // finally, the person is actually updated | ||||||
|  |             assertThat(personRepo.findByUuid(givenPerson.getUuid())).isPresent().get() | ||||||
|  |                     .matches(person -> { | ||||||
|  |                         assertThat(person.getPersonType()).isEqualTo(givenPerson.getPersonType()); | ||||||
|  |                         assertThat(person.getTradeName()).isEqualTo(givenPerson.getTradeName()); | ||||||
|  |                         assertThat(person.getFamilyName()).isEqualTo("Patched Family Name"); | ||||||
|  |                         assertThat(person.getGivenName()).isEqualTo("Patched Given Name"); | ||||||
|  |                         return true; | ||||||
|  |                     }); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Nested | ||||||
|  |     @Accepts({ "Person:D(Delete)" }) | ||||||
|  |     class DeletePerson { | ||||||
|  |  | ||||||
|  |         @Test | ||||||
|  |         void globalAdmin_withoutAssumedRole_canDeleteArbitraryPerson() { | ||||||
|  |             context.define("superuser-alex@hostsharing.net"); | ||||||
|  |             final var givenPerson = givenSomeTemporaryPersonCreatedBy("selfregistered-test-user@hostsharing.org"); | ||||||
|  |  | ||||||
|  |             RestAssured // @formatter:off | ||||||
|  |                 .given() | ||||||
|  |                     .header("current-user", "superuser-alex@hostsharing.net") | ||||||
|  |                     .port(port) | ||||||
|  |                 .when() | ||||||
|  |                     .delete("http://localhost/api/hs/office/persons/" + givenPerson.getUuid()) | ||||||
|  |                 .then().log().body().assertThat() | ||||||
|  |                     .statusCode(204); // @formatter:on | ||||||
|  |  | ||||||
|  |             // then the given person is gone | ||||||
|  |             assertThat(personRepo.findByUuid(givenPerson.getUuid())).isEmpty(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Test | ||||||
|  |         @Accepts({ "Person:X(Access Control)" }) | ||||||
|  |         void personOwner_canDeleteRelatedPerson() { | ||||||
|  |             final var givenPerson = givenSomeTemporaryPersonCreatedBy("selfregistered-test-user@hostsharing.org"); | ||||||
|  |  | ||||||
|  |             RestAssured // @formatter:off | ||||||
|  |                 .given() | ||||||
|  |                     .header("current-user", "selfregistered-test-user@hostsharing.org") | ||||||
|  |                     .port(port) | ||||||
|  |                 .when() | ||||||
|  |                     .delete("http://localhost/api/hs/office/persons/" + givenPerson.getUuid()) | ||||||
|  |                 .then().log().body().assertThat() | ||||||
|  |                     .statusCode(204); // @formatter:on | ||||||
|  |  | ||||||
|  |             // then the given person is still there | ||||||
|  |             assertThat(personRepo.findByUuid(givenPerson.getUuid())).isEmpty(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Test | ||||||
|  |         @Accepts({ "Person:X(Access Control)" }) | ||||||
|  |         void normalUser_canNotDeleteUnrelatedPerson() { | ||||||
|  |             context.define("superuser-alex@hostsharing.net"); | ||||||
|  |             final var givenPerson = givenSomeTemporaryPersonCreatedBy("selfregistered-test-user@hostsharing.org"); | ||||||
|  |  | ||||||
|  |             RestAssured // @formatter:off | ||||||
|  |                 .given() | ||||||
|  |                     .header("current-user", "selfregistered-user-drew@hostsharing.org") | ||||||
|  |                     .port(port) | ||||||
|  |                 .when() | ||||||
|  |                     .delete("http://localhost/api/hs/office/persons/" + givenPerson.getUuid()) | ||||||
|  |                 .then().log().body().assertThat() | ||||||
|  |                     .statusCode(404); // unrelated user cannot even view the person | ||||||
|  |             // @formatter:on | ||||||
|  |  | ||||||
|  |             // then the given person is still there | ||||||
|  |             assertThat(personRepo.findByUuid(givenPerson.getUuid())).isNotEmpty(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private HsOfficePersonEntity givenSomeTemporaryPersonCreatedBy(final String creatingUser) { | ||||||
|  |         return jpaAttempt.transacted(() -> { | ||||||
|  |             context.define(creatingUser); | ||||||
|  |             final var newPerson = HsOfficePersonEntity.builder() | ||||||
|  |                     .uuid(UUID.randomUUID()) | ||||||
|  |                     .personType(HsOfficePersonType.LEGAL) | ||||||
|  |                     .tradeName("Temp " + Context.getCallerMethodNameFromStackFrame(2)) | ||||||
|  |                     .familyName(RandomStringUtils.randomAlphabetic(10) + "@example.org") | ||||||
|  |                     .givenName("Given Name " + RandomStringUtils.randomAlphabetic(10)) | ||||||
|  |                     .build(); | ||||||
|  |  | ||||||
|  |             toCleanup(newPerson.getUuid()); | ||||||
|  |  | ||||||
|  |             return personRepo.save(newPerson); | ||||||
|  |         }).assertSuccessful().returnedValue(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private UUID toCleanup(final UUID tempPersonUuid) { | ||||||
|  |         tempPersonUuids.add(tempPersonUuid); | ||||||
|  |         return tempPersonUuid; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @BeforeEach | ||||||
|  |     @AfterEach | ||||||
|  |     void cleanup() { | ||||||
|  |         tempPersonUuids.forEach(uuid -> { | ||||||
|  |             jpaAttempt.transacted(() -> { | ||||||
|  |                 context.define("superuser-alex@hostsharing.net", null); | ||||||
|  |                 System.out.println("DELETING temporary person: " + uuid); | ||||||
|  |                 final var entity = personRepo.findByUuid(uuid); | ||||||
|  |                 final var count = personRepo.deleteByUuid(uuid); | ||||||
|  |                 System.out.println("DELETED temporary person: " + uuid + (count > 0 ? " successful" : " failed") + | ||||||
|  |                         (" (" + entity.map(HsOfficePersonEntity::getDisplayName).orElse("null") + ")")); | ||||||
|  |             }).assertSuccessful(); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,153 @@ | |||||||
|  | package net.hostsharing.hsadminng.hs.office.person; | ||||||
|  |  | ||||||
|  | import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePersonPatchResource; | ||||||
|  | import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePersonTypeResource; | ||||||
|  | import org.junit.jupiter.api.Test; | ||||||
|  | import org.junit.jupiter.params.ParameterizedTest; | ||||||
|  | import org.junit.jupiter.params.provider.EnumSource; | ||||||
|  | import org.junit.jupiter.params.provider.NullSource; | ||||||
|  | import org.junit.jupiter.params.provider.ValueSource; | ||||||
|  | import org.openapitools.jackson.nullable.JsonNullable; | ||||||
|  |  | ||||||
|  | import java.util.UUID; | ||||||
|  |  | ||||||
|  | import static org.assertj.core.api.Assertions.assertThat; | ||||||
|  |  | ||||||
|  | // TODO: there must be an easier way to test such patch classes | ||||||
|  | class HsOfficePersonEntityPatchUnitTest { | ||||||
|  |  | ||||||
|  |     private static final UUID INITIAL_PERSON_UUID = UUID.randomUUID(); | ||||||
|  |     final HsOfficePersonEntity givenPerson = new HsOfficePersonEntity(); | ||||||
|  |     final HsOfficePersonPatchResource patchResource = new HsOfficePersonPatchResource(); | ||||||
|  |  | ||||||
|  |     private final HsOfficePersonEntityPatch hsOfficePersonEntityPatch = | ||||||
|  |             new HsOfficePersonEntityPatch(givenPerson); | ||||||
|  |  | ||||||
|  |     { | ||||||
|  |         givenPerson.setUuid(INITIAL_PERSON_UUID); | ||||||
|  |         givenPerson.setPersonType(HsOfficePersonType.LEGAL); | ||||||
|  |         givenPerson.setTradeName("initial@example.org"); | ||||||
|  |         givenPerson.setFamilyName("initial postal address"); | ||||||
|  |         givenPerson.setGivenName("+01 100 123456789"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void willPatchAllProperties() { | ||||||
|  |         // given | ||||||
|  |         patchResource.setPersonType(HsOfficePersonTypeResource.NATURAL); | ||||||
|  |         patchResource.setTradeName(JsonNullable.of("patched@example.org")); | ||||||
|  |         patchResource.setFamilyName(JsonNullable.of("patched postal address")); | ||||||
|  |         patchResource.setGivenName(JsonNullable.of("+01 200 987654321")); | ||||||
|  |  | ||||||
|  |         // when | ||||||
|  |         hsOfficePersonEntityPatch.apply(patchResource); | ||||||
|  |  | ||||||
|  |         // then | ||||||
|  |         new HsOfficePersonEntityMatcher() | ||||||
|  |                 .withPatchedPersonType(HsOfficePersonType.NATURAL) | ||||||
|  |                 .withPatchedTradeName("patched@example.org") | ||||||
|  |                 .withPatchedFamilyName("patched postal address") | ||||||
|  |                 .withPatchedGivenName("+01 200 987654321") | ||||||
|  |                 .matches(givenPerson); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @ParameterizedTest | ||||||
|  |     @EnumSource(HsOfficePersonTypeResource.class) | ||||||
|  |     void willPatchOnlyPersonTypeProperty(final HsOfficePersonTypeResource patchedValue) { | ||||||
|  |         // given | ||||||
|  |         patchResource.setPersonType(patchedValue); | ||||||
|  |  | ||||||
|  |         // when | ||||||
|  |         hsOfficePersonEntityPatch.apply(patchResource); | ||||||
|  |  | ||||||
|  |         // then | ||||||
|  |         new HsOfficePersonEntityMatcher() | ||||||
|  |                 .withPatchedPersonType(HsOfficePersonType.valueOf(patchedValue.getValue())) | ||||||
|  |                 .matches(givenPerson); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @ParameterizedTest | ||||||
|  |     @ValueSource(strings = { "patched@example.org" }) | ||||||
|  |     @NullSource | ||||||
|  |     void willPatchOnlyTradeNameProperty(final String patchedValue) { | ||||||
|  |         // given | ||||||
|  |         patchResource.setTradeName(JsonNullable.of(patchedValue)); | ||||||
|  |  | ||||||
|  |         // when | ||||||
|  |         hsOfficePersonEntityPatch.apply(patchResource); | ||||||
|  |  | ||||||
|  |         // then | ||||||
|  |         new HsOfficePersonEntityMatcher() | ||||||
|  |                 .withPatchedTradeName(patchedValue) | ||||||
|  |                 .matches(givenPerson); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @ParameterizedTest | ||||||
|  |     @ValueSource(strings = { "patched postal address" }) | ||||||
|  |     @NullSource | ||||||
|  |     void willPatchOnlyFamilyNameProperty(final String patchedValue) { | ||||||
|  |         // given | ||||||
|  |         patchResource.setFamilyName(JsonNullable.of(patchedValue)); | ||||||
|  |  | ||||||
|  |         // when | ||||||
|  |         hsOfficePersonEntityPatch.apply(patchResource); | ||||||
|  |  | ||||||
|  |         // then | ||||||
|  |         new HsOfficePersonEntityMatcher() | ||||||
|  |                 .withPatchedFamilyName(patchedValue) | ||||||
|  |                 .matches(givenPerson); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @ParameterizedTest | ||||||
|  |     @ValueSource(strings = { "+01 200 987654321" }) | ||||||
|  |     @NullSource | ||||||
|  |     void willPatchOnlyGivenNameProperty(final String patchedValue) { | ||||||
|  |         // given | ||||||
|  |         patchResource.setGivenName(JsonNullable.of(patchedValue)); | ||||||
|  |  | ||||||
|  |         // when | ||||||
|  |         hsOfficePersonEntityPatch.apply(patchResource); | ||||||
|  |  | ||||||
|  |         // then | ||||||
|  |         new HsOfficePersonEntityMatcher() | ||||||
|  |                 .withPatchedGivenName(patchedValue) | ||||||
|  |                 .matches(givenPerson); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static class HsOfficePersonEntityMatcher { | ||||||
|  |  | ||||||
|  |         private HsOfficePersonType expectedPersonType = HsOfficePersonType.LEGAL; | ||||||
|  |         private String expectedTradeName = "initial@example.org"; | ||||||
|  |         private String expectedFamilyName = "initial postal address"; | ||||||
|  |  | ||||||
|  |         private String expectedGivenName = "+01 100 123456789"; | ||||||
|  |  | ||||||
|  |         HsOfficePersonEntityMatcher withPatchedPersonType(final HsOfficePersonType patchedPersonType) { | ||||||
|  |             expectedPersonType = patchedPersonType; | ||||||
|  |             return this; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         HsOfficePersonEntityMatcher withPatchedTradeName(final String patchedTradeName) { | ||||||
|  |             expectedTradeName = patchedTradeName; | ||||||
|  |             return this; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         HsOfficePersonEntityMatcher withPatchedFamilyName(final String patchedFamilyName) { | ||||||
|  |             expectedFamilyName = patchedFamilyName; | ||||||
|  |             return this; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         HsOfficePersonEntityMatcher withPatchedGivenName(final String patchedGivenName) { | ||||||
|  |             expectedGivenName = patchedGivenName; | ||||||
|  |             return this; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         void matches(final HsOfficePersonEntity givenPerson) { | ||||||
|  |  | ||||||
|  |             assertThat(givenPerson.getPersonType()).isEqualTo(expectedPersonType); | ||||||
|  |             assertThat(givenPerson.getTradeName()).isEqualTo(expectedTradeName); | ||||||
|  |             assertThat(givenPerson.getFamilyName()).isEqualTo(expectedFamilyName); | ||||||
|  |             assertThat(givenPerson.getGivenName()).isEqualTo(expectedGivenName); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user