From e95fbd14b31add1e9ab9dc667eac1e8b5371ec94 Mon Sep 17 00:00:00 2001 From: Manuel Rafeli Date: Mon, 29 Jan 2024 15:42:56 +0100 Subject: [PATCH] [SELC-3996] feat: Introduce New v2 onboarding/company Endpoint (#240) * client onboarding-ms onboarding company * service * endpoint v2 /company/onboarding * open api --- app/src/main/resources/swagger/api-docs.json | 87 ++++++++++++++++++- .../connector/api/OnboardingMsConnector.java | 2 + .../openapi/api-selfcare-onboarding-docs.json | 68 +++++++++++++++ .../connector/OnboardingMsConnectorImpl.java | 6 ++ .../rest/mapper/OnboardingMapper.java | 4 + .../OnboardingMsConnectorImplTest.java | 26 +++++- .../onboarding/core/InstitutionService.java | 2 + .../core/InstitutionServiceImpl.java | 7 ++ .../core/InstitutionServiceImplTest.java | 14 +++ .../controller/InstitutionV2Controller.java | 19 ++++ .../InstitutionV2ControllerTest.java | 19 ++++ 11 files changed, 249 insertions(+), 5 deletions(-) diff --git a/app/src/main/resources/swagger/api-docs.json b/app/src/main/resources/swagger/api-docs.json index 6dc7824a..a03423ff 100644 --- a/app/src/main/resources/swagger/api-docs.json +++ b/app/src/main/resources/swagger/api-docs.json @@ -1321,12 +1321,97 @@ } ] } }, - "/v2/institutions/onboarding" : { + "/v2/institutions/company/onboarding" : { "post" : { "tags" : [ "institutions" ], "summary" : "onboarding", "description" : "The service allows the onboarding of Users to a subunit of an Institution", "operationId" : "onboardingUsingPOST_3", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/CompanyOnboardingDto" + } + } + } + }, + "responses" : { + "201" : { + "description" : "Created" + }, + "400" : { + "description" : "Bad Request", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "401" : { + "description" : "Unauthorized", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "403" : { + "description" : "Forbidden", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "404" : { + "description" : "Not Found", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "409" : { + "description" : "Conflict", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "500" : { + "description" : "Internal Server Error", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + } + }, + "security" : [ { + "bearerAuth" : [ "global" ] + } ] + } + }, + "/v2/institutions/onboarding" : { + "post" : { + "tags" : [ "institutions" ], + "summary" : "onboarding", + "description" : "The service allows the onboarding of Users to a subunit of an Institution", + "operationId" : "onboardingUsingPOST_4", "requestBody" : { "content" : { "application/json" : { diff --git a/connector-api/src/main/java/it/pagopa/selfcare/onboarding/connector/api/OnboardingMsConnector.java b/connector-api/src/main/java/it/pagopa/selfcare/onboarding/connector/api/OnboardingMsConnector.java index 1f752ae6..1863dc86 100644 --- a/connector-api/src/main/java/it/pagopa/selfcare/onboarding/connector/api/OnboardingMsConnector.java +++ b/connector-api/src/main/java/it/pagopa/selfcare/onboarding/connector/api/OnboardingMsConnector.java @@ -6,6 +6,8 @@ public interface OnboardingMsConnector { void onboarding(OnboardingData onboardingData); + void onboardingCompany(OnboardingData onboardingData); + void onboardingTokenComplete(String onboardingId, MultipartFile contract); void onboardingPending(String onboardingId); diff --git a/connector/rest/docs/openapi/api-selfcare-onboarding-docs.json b/connector/rest/docs/openapi/api-selfcare-onboarding-docs.json index ae6c0e4a..da21ce3b 100644 --- a/connector/rest/docs/openapi/api-selfcare-onboarding-docs.json +++ b/connector/rest/docs/openapi/api-selfcare-onboarding-docs.json @@ -221,6 +221,41 @@ } ] } }, + "/v1/onboarding/pg/completion" : { + "post" : { + "tags" : [ "Onboarding Controller" ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/OnboardingPgRequest" + } + } + } + }, + "responses" : { + "200" : { + "description" : "OK", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/OnboardingResponse" + } + } + } + }, + "401" : { + "description" : "Not Authorized" + }, + "403" : { + "description" : "Not Allowed" + } + }, + "security" : [ { + "SecurityScheme" : [ ] + } ] + } + }, "/v1/onboarding/psp" : { "post" : { "tags" : [ "Onboarding Controller" ], @@ -1001,6 +1036,39 @@ } } }, + "OnboardingPgRequest" : { + "required" : [ "productId", "users", "taxCode", "origin", "digitalAddress" ], + "type" : "object", + "properties" : { + "productId" : { + "minLength" : 1, + "type" : "string" + }, + "users" : { + "minItems" : 1, + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/UserRequest" + } + }, + "taxCode" : { + "type" : "string" + }, + "businessName" : { + "type" : "string" + }, + "origin" : { + "$ref" : "#/components/schemas/Origin" + }, + "digitalAddress" : { + "pattern" : "\\S", + "type" : "string" + }, + "userRequestUid" : { + "type" : "string" + } + } + }, "OnboardingPspRequest" : { "required" : [ "productId", "users", "institution" ], "type" : "object", diff --git a/connector/rest/src/main/java/it/pagopa/selfcare/onboarding/connector/OnboardingMsConnectorImpl.java b/connector/rest/src/main/java/it/pagopa/selfcare/onboarding/connector/OnboardingMsConnectorImpl.java index 03c4b997..441bbe60 100644 --- a/connector/rest/src/main/java/it/pagopa/selfcare/onboarding/connector/OnboardingMsConnectorImpl.java +++ b/connector/rest/src/main/java/it/pagopa/selfcare/onboarding/connector/OnboardingMsConnectorImpl.java @@ -36,6 +36,12 @@ public void onboarding(OnboardingData onboardingData) { } } + + @Override + public void onboardingCompany(OnboardingData onboardingData) { + msOnboardingApiClient._v1OnboardingPgCompletionPost(onboardingMapper.toOnboardingPgRequest(onboardingData)); + } + @Override public void onboardingTokenComplete(String onboardingId, MultipartFile contract) { msOnboardingApiClient._v1OnboardingOnboardingIdCompletePut(onboardingId, contract); diff --git a/connector/rest/src/main/java/it/pagopa/selfcare/onboarding/connector/rest/mapper/OnboardingMapper.java b/connector/rest/src/main/java/it/pagopa/selfcare/onboarding/connector/rest/mapper/OnboardingMapper.java index 4e4185f8..9c5fea28 100644 --- a/connector/rest/src/main/java/it/pagopa/selfcare/onboarding/connector/rest/mapper/OnboardingMapper.java +++ b/connector/rest/src/main/java/it/pagopa/selfcare/onboarding/connector/rest/mapper/OnboardingMapper.java @@ -25,6 +25,10 @@ public interface OnboardingMapper { @Mapping(target = "additionalInformations", source = "institutionUpdate.additionalInformations") OnboardingDefaultRequest toOnboardingDefaultRequest(OnboardingData onboardingData); + @Mapping(target = "taxCode", source = "institutionUpdate.taxCode") + @Mapping(target = "digitalAddress", source = "institutionUpdate.digitalAddress") + OnboardingPgRequest toOnboardingPgRequest(OnboardingData onboardingData); + GeographicTaxonomyDto toGeographicTaxonomyDto(GeographicTaxonomy geographicTaxonomy); @Named("toInstitutionBase") diff --git a/connector/rest/src/test/java/it/pagopa/selfcare/onboarding/connector/OnboardingMsConnectorImplTest.java b/connector/rest/src/test/java/it/pagopa/selfcare/onboarding/connector/OnboardingMsConnectorImplTest.java index 20799469..3f5f41e8 100644 --- a/connector/rest/src/test/java/it/pagopa/selfcare/onboarding/connector/OnboardingMsConnectorImplTest.java +++ b/connector/rest/src/test/java/it/pagopa/selfcare/onboarding/connector/OnboardingMsConnectorImplTest.java @@ -5,10 +5,7 @@ import it.pagopa.selfcare.onboarding.connector.rest.client.MsOnboardingApiClient; import it.pagopa.selfcare.onboarding.connector.rest.mapper.OnboardingMapper; import it.pagopa.selfcare.onboarding.connector.rest.mapper.OnboardingMapperImpl; -import it.pagopa.selfcare.onboarding.generated.openapi.v1.dto.OnboardingDefaultRequest; -import it.pagopa.selfcare.onboarding.generated.openapi.v1.dto.OnboardingGet; -import it.pagopa.selfcare.onboarding.generated.openapi.v1.dto.OnboardingPaRequest; -import it.pagopa.selfcare.onboarding.generated.openapi.v1.dto.OnboardingPspRequest; +import it.pagopa.selfcare.onboarding.generated.openapi.v1.dto.*; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.function.Executable; @@ -116,6 +113,27 @@ void onboarding_institutionPsp() { assertNotNull(actual.getInstitution().getDataProtectionOfficer()); verifyNoMoreInteractions(msOnboardingApiClient); } + @Test + void onboardingCompany() { + // given + OnboardingData onboardingData = new OnboardingData(); + onboardingData.setTaxCode("taxCode"); + onboardingData.setInstitutionType(InstitutionType.PG); + InstitutionUpdate institutionUpdate = new InstitutionUpdate(); + institutionUpdate.setTaxCode("taxCode"); + onboardingData.setUsers(List.of(mockInstance(new User()))); + onboardingData.setInstitutionUpdate(institutionUpdate); + // when + onboardingMsConnector.onboardingCompany(onboardingData); + // then + ArgumentCaptor onboardingRequestCaptor = ArgumentCaptor.forClass(OnboardingPgRequest.class); + verify(msOnboardingApiClient, times(1)) + ._v1OnboardingPgCompletionPost(onboardingRequestCaptor.capture()); + OnboardingPgRequest actual = onboardingRequestCaptor.getValue(); + assertEquals(actual.getTaxCode(), institutionUpdate.getTaxCode()); + assertEquals(actual.getDigitalAddress(), institutionUpdate.getDigitalAddress()); + verifyNoMoreInteractions(msOnboardingApiClient); + } @Test void onboardingComplete() throws IOException { diff --git a/core/src/main/java/it/pagopa/selfcare/onboarding/core/InstitutionService.java b/core/src/main/java/it/pagopa/selfcare/onboarding/core/InstitutionService.java index beb667dd..32a1af42 100644 --- a/core/src/main/java/it/pagopa/selfcare/onboarding/core/InstitutionService.java +++ b/core/src/main/java/it/pagopa/selfcare/onboarding/core/InstitutionService.java @@ -17,6 +17,8 @@ public interface InstitutionService { void onboardingProductV2(OnboardingData onboardingData); + void onboardingCompanyV2(OnboardingData onboardingData); + void onboardingProduct(OnboardingData onboardingData); void onboarding(OnboardingData onboardingData); diff --git a/core/src/main/java/it/pagopa/selfcare/onboarding/core/InstitutionServiceImpl.java b/core/src/main/java/it/pagopa/selfcare/onboarding/core/InstitutionServiceImpl.java index a47ae8b6..b538876d 100644 --- a/core/src/main/java/it/pagopa/selfcare/onboarding/core/InstitutionServiceImpl.java +++ b/core/src/main/java/it/pagopa/selfcare/onboarding/core/InstitutionServiceImpl.java @@ -104,6 +104,13 @@ public void onboardingProductV2(OnboardingData onboardingData) { onboardingMsConnector.onboarding(onboardingData); log.trace("onboarding end"); } + @Override + public void onboardingCompanyV2(OnboardingData onboardingData) { + log.trace("onboardingProductAsync start"); + log.debug("onboardingProductAsync onboardingData = {}", onboardingData); + onboardingMsConnector.onboardingCompany(onboardingData); + log.trace("onboarding end"); + } @Override public void onboardingProduct(OnboardingData onboardingData) { diff --git a/core/src/test/java/it/pagopa/selfcare/onboarding/core/InstitutionServiceImplTest.java b/core/src/test/java/it/pagopa/selfcare/onboarding/core/InstitutionServiceImplTest.java index af965a37..1f90e210 100644 --- a/core/src/test/java/it/pagopa/selfcare/onboarding/core/InstitutionServiceImplTest.java +++ b/core/src/test/java/it/pagopa/selfcare/onboarding/core/InstitutionServiceImplTest.java @@ -472,6 +472,20 @@ void onboardingProductAsync() { .onboarding(any()); } + + @Test + void onboardingCompanyV2() { + // given + OnboardingData onboardingData = mockInstance(new OnboardingData(), "setInstitutionType", "setUsers"); + onboardingData.setInstitutionType(InstitutionType.PG); + onboardingData.setUsers(List.of(dummyManager, dummyDelegate)); + // when + institutionService.onboardingCompanyV2(onboardingData); + // then + verify(onboardingMsConnector, times(1)) + .onboardingCompany(any()); + } + @Test void shouldOnboardingProductInstitutionNotPa() { // given diff --git a/web/src/main/java/it/pagopa/selfcare/onboarding/web/controller/InstitutionV2Controller.java b/web/src/main/java/it/pagopa/selfcare/onboarding/web/controller/InstitutionV2Controller.java index 8a4b3d11..3d6097d5 100644 --- a/web/src/main/java/it/pagopa/selfcare/onboarding/web/controller/InstitutionV2Controller.java +++ b/web/src/main/java/it/pagopa/selfcare/onboarding/web/controller/InstitutionV2Controller.java @@ -7,6 +7,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import it.pagopa.selfcare.commons.web.model.Problem; import it.pagopa.selfcare.onboarding.core.InstitutionService; +import it.pagopa.selfcare.onboarding.web.model.CompanyOnboardingDto; import it.pagopa.selfcare.onboarding.web.model.OnboardingProductDto; import it.pagopa.selfcare.onboarding.web.model.mapper.OnboardingResourceMapper; import lombok.extern.slf4j.Slf4j; @@ -54,4 +55,22 @@ public void onboarding(@RequestBody @Valid OnboardingProductDto request) { log.trace(ONBOARDING_END); } + + + @ApiResponse(responseCode = "403", + description = "Forbidden", + content = { + @Content(mediaType = APPLICATION_PROBLEM_JSON_VALUE, + schema = @Schema(implementation = Problem.class)) + }) + @PostMapping(value = "/company/onboarding") + @ResponseStatus(HttpStatus.CREATED) + @ApiOperation(value = "", notes = "${swagger.onboarding.institutions.api.onboarding.subunit}") + public void onboarding(@RequestBody @Valid CompanyOnboardingDto request) { + log.trace(ONBOARDING_START); + log.debug("onboarding request = {}", request); + institutionService.onboardingCompanyV2(onboardingResourceMapper.toEntity(request)); + log.trace(ONBOARDING_END); + } + } diff --git a/web/src/test/java/it/pagopa/selfcare/onboarding/web/controller/InstitutionV2ControllerTest.java b/web/src/test/java/it/pagopa/selfcare/onboarding/web/controller/InstitutionV2ControllerTest.java index 9f96ac0b..d338834f 100644 --- a/web/src/test/java/it/pagopa/selfcare/onboarding/web/controller/InstitutionV2ControllerTest.java +++ b/web/src/test/java/it/pagopa/selfcare/onboarding/web/controller/InstitutionV2ControllerTest.java @@ -52,4 +52,23 @@ void onboardingProductAsync(@Value("classpath:stubs/onboardingProductsDtoWithout .onboardingProductV2(any(OnboardingData.class)); verifyNoMoreInteractions(institutionServiceMock); } + + + @Test + void onboardingCompany(@Value("classpath:stubs/onboardingCompanyDto.json") Resource onboardingDto) throws Exception { + + // when + mvc.perform(MockMvcRequestBuilders + .post(BASE_URL + "/company/onboarding") + .content(onboardingDto.getInputStream().readAllBytes()) + .contentType(APPLICATION_JSON_VALUE) + .accept(APPLICATION_JSON_VALUE)) + .andExpect(status().isCreated()) + .andExpect(content().string(emptyString())); + // then + + verify(institutionServiceMock, times(1)) + .onboardingCompanyV2(any(OnboardingData.class)); + verifyNoMoreInteractions(institutionServiceMock); + } }