diff --git a/helm/Chart.yaml b/helm/Chart.yaml index 85c601a3a..b7bd39f7b 100644 --- a/helm/Chart.yaml +++ b/helm/Chart.yaml @@ -2,8 +2,8 @@ apiVersion: v2 name: pagopa-selfcare-ms-backoffice description: Microservice that manage api keys for pagopa product from selfcare type: application -version: 0.405.0 -appVersion: "2.25.0-5-next" +version: 0.409.0 +appVersion: "2.26.3" dependencies: - name: microservice-chart version: 2.4.0 diff --git a/helm/values-dev.yaml b/helm/values-dev.yaml index 37aa27aa3..a6b01420c 100644 --- a/helm/values-dev.yaml +++ b/helm/values-dev.yaml @@ -4,7 +4,7 @@ microservice-chart: fullnameOverride: "" image: repository: ghcr.io/pagopa/pagopa-selfcare-ms-backoffice-backend - tag: "2.25.0-5-next" + tag: "2.26.3" pullPolicy: Always livenessProbe: httpGet: diff --git a/helm/values-prod.yaml b/helm/values-prod.yaml index c5f9d112b..0d4aa04d9 100644 --- a/helm/values-prod.yaml +++ b/helm/values-prod.yaml @@ -4,7 +4,7 @@ microservice-chart: fullnameOverride: "" image: repository: ghcr.io/pagopa/pagopa-selfcare-ms-backoffice-backend - tag: "2.25.0-5-next" #improve + tag: "2.26.3" #improve pullPolicy: Always livenessProbe: httpGet: diff --git a/helm/values-uat.yaml b/helm/values-uat.yaml index ff72df6b0..6ca6436d1 100644 --- a/helm/values-uat.yaml +++ b/helm/values-uat.yaml @@ -4,7 +4,7 @@ microservice-chart: fullnameOverride: "" image: repository: ghcr.io/pagopa/pagopa-selfcare-ms-backoffice-backend - tag: "2.25.0-5-next" #improve + tag: "2.26.3" #improve pullPolicy: Always livenessProbe: httpGet: diff --git a/openapi/openapi.json b/openapi/openapi.json index 0adf752a2..23e6d61af 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -4,7 +4,7 @@ "description": "Microservice to manage PagoPA Backoffice", "termsOfService": "https://www.pagopa.gov.it/", "title": "SelfCare Backoffice", - "version": "2.25.0-5-next" + "version": "2.26.3" }, "servers": [ { diff --git a/pom.xml b/pom.xml index 5c6ea8e03..12f6fc9f1 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ 2.5.14 pagopa-selfcare-ms-backoffice - 2.25.0-5-next + 2.26.3 SelfCare Backoffice Microservice to manage PagoPA Backoffice diff --git a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/client/AuthorizerConfigClient.java b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/client/AuthorizerConfigClient.java index f61ef3df0..dd5b0eec9 100644 --- a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/client/AuthorizerConfigClient.java +++ b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/client/AuthorizerConfigClient.java @@ -24,4 +24,11 @@ public interface AuthorizerConfigClient { @DeleteMapping(value = "/authorizations/{authorization-id}") void deleteAuthorization(@PathVariable("authorization-id") String authorizationId); + + @PutMapping(value = "/authorizations/{authorization-id}", produces = MediaType.APPLICATION_JSON_VALUE) + @Valid + Authorization updateAuthorization( + @PathVariable("authorization-id") String authorizationId, + @RequestBody Authorization authorization + ); } diff --git a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/repository/TaxonomyRepository.java b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/repository/TaxonomyRepository.java index 4dc72baea..556026fb0 100644 --- a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/repository/TaxonomyRepository.java +++ b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/repository/TaxonomyRepository.java @@ -6,6 +6,7 @@ import java.time.Instant; import java.util.List; +import java.util.regex.Pattern; public interface TaxonomyRepository extends MongoRepository { @@ -17,7 +18,7 @@ public interface TaxonomyRepository extends MongoRepository searchTaxonomies(String ec, String macroArea, String code, Boolean valid, Instant now); - List findBySpecificBuiltInDataIn(List codes); + List findBySpecificBuiltInDataIn(List codes); } diff --git a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/service/ApiManagementService.java b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/service/ApiManagementService.java index 4fa7b4d90..d05809870 100644 --- a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/service/ApiManagementService.java +++ b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/service/ApiManagementService.java @@ -284,8 +284,8 @@ public void updateBrokerAuthorizerSegregationCodesMetadata( apiKeys.parallelStream().forEach( apiKey -> { String prefixId = apiKey.getId().split("-")[0] + "-"; - updateAuthorizerConfigMetadata(institutionId, prefixId, ciSegregationCodes, true); - updateAuthorizerConfigMetadata(institutionId, prefixId, ciSegregationCodes, false); + updateAuthorizerConfigMetadata(institutionId, prefixId, ciSegregationCodes, true, apiKey.getPrimaryKey()); + updateAuthorizerConfigMetadata(institutionId, prefixId, ciSegregationCodes, false, apiKey.getSecondaryKey()); } ); } @@ -311,25 +311,28 @@ private void updateAuthorization( .orElseThrow(() -> new AppException(AppError.APIM_KEY_NOT_FOUND, institutionId)); Subscription subscription = Subscription.fromPrefix(subscriptionPrefixId); + InstitutionResponse institution = getInstitutionResponse(institutionId); + DelegationInfo delegationInfoResponse = getDelegationInfo(institutionId, subscription.getAuthDelegations(), institution.getTaxCode()); + String subKey = isPrimaryKey ? apiKeys.getPrimaryKey() : apiKeys.getSecondaryKey(); Authorization authorization; try { String authorizationId = createAuthorizationId(subscriptionPrefixId, institutionId, isPrimaryKey); authorization = this.authorizerConfigClient.getAuthorization(authorizationId); - authorization.setSubscriptionKey(isPrimaryKey ? apiKeys.getPrimaryKey() : apiKeys.getSecondaryKey()); - - InstitutionResponse institution = getInstitutionResponse(institutionId); - DelegationInfo delegationInfoResponse = getDelegationInfo(institutionId, subscription.getAuthDelegations(), institution.getTaxCode()); - + authorization.setSubscriptionKey(subKey); authorization.setAuthorizedEntities(getAuthorizationEntities(institution, delegationInfoResponse.delegationResponse)); authorization.setOtherMetadata(getAuthorizationMetadataList(delegationInfoResponse.ciSegregationCodes, authorization.getOtherMetadata())); this.authorizerConfigClient.deleteAuthorization(authorization.getId()); this.authorizerConfigClient.createAuthorization(authorization); } catch (FeignException.NotFound e) { - log.error("An error occurred while updating API key authorizer configuration for institution {} and subscription {}, proceed to recreate the API key", - sanitizeLogParam(institutionId), sanitizeLogParam(subscription.getDisplayName()), e); - createSubscriptionKeys(institutionId, subscription); + log.error("{} key authorizer configuration for institution {} and subscription {} not found, proceed to recreate the configuration", + isPrimaryKey ? PRIMARY : SECONDARY, + sanitizeLogParam(institutionId), + sanitizeLogParam(subscription.getDisplayName()), + e); + authorization = buildAuthorization(subscription, subKey, institution, isPrimaryKey, delegationInfoResponse); + this.authorizerConfigClient.createAuthorization(authorization); } } @@ -433,21 +436,26 @@ private void updateAuthorizerConfigMetadata( String institutionId, String prefixId, CreditorInstitutionStationSegregationCodesList ciSegregationCodes, - boolean isPrimaryKey + boolean isPrimaryKey, + String subKey ) { Subscription subscription = Subscription.fromPrefix(prefixId); + Authorization authorization; + String authorizationId = createAuthorizationId(prefixId, institutionId, isPrimaryKey); try { - String authorizationId = createAuthorizationId(prefixId, institutionId, isPrimaryKey); - Authorization authorization = this.authorizerConfigClient.getAuthorization(authorizationId); - + authorization = this.authorizerConfigClient.getAuthorization(authorizationId); authorization.setOtherMetadata(getAuthorizationMetadataList(ciSegregationCodes, authorization.getOtherMetadata())); - - this.authorizerConfigClient.deleteAuthorization(authorization.getId()); - this.authorizerConfigClient.createAuthorization(authorization); + this.authorizerConfigClient.updateAuthorization(authorizationId, authorization); } catch (FeignException.NotFound e) { - log.error("An error occurred while updating API key authorizer configuration for institution {} and subscription {}, proceed to recreate the API key", - sanitizeLogParam(institutionId), sanitizeLogParam(subscription.getDisplayName()), e); - createSubscriptionKeys(institutionId, subscription); + log.error("{} key authorizer configuration for institution {} and subscription {} not found, proceed to recreate the configuration", + isPrimaryKey ? PRIMARY : SECONDARY, + sanitizeLogParam(institutionId), + sanitizeLogParam(subscription.getDisplayName()), + e); + InstitutionResponse institution = getInstitutionResponse(institutionId); + DelegationInfo delegationInfoResponse = getDelegationInfo(institutionId, subscription.getAuthDelegations(), institution.getTaxCode()); + authorization = buildAuthorization(subscription, subKey, institution, isPrimaryKey, delegationInfoResponse); + this.authorizerConfigClient.createAuthorization(authorization); } } diff --git a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/service/CreditorInstitutionService.java b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/service/CreditorInstitutionService.java index 4290f48b4..cf20c925e 100644 --- a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/service/CreditorInstitutionService.java +++ b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/service/CreditorInstitutionService.java @@ -48,6 +48,8 @@ import java.util.Objects; import java.util.Optional; +import static it.pagopa.selfcare.pagopa.backoffice.util.Utility.sanitizeLogParam; + @Slf4j @Service public class CreditorInstitutionService { @@ -130,10 +132,10 @@ public AvailableCodes getCreditorInstitutionSegregationCodes(String ciTaxCode, S * Check if the provided tax code is a creditor institution tax code and if so, associates it to the given station and * updates the authorizer config for each broker's api keys by adding the specified segregation code * - * @param ciTaxCode creditor institution's tax code + * @param ciTaxCode creditor institution's tax code * @param institutionId broker's institution id * @param brokerTaxCode broker's tax code - * @param dto creditor institution - station association info + * @param dto creditor institution - station association info * @return the creditor institution - station association info */ public CreditorInstitutionStationEditResource associateStationToCreditorInstitution( @@ -148,7 +150,8 @@ public CreditorInstitutionStationEditResource associateStationToCreditorInstitut try { this.apiManagementService.updateBrokerAuthorizerSegregationCodesMetadata(institutionId, brokerTaxCode); } catch (Exception e) { - log.error("Failed to update broker API key authorizations, revert associate station to CI operation"); + log.error("Failed to update broker {} API key authorizations, revert associate station to CI operation", + sanitizeLogParam(brokerTaxCode), e); this.apiConfigClient.deleteCreditorInstitutionStationRelationship(ciTaxCode, ecStation.getStationCode()); throw e; } @@ -162,7 +165,7 @@ public CreditorInstitutionStationEditResource associateStationToCreditorInstitut * station with the provided info * * @param ciTaxCode creditor institution's tax code - * @param dto creditor institution - station association info + * @param dto creditor institution - station association info * @return the updated creditor institution - station association info */ public CreditorInstitutionStationEditResource updateStationAssociationToCreditorInstitution( @@ -181,7 +184,7 @@ public CreditorInstitutionStationEditResource updateStationAssociationToCreditor * Removes the association and updates the authorizer config for each broker's api keys by removing * the segregation code of the association * - * @param ciTaxCode creditor institution's tax code + * @param ciTaxCode creditor institution's tax code * @param institutionId broker's institution id * @param brokerTaxCode broker's tax code */ @@ -191,17 +194,24 @@ public void deleteCreditorInstitutionStationRelationship( String institutionId, String brokerTaxCode ) { + CreditorInstitutions ciForRollback = + this.apiConfigClient.getCreditorInstitutionsByStation(stationCode, 1, 0, ciTaxCode); this.apiConfigClient.deleteCreditorInstitutionStationRelationship(ciTaxCode, stationCode); try { this.apiManagementService.updateBrokerAuthorizerSegregationCodesMetadata(institutionId, brokerTaxCode); } catch (Exception e) { - log.error("Failed to update broker API key authorizations, revert dissociate station to CI operation"); - CreditorInstitutions creditorInstitutions = - this.apiConfigClient.getCreditorInstitutionsByStation(stationCode, 1, 0, ciTaxCode); - CreditorInstitutionStationEdit dto = - this.modelMapper.map(creditorInstitutions.getCreditorInstitutionList().get(0), CreditorInstitutionStationEdit.class); - dto.setStationCode(stationCode); - this.apiConfigClient.createCreditorInstitutionStationRelationship(ciTaxCode, dto); + log.error("Failed to update broker {} API key authorizations, revert dissociate station to CI operation", + sanitizeLogParam(brokerTaxCode), e); + if (ciForRollback != null && ciForRollback.getCreditorInstitutionList() != null && ciForRollback.getCreditorInstitutionList().size() == 1) { + CreditorInstitutionStationEdit dto = + this.modelMapper.map(ciForRollback.getCreditorInstitutionList().get(0), CreditorInstitutionStationEdit.class); + dto.setStationCode(stationCode); + dto.setAuxDigit(dto.getAuxDigit() == null ? 3L : dto.getAuxDigit()); + this.apiConfigClient.createCreditorInstitutionStationRelationship(ciTaxCode, dto); + } else { + log.error("Unable to rollback dissociate station ({}) to CI ({}) operation", + sanitizeLogParam(stationCode), sanitizeLogParam(ciTaxCode)); + } throw e; } } @@ -313,8 +323,7 @@ public CreditorInstitutionInfoResource getAvailableCreditorInstitutionsForStatio ) { List infoList = new ArrayList<>(); List delegations = getDelegationExternals(brokerId, ciName).parallelStream() - .filter(Objects::nonNull) - .filter(delegation -> RoleType.CI.equals(RoleType.fromSelfcareRole(delegation.getTaxCode(), delegation.getInstitutionType()))) + .filter(delegation -> isCIDelegation(brokerId, delegation)) .map(DelegationExternal::getTaxCode) .toList(); @@ -365,6 +374,7 @@ private List getDelegationExternals(String brokerId, String .taxCode(broker.getTaxCode()) .institutionName(broker.getDescription()) .institutionType(broker.getInstitutionType().toString()) + .brokerId(brokerId) .build() ); } @@ -376,9 +386,12 @@ private boolean brokerCanBeAddedToDelegation( InstitutionResponse broker, String ciNameFilter ) { - return RoleType.CI.equals(RoleType.fromSelfcareRole(broker.getTaxCode(), broker.getInstitutionType().name())) + return ( + RoleType.CI.equals(RoleType.fromSelfcareRole(broker.getTaxCode(), broker.getInstitutionType().name())) + || RoleType.PT.equals(RoleType.fromSelfcareRole(broker.getTaxCode(), broker.getInstitutionType().name())) + ) && (StringUtils.isBlank(ciNameFilter) || broker.getDescription().toLowerCase().contains(ciNameFilter.toLowerCase())) - && delegationExternals.stream().noneMatch(delegationExternal -> delegationExternal.getTaxCode().equals(broker.getTaxCode())); + && delegationExternals.parallelStream().noneMatch(delegationExternal -> delegationExternal.getTaxCode().equals(broker.getTaxCode())); } private void checkIfIsCITaxCodeFailOtherwise(String ciTaxCode) { @@ -388,4 +401,15 @@ private void checkIfIsCITaxCodeFailOtherwise(String ciTaxCode) { throw new AppException(AppError.CREDITOR_INSTITUTION_NOT_FOUND, ciTaxCode); } } + + private boolean isCIDelegation(String brokerId, DelegationExternal delegation) { + return delegation != null + && ( + RoleType.CI.equals(RoleType.fromSelfcareRole(delegation.getTaxCode(), delegation.getInstitutionType())) + || ( + delegation.getBrokerId().equals(brokerId) + && RoleType.PT.equals(RoleType.fromSelfcareRole(delegation.getTaxCode(), delegation.getInstitutionType())) + ) + ); + } } diff --git a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/service/TaxonomyService.java b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/service/TaxonomyService.java index 3e93fd41b..f078cce5e 100644 --- a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/service/TaxonomyService.java +++ b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/service/TaxonomyService.java @@ -11,6 +11,7 @@ import java.time.Instant; import java.util.List; +import java.util.regex.Pattern; import java.util.stream.Collectors; /** @@ -30,7 +31,7 @@ public class TaxonomyService { public Taxonomies getTaxonomies(String code, String ec, String macroArea, Boolean onlyValid) { List taxonomies = taxonomyRepository.searchTaxonomies( - ec, macroArea, code != null ? ".*".concat(code).concat(".*") : null, onlyValid, Instant.now()) + ec, macroArea, code != null ? "^[0-9]/.*".concat(code).concat(".*/$") : null, onlyValid, Instant.now()) .stream() .map(elem -> modelMapper.map(elem, Taxonomy.class)) .toList(); @@ -40,7 +41,9 @@ public Taxonomies getTaxonomies(String code, String ec, String macroArea, Boolea } public List getTaxonomiesByCodes(List codes) { - return taxonomyRepository.findBySpecificBuiltInDataIn(codes).stream() + return taxonomyRepository.findBySpecificBuiltInDataIn( + codes.stream().map(code -> Pattern.compile(code.contains("/") ? "^"+code+"$" : "^[0-9]/"+code+"/$")) + .toList()).stream() .map(elem -> modelMapper.map(elem, Taxonomy.class)).collect(Collectors.toList()); } diff --git a/src/test/java/it/pagopa/selfcare/pagopa/backoffice/service/ApiManagementServiceTest.java b/src/test/java/it/pagopa/selfcare/pagopa/backoffice/service/ApiManagementServiceTest.java index e813cea26..e3911e40f 100644 --- a/src/test/java/it/pagopa/selfcare/pagopa/backoffice/service/ApiManagementServiceTest.java +++ b/src/test/java/it/pagopa/selfcare/pagopa/backoffice/service/ApiManagementServiceTest.java @@ -291,11 +291,8 @@ void regeneratePrimaryKeyFailOnAuthorizerConfigUpdateTriggerAPIKeyRecreation() t assertDoesNotThrow(() -> service.regeneratePrimaryKey(INSTITUTION_ID, "gdp-aTaxCode")); verify(apimClient).regeneratePrimaryKey("gdp-aTaxCode"); - verify(apimClient, times(2)).getApiSubscriptions(INSTITUTION_ID); - verify(apimClient).getInstitution(INSTITUTION_ID); - verify(apimClient, never()).createInstitution(anyString(), any()); - verify(apimClient).createInstitutionSubscription(any(), any(), any(), any(), any()); - verify(authorizerConfigClient, times(2)).createAuthorization(any()); + verify(apimClient).getApiSubscriptions(INSTITUTION_ID); + verify(authorizerConfigClient).createAuthorization(any()); verify(authorizerConfigClient, never()).deleteAuthorization(anyString()); } @@ -424,8 +421,34 @@ void updateBrokerAuthorizerSegregationCodesMetadataSuccess() { assertDoesNotThrow(() -> service.updateBrokerAuthorizerSegregationCodesMetadata(INSTITUTION_ID, CI_TAX_CODE)); verify(apimClient).getApiSubscriptions(INSTITUTION_ID); - verify(authorizerConfigClient, times(2)).deleteAuthorization(anyString()); - verify(authorizerConfigClient, times(2)).createAuthorization(any()); + verify(authorizerConfigClient, times(2)).updateAuthorization(anyString(), any()); + } + + @Test + void updateBrokerAuthorizerSegregationCodesMetadataFailOnPrimary() throws IOException { + InstitutionResponse institutionResponse = TestUtil.fileToObject( + "response/externalapi/institution_response.json", InstitutionResponse.class); + String subscriptionId = String.format("%s%s", Subscription.GPD.getPrefixId(), CI_TAX_CODE); + InstitutionApiKeys institutionApiKeys1 = buildInstitutionApiKeys(subscriptionId); + + when(apimClient.getApiSubscriptions(INSTITUTION_ID)).thenReturn(List.of(institutionApiKeys1)); + when(apiConfigSelfcareIntegrationClient.getCreditorInstitutionsSegregationCodeAssociatedToBroker(anyString())) + .thenReturn( + buildCreditorInstitutionStationSegregationCodesList(), + buildCreditorInstitutionStationSegregationCodesList() + ); + when(authorizerConfigClient.getAuthorization(anyString())) + .thenThrow(FeignException.NotFound.class) + .thenReturn(buildAuthorizationWithSegregationCodes(CI_TAX_CODE)); + when(externalApiClient.getInstitution(any())).thenReturn(institutionResponse); + when(externalApiClient.getBrokerDelegation(null, INSTITUTION_ID, "prod-pagopa", "FULL", null)) + .thenReturn(createDelegations()); + + assertDoesNotThrow(() -> service.updateBrokerAuthorizerSegregationCodesMetadata(INSTITUTION_ID, CI_TAX_CODE)); + + verify(apimClient).getApiSubscriptions(INSTITUTION_ID); + verify(authorizerConfigClient).updateAuthorization(anyString(), any()); + verify(authorizerConfigClient).createAuthorization(any()); } private Authorization buildAuthorizationWithSegregationCodes(String ciTaxCode) { diff --git a/src/test/java/it/pagopa/selfcare/pagopa/backoffice/service/CreditorInstitutionServiceTest.java b/src/test/java/it/pagopa/selfcare/pagopa/backoffice/service/CreditorInstitutionServiceTest.java index ff1cf31df..131082e69 100644 --- a/src/test/java/it/pagopa/selfcare/pagopa/backoffice/service/CreditorInstitutionServiceTest.java +++ b/src/test/java/it/pagopa/selfcare/pagopa/backoffice/service/CreditorInstitutionServiceTest.java @@ -278,6 +278,8 @@ void deleteCreditorInstitutionStationRelationship_ok() { verify(apiConfigClient).deleteCreditorInstitutionStationRelationship(anyString(), anyString()); verify(apiManagementService).updateBrokerAuthorizerSegregationCodesMetadata(INSTITUTION_ID, BROKER_TAX_CODE); + verify(apiConfigClient).getCreditorInstitutionsByStation(STATION_CODE1, 1, 0, CI_TAX_CODE); + verify(apiConfigClient, never()).createCreditorInstitutionStationRelationship(anyString(), any()); } @Test @@ -287,6 +289,9 @@ void deleteCreditorInstitutionStationRelationship_ko() { assertThrows(FeignException.class, () -> service.deleteCreditorInstitutionStationRelationship(CI_TAX_CODE, STATION_CODE1, INSTITUTION_ID, BROKER_TAX_CODE)); + + verify(apiConfigClient).getCreditorInstitutionsByStation(STATION_CODE1, 1, 0, CI_TAX_CODE); + verify(apiConfigClient, never()).createCreditorInstitutionStationRelationship(anyString(), any()); } @Test @@ -301,6 +306,16 @@ void deleteCreditorInstitutionStationRelationshipFailOnAuthorizerUpdateExpectRol verify(apiConfigClient).createCreditorInstitutionStationRelationship(anyString(), any()); } + @Test + void deleteCreditorInstitutionStationRelationshipFailOnAuthorizerUpdateNoRollback() { + doThrow(AppException.class).when(apiManagementService).updateBrokerAuthorizerSegregationCodesMetadata(anyString(), anyString()); + assertThrows(AppException.class, () -> + service.deleteCreditorInstitutionStationRelationship(CI_TAX_CODE, STATION_CODE1, INSTITUTION_ID, BROKER_TAX_CODE)); + + verify(apiConfigClient).getCreditorInstitutionsByStation(STATION_CODE1, 1, 0, CI_TAX_CODE); + verify(apiConfigClient, never()).createCreditorInstitutionStationRelationship(anyString(), any()); + } + @Test void createCreditorInstitution_ok() throws IOException { when(apiConfigClient.createCreditorInstitution(any(CreditorInstitutionDetails.class))) @@ -540,6 +555,42 @@ void getAvailableCreditorInstitutionsForStationSuccessWithAddingItselfToDelegati assertEquals(2, result.getCreditorInstitutionInfos().size()); } + @Test + void getAvailableCreditorInstitutionsForStationSuccessWithAddingItselfPTToDelegationsAndPSPDelegationFiltered() { + DelegationExternal expectedCI = buildDelegation("PA", CI_TAX_CODE_2); + List delegations = new ArrayList<>(); + delegations.add(buildDelegation("PSP", "12345678")); + delegations.add(expectedCI); + InstitutionResponse institutionResponse = buildInstitutionResponse(InstitutionType.PT, "1234"); + + when(externalApiClient.getBrokerDelegation( + null, + BROKER_ID, + "prod-pagopa", + "FULL", + null) + ).thenReturn(delegations); + when(externalApiClient.getInstitution(BROKER_ID)).thenReturn(institutionResponse); + when(apiConfigSelfcareIntegrationClient.getStationCreditorInstitutions(eq(STATION_CODE), anyList())) + .thenReturn(List.of( + CreditorInstitutionInfo.builder() + .ciTaxCode(expectedCI.getTaxCode()) + .businessName(expectedCI.getInstitutionName()) + .build(), + CreditorInstitutionInfo.builder() + .ciTaxCode(institutionResponse.getTaxCode()) + .businessName(institutionResponse.getDescription()) + .build()) + ); + + CreditorInstitutionInfoResource result = assertDoesNotThrow(() -> + service.getAvailableCreditorInstitutionsForStation(STATION_CODE, BROKER_ID, null)); + + assertNotNull(result); + assertNotNull(result.getCreditorInstitutionInfos()); + assertEquals(2, result.getCreditorInstitutionInfos().size()); + } + @Test void getAvailableCreditorInstitutionsForStationSuccessOnlyWithAddItselfToDelegations() { InstitutionResponse institutionResponse = buildInstitutionResponse(InstitutionType.PA, "1234");