From e7792c671a4d67f62a4f741c88932ac09edd832a Mon Sep 17 00:00:00 2001 From: Loup Theron Date: Thu, 15 Aug 2024 11:29:11 +0200 Subject: [PATCH] Fix double logs sending and pno pdf exist api --- .../GetPriorNotificationPdfDocument.kt | 13 ++++++++-- .../PublicPriorNotificationController.kt | 24 ++++++++++++++++--- ...PublicPriorNotificationControllerITests.kt | 19 ++++++++++++--- .../shared/DownloadButton/index.tsx | 9 ++++--- .../PriorNotification/priorNotificationApi.ts | 20 +++++++++++++++- frontend/src/libs/FrontendError.ts | 7 ++---- 6 files changed, 75 insertions(+), 17 deletions(-) diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/GetPriorNotificationPdfDocument.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/GetPriorNotificationPdfDocument.kt index ccae93601e..e8c0850037 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/GetPriorNotificationPdfDocument.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/GetPriorNotificationPdfDocument.kt @@ -2,13 +2,22 @@ package fr.gouv.cnsp.monitorfish.domain.use_cases.prior_notification import fr.gouv.cnsp.monitorfish.config.UseCase import fr.gouv.cnsp.monitorfish.domain.entities.prior_notification.PdfDocument +import fr.gouv.cnsp.monitorfish.domain.exceptions.BackendUsageException import fr.gouv.cnsp.monitorfish.domain.repositories.PriorNotificationPdfDocumentRepository @UseCase class GetPriorNotificationPdfDocument( private val priorNotificationPdfDocumentRepository: PriorNotificationPdfDocumentRepository, ) { - fun execute(reportId: String): PdfDocument { - return priorNotificationPdfDocumentRepository.findByReportId(reportId) + fun execute(reportId: String, isVerifyingExistence: Boolean): PdfDocument? { + return try { + priorNotificationPdfDocumentRepository.findByReportId(reportId) + } catch (e: BackendUsageException) { + if (isVerifyingExistence) { + return null + } + + throw e + } } } diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/public_api/PublicPriorNotificationController.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/public_api/PublicPriorNotificationController.kt index c4ed61ec00..78d7007d08 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/public_api/PublicPriorNotificationController.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/public_api/PublicPriorNotificationController.kt @@ -28,9 +28,9 @@ class PublicPriorNotificationController( @PathVariable(name = "reportId") reportId: String, ): ResponseEntity { - val pdfDocument = getPriorNotificationPdfDocument.execute(reportId = reportId) - if (pdfDocument.pdfDocument == null) { - ResponseEntity.status(HttpStatus.NOT_FOUND).body(null) + val pdfDocument = getPriorNotificationPdfDocument.execute(reportId = reportId, isVerifyingExistence = false) + if (pdfDocument?.pdfDocument == null) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null) } val fileName = "preavis_debarquement_${pdfDocument.generationDatetimeUtc.format(ISO_DATE_TIME)}.pdf" @@ -44,4 +44,22 @@ class PublicPriorNotificationController( return ResponseEntity(pdfDocument.pdfDocument, headers, HttpStatus.OK) } + + data class Status(val status: String) + + // FIXME Move this API to `/bff` + @GetMapping("/pdf/{reportId}/exist") + @Operation(summary = "Check the PDF document") + fun getPdfDocumentExistence( + @PathParam("Logbook message `reportId`") + @PathVariable(name = "reportId") + reportId: String, + ): Status { + val pdfDocument = getPriorNotificationPdfDocument.execute(reportId = reportId, isVerifyingExistence = true) + if (pdfDocument?.pdfDocument == null) { + return Status(HttpStatus.NO_CONTENT.name) + } + + return Status(HttpStatus.FOUND.name) + } } diff --git a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/public_api/PublicPriorNotificationControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/public_api/PublicPriorNotificationControllerITests.kt index b951755748..dd96fcea7a 100644 --- a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/public_api/PublicPriorNotificationControllerITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/public_api/PublicPriorNotificationControllerITests.kt @@ -5,6 +5,7 @@ import fr.gouv.cnsp.monitorfish.config.SentryConfig import fr.gouv.cnsp.monitorfish.domain.entities.prior_notification.PdfDocument import fr.gouv.cnsp.monitorfish.domain.entities.prior_notification.PriorNotificationSource import fr.gouv.cnsp.monitorfish.domain.use_cases.prior_notification.GetPriorNotificationPdfDocument +import org.hamcrest.Matchers.equalTo import org.junit.jupiter.api.Test import org.mockito.BDDMockito.given import org.springframework.beans.factory.annotation.Autowired @@ -15,8 +16,7 @@ import org.springframework.context.annotation.Import import org.springframework.http.MediaType import org.springframework.test.web.servlet.MockMvc import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get -import org.springframework.test.web.servlet.result.MockMvcResultMatchers.content -import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status +import org.springframework.test.web.servlet.result.MockMvcResultMatchers.* import java.time.ZonedDateTime @Import(SentryConfig::class) @@ -70,7 +70,7 @@ class PublicPriorNotificationControllerITests { """.trimIndent().toByteArray() // Given - given(getPriorNotificationPdfDocument.execute("REPORT_ID")) + given(getPriorNotificationPdfDocument.execute("REPORT_ID", false)) .willReturn( PdfDocument( reportId = "REPORT_ID", @@ -87,4 +87,17 @@ class PublicPriorNotificationControllerITests { .andExpect(content().contentType(MediaType.APPLICATION_PDF)) .andExpect(content().bytes(dummyPdfContent)) } + + @Test + fun `getPdfExistence Should get the PDF existence of a prior notification`() { + // Given + given(getPriorNotificationPdfDocument.execute("REPORT_ID", true)).willReturn(null) + + // When + api.perform(get("/api/v1/prior_notifications/pdf/REPORT_ID/exist")) + // Then + .andExpect(status().isOk) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)) + .andExpect(jsonPath("$.status", equalTo("NO_CONTENT"))) + } } diff --git a/frontend/src/features/PriorNotification/components/shared/DownloadButton/index.tsx b/frontend/src/features/PriorNotification/components/shared/DownloadButton/index.tsx index 8b6933d915..de19fb3c99 100644 --- a/frontend/src/features/PriorNotification/components/shared/DownloadButton/index.tsx +++ b/frontend/src/features/PriorNotification/components/shared/DownloadButton/index.tsx @@ -1,7 +1,10 @@ import { RTK_ONE_MINUTE_POLLING_QUERY_OPTIONS } from '@api/constants' import { useGetGearsQuery } from '@api/gear' import { getAlpha2CodeFromAlpha2or3Code } from '@components/CountryFlag/utils' -import { useGetPriorNotificationPDFQuery } from '@features/PriorNotification/priorNotificationApi' +import { + StatusBodyEnum, + useGetPriorNotificationPDFExistenceQuery +} from '@features/PriorNotification/priorNotificationApi' import { Accent, Button, customDayjs, Dropdown, Icon } from '@mtes-mct/monitor-ui' import printJS from 'print-js' import { useMemo } from 'react' @@ -26,8 +29,8 @@ export function DownloadButton({ }: DownloadButtonProps) { const isSuperUser = useIsSuperUser() const getGearsApiQuery = useGetGearsQuery() - const { isError } = useGetPriorNotificationPDFQuery(reportId, RTK_ONE_MINUTE_POLLING_QUERY_OPTIONS) - const isPriorNotificationPDFDocumentAvailable = useMemo(() => !isError, [isError]) + const { data } = useGetPriorNotificationPDFExistenceQuery(reportId, RTK_ONE_MINUTE_POLLING_QUERY_OPTIONS) + const isPriorNotificationPDFDocumentAvailable = useMemo(() => data?.status === StatusBodyEnum.FOUND, [data]) const hasAuthorizedLandingDownload = isSuperUser && getHasAuthorizedLandingDownload( diff --git a/frontend/src/features/PriorNotification/priorNotificationApi.ts b/frontend/src/features/PriorNotification/priorNotificationApi.ts index 26908ef50e..7a74bc9632 100644 --- a/frontend/src/features/PriorNotification/priorNotificationApi.ts +++ b/frontend/src/features/PriorNotification/priorNotificationApi.ts @@ -22,6 +22,15 @@ const GET_PRIOR_NOTIFICATION_PDF_ERROR_MESSAGE = "Nous n'avons pas pu récupére const VERIFY_AND_SEND_PRIOR_NOTIFICATION_ERROR_MESSAGE = "Nous n'avons pas pu vérifier et envoyer le préavis." const INVALIDATE_PRIOR_NOTIFICATION_ERROR_MESSAGE = "Nous n'avons pas pu invalider et envoyer le préavis." +export enum StatusBodyEnum { + FOUND = 'FOUND', + NO_CONTENT = 'NO_CONTENT' +} + +type StatusBody = { + status: StatusBodyEnum +} + export const priorNotificationApi = monitorfishApi.injectEndpoints({ endpoints: builder => ({ computeManualPriorNotification: builder.mutation< @@ -208,6 +217,15 @@ export const priorNotificationPublicApi = monitorfishPublicApi.injectEndpoints({ url: `/v1/prior_notifications/pdf/${reportId}` }), transformErrorResponse: response => new FrontendApiError(GET_PRIOR_NOTIFICATION_PDF_ERROR_MESSAGE, response) + }), + getPriorNotificationPDFExistence: builder.query({ + extraOptions: { maxRetries: 0 }, + forceRefetch: () => true, + query: reportId => ({ + method: 'GET', + url: `/v1/prior_notifications/pdf/${reportId}/exist` + }), + transformErrorResponse: response => new FrontendApiError(GET_PRIOR_NOTIFICATION_PDF_ERROR_MESSAGE, response) }) }) }) @@ -218,4 +236,4 @@ export const { useGetPriorNotificationTypesQuery } = priorNotificationApi -export const { useGetPriorNotificationPDFQuery } = priorNotificationPublicApi +export const { useGetPriorNotificationPDFExistenceQuery, useGetPriorNotificationPDFQuery } = priorNotificationPublicApi diff --git a/frontend/src/libs/FrontendError.ts b/frontend/src/libs/FrontendError.ts index f86972c175..10ee55bdfe 100644 --- a/frontend/src/libs/FrontendError.ts +++ b/frontend/src/libs/FrontendError.ts @@ -1,6 +1,6 @@ /* eslint-disable no-console */ -import { captureException, captureMessage, Scope } from '@sentry/react' +import { captureException, Scope } from '@sentry/react' export class FrontendError extends Error { #scope: Scope | undefined @@ -30,10 +30,7 @@ export class FrontendError extends Error { } logSentryError() { - captureMessage(this.message, this.scope) - if (this.originalError) { - captureException(this.originalError, this.scope) - } + captureException(new Error(this.message, { cause: this.originalError }), this.scope) } get scope() {