add endpoint HTTP GET /api/hs/office/partners/P-{partnerNumber}

This commit is contained in:
Michael Hoennig 2024-12-06 14:57:32 +01:00
parent a05430a54b
commit fc47cb0fce
8 changed files with 94 additions and 7 deletions

View File

@ -104,6 +104,23 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
return ResponseEntity.ok(mapper.map(result.get(), HsOfficePartnerResource.class));
}
@Override
@Transactional(readOnly = true)
@Timed("app.office.partners.api.getSinglePartnerByPartnerNumber")
public ResponseEntity<HsOfficePartnerResource> getSinglePartnerByPartnerNumber(
final String currentSubject,
final String assumedRoles,
final Integer partnerNumber) {
context.define(currentSubject, assumedRoles);
final var result = partnerRepo.findPartnerByPartnerNumber(partnerNumber);
if (result.isEmpty()) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(mapper.map(result.get(), HsOfficePartnerResource.class));
}
@Override
@Transactional
@Timed("app.office.partners.api.deletePartnerByUuid")

View File

@ -32,7 +32,7 @@ public interface HsOfficePartnerRepository extends Repository<HsOfficePartnerEnt
List<HsOfficePartnerEntity> findPartnerByOptionalNameLike(String name);
@Timed("app.office.partners.repo.findPartnerByPartnerNumber")
HsOfficePartnerEntity findPartnerByPartnerNumber(Integer partnerNumber);
Optional<HsOfficePartnerEntity> findPartnerByPartnerNumber(Integer partnerNumber);
@Timed("app.office.partners.repo.save")
HsOfficePartnerEntity save(final HsOfficePartnerEntity entity);

View File

@ -0,0 +1,28 @@
get:
tags:
- hs-office-partners
description: 'Fetch a single business partner by its partner-number (prefixed with "P-"), if visible for the current subject.'
operationId: getSinglePartnerByPartnerNumber
parameters:
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: partnerNumber
in: path
required: true
schema:
type: integer
minimum: 10000
maximum: 99999
description: partner-number (prefixed with "P-") of the partner to fetch.
responses:
"200":
description: OK
content:
'application/json':
schema:
$ref: 'hs-office-partner-schemas.yaml#/components/schemas/HsOfficePartner'
"401":
$ref: 'error-responses.yaml#/components/responses/Unauthorized'
"403":
$ref: 'error-responses.yaml#/components/responses/Forbidden'

View File

@ -13,6 +13,9 @@ paths:
/api/hs/office/partners:
$ref: "hs-office-partners.yaml"
/api/hs/office/partners/P-{partnerNumber}:
$ref: "hs-office-partners-with-partnerNumber.yaml"
/api/hs/office/partners/{partnerUUID}:
$ref: "hs-office-partners-with-uuid.yaml"

View File

@ -83,7 +83,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
// given
context("superuser-alex@hostsharing.net");
final var count = debitorRepo.count();
final var givenPartner = partnerRepo.findPartnerByPartnerNumber(10001);
final var givenPartner = partnerRepo.findPartnerByPartnerNumber(10001).orElseThrow();
final var givenPartnerPerson = one(personRepo.findPersonByOptionalNameLike("First GmbH"));
final var givenContact = one(contactrealRepo.findContactByOptionalCaptionLike("first contact"));

View File

@ -112,16 +112,16 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
void globalAdmin_canViewMembershipsByPartnerUuid() {
context.define("superuser-alex@hostsharing.net");
final var partner = partnerRepo.findPartnerByPartnerNumber(10001);
final var partner = partnerRepo.findPartnerByPartnerNumber(10001).orElseThrow();
RestAssured // @formatter:off
.given()
.given()
.header("current-subject", "superuser-alex@hostsharing.net")
.port(port)
.when()
.when()
.queryParam("partnerUuid", partner.getUuid() )
.get("http://localhost/api/hs/office/memberships")
.then().log().all().assertThat()
.then().log().all().assertThat()
.statusCode(200)
.contentType("application/json")
.body("", lenientlyEquals("""

View File

@ -168,6 +168,45 @@ class HsOfficePartnerControllerRestTest {
}
}
@Nested
class GetSinglePartnerByPartnerNumber {
@Test
void respondWithPartner_ifPartnerNumberIsAvailable() throws Exception {
// given
when(partnerRepo.findPartnerByPartnerNumber(12345)).thenReturn(Optional.of(HsOfficePartnerEntity.builder()
.partnerNumber(12345)
.build()));
// when
mockMvc.perform(MockMvcRequestBuilders
.get("/api/hs/office/partners/P-12345")
.header("current-subject", "superuser-alex@hostsharing.net")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON))
// then
.andExpect(status().isOk())
.andExpect(jsonPath("partnerNumber", is("P-12345")));
}
@Test
void respondNotFound_ifPartnerNumberIsNotAvailable() throws Exception {
// given
when(partnerRepo.findPartnerByPartnerNumber(12345)).thenReturn(Optional.empty());
// when
mockMvc.perform(MockMvcRequestBuilders
.get("/api/hs/office/partners/P-12345")
.header("current-subject", "superuser-alex@hostsharing.net")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON))
// then
.andExpect(status().isNotFound());
}
}
@Nested
class DeletePartner {

View File

@ -243,7 +243,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
context("superuser-alex@hostsharing.net");
// when
final var result = partnerRepo.findPartnerByPartnerNumber(10001);
final var result = partnerRepo.findPartnerByPartnerNumber(10001).orElseThrow();
// then
assertThat(result)