Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PAGOPA-1999] New path paid notice disable #85

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3,480 changes: 1,711 additions & 1,769 deletions openapi/openapi.json

Large diffs are not rendered by default.

1,071 changes: 504 additions & 567 deletions openapi/openapi_ec.json

Large diffs are not rendered by default.

1,438 changes: 699 additions & 739 deletions openapi/openapi_helpdesk.json

Large diffs are not rendered by default.

1,618 changes: 762 additions & 856 deletions openapi/openapi_io.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package it.gov.pagopa.bizeventsservice.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import it.gov.pagopa.bizeventsservice.model.ProblemJson;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotBlank;


@Tag(name = "Paid Notice REST APIs")
@RequestMapping("/paids")
@Validated
public interface IPaidNoticeController {
String X_FISCAL_CODE = "x-fiscal-code";

@Operation(summary = "Disable the paid notice details given its id.", security = {
@SecurityRequirement(name = "ApiKey")}, operationId = "disablePaidNotice")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Event Disabled.",
content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE)),
@ApiResponse(responseCode = "401", description = "Wrong or missing function key.", content = @Content(schema = @Schema())),
@ApiResponse(responseCode = "404", description = "Not found the paid event.", content = @Content(schema = @Schema(implementation = ProblemJson.class))),
@ApiResponse(responseCode = "429", description = "Too many requests.", content = @Content(schema = @Schema())),
@ApiResponse(responseCode = "500", description = "Service unavailable.", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = ProblemJson.class)))})
@PostMapping(value = "/{event-id}/disable", produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<Void> disablePaidNotice(
@RequestHeader(X_FISCAL_CODE) @NotBlank String fiscalCode,
@Parameter(description = "The id of the paid event.", required = true) @NotBlank @PathVariable("event-id") String eventId);


}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public interface ITransactionController {
@GetMapping
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Obtained transaction list.",
headers = @Header(name = X_CONTINUATION_TOKEN, description = "continuation token for paginated query", schema = @Schema(type="string")),
headers = @Header(name = X_CONTINUATION_TOKEN, description = "continuation token for paginated query", schema = @Schema(type = "string")),
content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(name = "TransactionListWrapResponse", implementation = TransactionListWrapResponse.class))),
@ApiResponse(responseCode = "401", description = "Wrong or missing function key.", content = @Content(schema = @Schema())),
@ApiResponse(responseCode = "404", description = "Not found the transaction.", content = @Content(schema = @Schema(implementation = ProblemJson.class))),
Expand All @@ -71,17 +71,17 @@ ResponseEntity<TransactionListWrapResponse> getTransactionList(
@RequestParam(required = false, name = "orderby", defaultValue = "TRANSACTION_DATE") @Parameter(description = "Order by TRANSACTION_DATE") Order.TransactionListOrder orderBy,
@RequestParam(required = false, name = "ordering", defaultValue = "DESC") @Parameter(description = "Direction of ordering") Sort.Direction ordering);


/**
* recovers biz-event data for the transaction list
*
* @param fiscalCode tokenized user fiscal code
* @param isPayer optional flag defining the filter to select only the notices where the user is the payer
* @param isDebtor optional flag defining the filter to select only the notices where the user is the debtor
* @param page optional parameter defining page number, default to 0 (first page)
* @param size optional parameter defining page size, defaults to 10
* @param orderBy optional parameter defining the sort field for the returned list, defaults to TRANSACTION_DATE
* @param ordering optional parameter defining the sorting direction of the returned list, defaults to DESC
* @param fiscalCode tokenized user fiscal code
* @param isPayer optional flag defining the filter to select only the notices where the user is the payer
* @param isDebtor optional flag defining the filter to select only the notices where the user is the debtor
* @param page optional parameter defining page number, default to 0 (first page)
* @param size optional parameter defining page size, defaults to 10
* @param orderBy optional parameter defining the sort field for the returned list, defaults to TRANSACTION_DATE
* @param ordering optional parameter defining the sorting direction of the returned list, defaults to DESC
* @return the transaction list
*/
@GetMapping(value = "/cached", produces = MediaType.APPLICATION_JSON_VALUE)
Expand Down Expand Up @@ -117,7 +117,13 @@ ResponseEntity<TransactionDetailResponse> getTransactionDetails(
@RequestHeader("x-fiscal-code") @NotBlank String fiscalCode,
@Parameter(description = "The id of the transaction.", required = true) @NotBlank @PathVariable("transaction-id") String transactionId);

@Operation(summary = "Disable the transaction details given its id.", security = {
/**
* @param fiscalCode
* @param transactionId
* @return
* @deprecated
*/
@Operation(summary = "Disable the transaction details given its id.", description = "This operation is deprecated. Use Paid Notice APIs instead", deprecated = true, security = {
@SecurityRequirement(name = "ApiKey")}, operationId = "disableTransaction")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Disabled Transactions.",
Expand All @@ -127,22 +133,23 @@ ResponseEntity<TransactionDetailResponse> getTransactionDetails(
@ApiResponse(responseCode = "429", description = "Too many requests.", content = @Content(schema = @Schema())),
@ApiResponse(responseCode = "500", description = "Service unavailable.", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = ProblemJson.class)))})
@PostMapping(value = "/{transaction-id}/disable", produces = MediaType.APPLICATION_JSON_VALUE)
@Deprecated(forRemoval = false)
ResponseEntity<Void> disableTransaction(
@RequestHeader("x-fiscal-code") @NotBlank String fiscalCode,
@Parameter(description = "The id of the transaction.", required = true) @NotBlank @PathVariable("transaction-id") String transactionId);

@Operation(summary = "Retrieve the PDF receipt given event id.", security = {
@SecurityRequirement(name = "ApiKey")}, operationId = "getPDFReceipt")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Obtained the PDF receipt.", content = @Content(mediaType = MediaType.APPLICATION_PDF_VALUE, schema = @Schema( type = "string", format = "binary"))),
@ApiResponse(responseCode = "200", description = "Obtained the PDF receipt.", content = @Content(mediaType = MediaType.APPLICATION_PDF_VALUE, schema = @Schema(type = "string", format = "binary"))),
@ApiResponse(responseCode = "401", description = "Wrong or missing function key.", content = @Content(schema = @Schema())),
@ApiResponse(responseCode = "404", description = "Not found the receipt.", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = ProblemJson.class))),
@ApiResponse(responseCode = "422", description = "Unprocessable receipt.", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = ProblemJson.class))),
@ApiResponse(responseCode = "429", description = "Too many requests.", content = @Content(schema = @Schema())),
@ApiResponse(responseCode = "500", description = "Service unavailable.", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = ProblemJson.class)))})
@GetMapping(value = "/{event-id}/pdf")
ResponseEntity<byte[]> getPDFReceipt(
@RequestHeader("x-fiscal-code") @NotBlank String fiscalCode,
@RequestHeader("x-fiscal-code") @NotBlank String fiscalCode,
@Parameter(description = "The id of the event.", required = true) @NotBlank @PathVariable("event-id") String eventId);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package it.gov.pagopa.bizeventsservice.controller.impl;

import it.gov.pagopa.bizeventsservice.controller.IPaidNoticeController;
import it.gov.pagopa.bizeventsservice.service.ITransactionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;

/**
* Implementation of {@link IPaidNoticeController} that contains the Rest Controller
* for events services
*/
@RestController
public class PaidNoticeController implements IPaidNoticeController {

private final ITransactionService transactionService;

@Autowired
public PaidNoticeController(ITransactionService transactionService) {
this.transactionService = transactionService;
}


@Override
public ResponseEntity<Void> disablePaidNotice(String fiscalCode, String transactionId) {
transactionService.disableTransaction(fiscalCode, transactionId);
return new ResponseEntity<>(HttpStatus.OK);
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package it.gov.pagopa.bizeventsservice.controller;


import it.gov.pagopa.bizeventsservice.exception.AppError;
import it.gov.pagopa.bizeventsservice.exception.AppException;
import it.gov.pagopa.bizeventsservice.model.response.transaction.TransactionDetailResponse;
import it.gov.pagopa.bizeventsservice.model.response.transaction.TransactionListItem;
import it.gov.pagopa.bizeventsservice.model.response.transaction.TransactionListResponse;
import it.gov.pagopa.bizeventsservice.service.ITransactionService;
import it.gov.pagopa.bizeventsservice.util.Utility;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;

import java.io.IOException;
import java.util.List;

import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@SpringBootTest
@AutoConfigureMockMvc
public class PaidNoticeControllerTest {

public static final String INVALID_FISCAL_CODE = "INVALID_TX_FISCAL_CODE";
public static final String VALID_FISCAL_CODE = "AAAAAA00A00A000A";
public static final String FISCAL_CODE_HEADER_KEY = "x-fiscal-code";
public static final String PAIDS_EVENT_ID_DISABLE_PATH = "/paids/1234321234/disable";

@Autowired
private MockMvc mvc;

@MockBean
private ITransactionService transactionService;


private byte[] receipt = {69, 121, 101, 45, 62, 118, 101, 114, (byte) 196, (byte) 195, 61, 101, 98};

@BeforeEach
void setUp() throws IOException {
// precondition
List<TransactionListItem> transactionListItems = Utility.readModelFromFile("biz-events/getTransactionList.json", List.class);
TransactionListResponse transactionListResponse = TransactionListResponse.builder().transactionList(transactionListItems).build();
TransactionDetailResponse transactionDetailResponse = Utility.readModelFromFile("biz-events/transactionDetails.json", TransactionDetailResponse.class);
when(transactionService.getTransactionList(eq(VALID_FISCAL_CODE), any(), any(), anyString(), anyInt(), any(), any())).thenReturn(transactionListResponse);
when(transactionService.getCachedTransactionList(eq(VALID_FISCAL_CODE), any(), any(), anyInt(), anyInt(), any(), any())).thenReturn(transactionListResponse);
when(transactionService.getTransactionDetails(anyString(), anyString())).thenReturn(transactionDetailResponse);
when(transactionService.getPDFReceipt(anyString(), anyString())).thenReturn(receipt);
}

@Test
void getTransactionDisableShouldReturnOK() throws Exception {
mvc.perform(post(PAIDS_EVENT_ID_DISABLE_PATH)
.header(FISCAL_CODE_HEADER_KEY, VALID_FISCAL_CODE)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andReturn();
verify(transactionService).disableTransaction(any(), any());
}

@Test
void getTransactionDisableWithMissingFiscalCodeShouldReturnError() throws Exception {
mvc.perform(post(PAIDS_EVENT_ID_DISABLE_PATH)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isBadRequest())
.andReturn();
}

@Test
void getTransactionDisableWithInvalidFiscalCodeShouldReturnError() throws Exception {
doAnswer(x -> {
throw new AppException(AppError.INVALID_FISCAL_CODE, INVALID_FISCAL_CODE);
}).when(transactionService).disableTransaction(anyString(), anyString());
mvc.perform(post(PAIDS_EVENT_ID_DISABLE_PATH)
.header(FISCAL_CODE_HEADER_KEY, INVALID_FISCAL_CODE)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isBadRequest())
.andReturn();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import java.io.IOException;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down
2 changes: 1 addition & 1 deletion src/test/resources/receipts/getOrganizationReceipt.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"city": null,
"stateProvinceRegion": null,
"country": null,
"email": null
"eMail": null
},
"transferList": [
{
Expand Down
Loading