Skip to content

Commit

Permalink
[VAS-1113] feat: Improvement get available CI for station api (#56)
Browse files Browse the repository at this point in the history
* [VAS-1113] updated model

* [VAS-1113] updated get available creditor institutions for station API

* [VAS-1113] fixed db schema

* [VAS-1113] updated unit tests

* [VAS-1113] updated openapi

* Bump to version 1.11.4-1-VAS-1113-improvement-get-available-ci-for-station-api [skip ci]

---------

Co-authored-by: pagopa-github-bot <[email protected]>
  • Loading branch information
gioelemella and pagopa-github-bot authored Jun 17, 2024
1 parent 7d37412 commit 6f1b30b
Show file tree
Hide file tree
Showing 15 changed files with 88 additions and 33 deletions.
4 changes: 2 additions & 2 deletions helm/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ apiVersion: v2
name: pagopa-api-config-selfcare-integration
description: Microservice that manages requests from selfcare
type: application
version: 1.95.0
appVersion: 1.11.4
version: 1.96.0
appVersion: 1.11.4-1-VAS-1113-improvement-get-available-ci-for-station-api
dependencies:
- name: microservice-chart
version: 2.8.0
Expand Down
2 changes: 1 addition & 1 deletion helm/values-dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ microservice-chart: &microservice-chart
envSecret: {}
image:
repository: ghcr.io/pagopa/pagopa-api-config-selfcare-integration
tag: "1.11.4"
tag: "1.11.4-1-VAS-1113-improvement-get-available-ci-for-station-api"
pullPolicy: Always
livenessProbe:
httpGet:
Expand Down
2 changes: 1 addition & 1 deletion helm/values-prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ microservice-chart: &microservice-chart
envSecret: {}
image:
repository: ghcr.io/pagopa/pagopa-api-config-selfcare-integration
tag: "1.11.4"
tag: "1.11.4-1-VAS-1113-improvement-get-available-ci-for-station-api"
pullPolicy: Always
livenessProbe:
httpGet:
Expand Down
2 changes: 1 addition & 1 deletion helm/values-uat.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ microservice-chart: &microservice-chart
envSecret: {}
image:
repository: ghcr.io/pagopa/pagopa-api-config-selfcare-integration
tag: "1.11.4"
tag: "1.11.4-1-VAS-1113-improvement-get-available-ci-for-station-api"
pullPolicy: Always
livenessProbe:
httpGet:
Expand Down
24 changes: 19 additions & 5 deletions openapi/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"title": "API-Config - SelfCare Integration",
"description": "Spring application exposes APIs for SelfCare",
"termsOfService": "https://www.pagopa.gov.it/",
"version": "1.11.4"
"version": "1.11.4-1-VAS-1113-improvement-get-available-ci-for-station-api"
},
"servers": [
{
Expand Down Expand Up @@ -667,7 +667,7 @@
"tags": [
"Creditor Institutions"
],
"summary": "Get the list of creditor institutions associated to a station",
"summary": "Get the list of creditor institutions that can be associated to a station",
"operationId": "getStationCreditorInstitutions",
"parameters": [
{
Expand All @@ -678,6 +678,20 @@
"schema": {
"type": "string"
}
},
{
"name": "ciTaxCodeList",
"in": "query",
"description": "List of Creditor Institution's tax code, restrict the research to this tax code list only",
"required": true,
"schema": {
"maxItems": 10,
"minItems": 0,
"type": "array",
"items": {
"type": "string"
}
}
}
],
"responses": {
Expand All @@ -696,7 +710,7 @@
"schema": {
"type": "array",
"items": {
"type": "string"
"$ref": "#/components/schemas/CreditorInstitutionInfo"
}
}
}
Expand Down Expand Up @@ -2263,7 +2277,7 @@
"CreditorInstitutionInfo": {
"required": [
"business_name",
"creditor_institution_code"
"ci_tax_code"
],
"type": "object",
"properties": {
Expand All @@ -2272,7 +2286,7 @@
"description": "The business name of the creditor institution",
"example": "Comune di Roma"
},
"creditor_institution_code": {
"ci_tax_code": {
"type": "string",
"description": "The tax code of the creditor institution",
"example": "02438750586"
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

<groupId>it.gov.pagopa.api-config</groupId>
<artifactId>selfcareintegration</artifactId>
<version>1.11.4</version>
<version>1.11.4-1-VAS-1113-improvement-get-available-ci-for-station-api</version>
<name>API-Config - SelfCare Integration</name>
<description>Spring application exposes APIs for SelfCare</description>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,12 @@ public ResponseEntity<StationDetailsList> getStationsDetailsFromCreditorInstitut
* code 500)
*/
@Operation(
summary = "Get the list of creditor institutions associated to a station",
summary = "Get the list of creditor institutions that can be associated to a station",
security = {@SecurityRequirement(name = "ApiKey"), @SecurityRequirement(name = "Authorization")})
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "OK",
content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
array = @ArraySchema(schema = @Schema(implementation = String.class)))),
array = @ArraySchema(schema = @Schema(implementation = CreditorInstitutionInfo.class)))),
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = ProblemJson.class))),
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(schema = @Schema())),
@ApiResponse(responseCode = "403", description = "Forbidden", content = @Content(schema = @Schema())),
Expand All @@ -102,10 +102,11 @@ public ResponseEntity<StationDetailsList> getStationsDetailsFromCreditorInstitut
content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = ProblemJson.class)))
})
@GetMapping(value = "/stations/{station-code}", produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<List<String>> getStationCreditorInstitutions(
@Parameter(description = "Station's code") @PathVariable("station-code") String stationCode
public ResponseEntity<List<CreditorInstitutionInfo>> getStationCreditorInstitutions(
@Parameter(description = "Station's code") @PathVariable("station-code") String stationCode,
@Parameter(description = "List of Creditor Institution's tax code, restrict the research to this tax code list only") @RequestParam @Size(max = 10) List<String> ciTaxCodeList
) {
return ResponseEntity.ok(this.creditorInstitutionsService.getStationCreditorInstitutions(stationCode));
return ResponseEntity.ok(this.creditorInstitutionsService.getStationCreditorInstitutions(stationCode, ciTaxCodeList));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public enum AppError {
"Creditor Institutions not found",
"No Creditor Institutions found with codes: %s"),
STATION_NOT_FOUND(HttpStatus.NOT_FOUND, "Station not found", "No Station found with code: %s"),
PA_NOT_FOUND(HttpStatus.NOT_FOUND, "PA not found", "No PA found with code: %s"),


BROKER_NOT_FOUND(HttpStatus.NOT_FOUND, "Broker not found", "No Broker found with code: %s"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class ConvertPaToCreditorInstitutionInfo implements Converter<Pa, Credito
public CreditorInstitutionInfo convert(MappingContext<Pa, CreditorInstitutionInfo> context) {
@Valid Pa pa = context.getSource();
return CreditorInstitutionInfo.builder()
.creditorInstitutionCode(pa.getIdDominio())
.ciTaxCode(pa.getIdDominio())
.businessName(pa.getRagioneSociale() != null ? pa.getRagioneSociale() : "")
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ public class CreditorInstitutionInfo {
@NotNull
private String businessName;

@JsonProperty("creditor_institution_code")
@JsonProperty("ci_tax_code")
@Schema(example = "02438750586", description = "The tax code of the creditor institution", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank
private String creditorInstitutionCode;
private String ciTaxCode;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package it.gov.pagopa.apiconfig.selfcareintegration.repository;

import it.gov.pagopa.apiconfig.starter.entity.Pa;
import it.gov.pagopa.apiconfig.starter.entity.PaStazionePa;
import it.gov.pagopa.apiconfig.starter.entity.Stazioni;
import it.gov.pagopa.apiconfig.starter.repository.PaStazionePaRepository;
Expand All @@ -18,5 +19,5 @@ public interface ExtendedCreditorInstitutionStationRepository extends PaStazione

Page<PaStazionePa> findByFkPa(@Param("fkPa") Long creditorInstitutionId, Pageable pageable);

List<PaStazionePa> findByFkStazione(@Param("fkStazione") Stazioni station);
List<PaStazionePa> findByFkStazioneAndPaIn(@Param("fkStazione") Stazioni station, @Param("pa") List<Pa> paList);
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,14 +149,21 @@ public List<CreditorInstitutionInfo> getCreditorInstitutionInfoList(List<String>
* @param stationCode station's code
* @return the list of creditor institution's tax codes
*/
public List<String> getStationCreditorInstitutions(String stationCode) {
public List<CreditorInstitutionInfo> getStationCreditorInstitutions(String stationCode, List<String> ciTaxCodeList) {
Stazioni station = this.stationRepository.findByIdStazione(stationCode)
.orElseThrow(() -> new AppException(AppError.STATION_NOT_FOUND, stationCode));

List<PaStazionePa> stazionePaList = this.ciStationRepository.findByFkStazione(station);
return stazionePaList.stream()
List<Pa> paList = this.paRepository.findByIdDominioIn(ciTaxCodeList)
.orElseThrow(() -> new AppException(AppError.PA_NOT_FOUND, ciTaxCodeList));

List<String> stazionePaList = this.ciStationRepository.findByFkStazioneAndPaIn(station, paList).stream()
.map(paStazionePa -> paStazionePa.getPa().getIdDominio())
.toList();

return paList.parallelStream()
.filter(pa -> !stazionePaList.contains(pa.getIdDominio()))
.map(pa -> this.modelMapper.map(pa, CreditorInstitutionInfo.class))
.toList();
}

private CIAssociatedCodeList extractUsedAndUnusedCodes(
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/h2/schema-h2.sql
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ create table NODO4_CFG.STAZIONI
TARGET_HOST_POF varchar(100),
TARGET_PORT_POF numeric,
TARGET_PATH_POF varchar(100),
FLAG_STANDIN char not null default 'N',
VERSIONE_PRIMITIVE numeric(2) default 1,
constraint PK_STAZIONI
primary key (OBJ_ID),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,13 @@ void getCreditorInstitutionsTest() throws Exception {

@Test
void getStationCreditorInstitutionsTest() throws Exception {
List<String> ciTaxCodes = Collections.singletonList("ciTaxCode");

when(creditorInstitutionsService.getStationCreditorInstitutions("stationCode"))
.thenReturn(Collections.singletonList("ciTaxCode"));
when(creditorInstitutionsService.getStationCreditorInstitutions("stationCode", ciTaxCodes))
.thenReturn(Collections.singletonList(CreditorInstitutionInfo.builder().build()));

mvc.perform(get("/creditorinstitutions/stations/{station-code}", "stationCode"))
mvc.perform(get("/creditorinstitutions/stations/{station-code}", "stationCode")
.param("ciTaxCodeList", String.valueOf(ciTaxCodes)))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
Expand All @@ -58,6 +58,7 @@ class CreditorInstitutionsServiceTest {
private static final String CI_TAX_CODE = "1234";
private static final String TARGET_CI_TAX_CODE = "targetCITaxCode";
private static final String STATION_CODE = "stationCode";
private static final String RAGIONE_SOCIALE = "pa";

@MockBean
private PaRepository paRepository;
Expand Down Expand Up @@ -218,7 +219,7 @@ void getCreditorInstitutionInfoListSuccess() throws IOException {
assertNotNull(result);
assertEquals(1, result.size());
CreditorInstitutionInfo ci = result.get(0);
assertEquals(pa.getIdDominio(), ci.getCreditorInstitutionCode());
assertEquals(pa.getIdDominio(), ci.getCiTaxCode());
assertEquals(pa.getRagioneSociale(), ci.getBusinessName());
}

Expand Down Expand Up @@ -253,24 +254,51 @@ void getCreditorInstitutionInfoListFailInternalServerError() throws IOException
void getStationCreditorInstitutionsSuccess() throws IOException {
Stazioni stazioni = getMockStazioni();
PaStazionePa paStazionePa = getMockPaStazionePa();
Pa pa = getMockPa();
List<String> ciTaxCodes = List.of(CI_TAX_CODE, pa.getIdDominio());
List<Pa> paList = List.of(pa, Pa.builder().idDominio(CI_TAX_CODE).ragioneSociale(RAGIONE_SOCIALE).build());

when(stationRepository.findByIdStazione(STATION_CODE)).thenReturn(Optional.of(stazioni));
when(ciStationRepository.findByFkStazione(stazioni)).thenReturn(Collections.singletonList(paStazionePa));
when(paRepository.findByIdDominioIn(ciTaxCodes)).thenReturn(Optional.of(paList));
when(ciStationRepository.findByFkStazioneAndPaIn(stazioni, paList)).thenReturn(Collections.singletonList(paStazionePa));

List<String> result = assertDoesNotThrow(() -> creditorInstitutionsService.getStationCreditorInstitutions(STATION_CODE));
List<CreditorInstitutionInfo> result = assertDoesNotThrow(() ->
creditorInstitutionsService.getStationCreditorInstitutions(STATION_CODE, ciTaxCodes));

assertNotNull(result);
assertEquals(1, result.size());
assertEquals(RAGIONE_SOCIALE, result.get(0).getBusinessName());
assertEquals(CI_TAX_CODE, result.get(0).getCiTaxCode());
}

@Test
void getStationCreditorInstitutionsFailNotFound() {
void getStationCreditorInstitutionsFailStationNotFound() {
List<String> ciTaxCodes = Collections.singletonList(CI_TAX_CODE);

when(stationRepository.findByIdStazione(STATION_CODE)).thenReturn(Optional.empty());

AppException e = assertThrows(AppException.class, () -> creditorInstitutionsService.getStationCreditorInstitutions(STATION_CODE));
AppException e = assertThrows(AppException.class, () -> creditorInstitutionsService.getStationCreditorInstitutions(STATION_CODE, ciTaxCodes));

assertNotNull(e);
assertEquals(HttpStatus.NOT_FOUND, e.getHttpStatus());

verify(paRepository, never()).findByIdDominioIn(anyList());
verify(ciStationRepository, never()).findByFkStazioneAndPaIn(any(), anyList());
}

@Test
void getStationCreditorInstitutionsFailPaNotFound() throws IOException {
List<String> ciTaxCodes = Collections.singletonList(CI_TAX_CODE);
Stazioni stazioni = getMockStazioni();

when(stationRepository.findByIdStazione(STATION_CODE)).thenReturn(Optional.of(stazioni));
when(paRepository.findByIdDominioIn(ciTaxCodes)).thenReturn(Optional.empty());

AppException e = assertThrows(AppException.class, () -> creditorInstitutionsService.getStationCreditorInstitutions(STATION_CODE, ciTaxCodes));

assertNotNull(e);
assertEquals(HttpStatus.NOT_FOUND, e.getHttpStatus());

verify(ciStationRepository, never()).findByFkStazione(any());
verify(ciStationRepository, never()).findByFkStazioneAndPaIn(any(), anyList());
}
}

0 comments on commit 6f1b30b

Please sign in to comment.