Skip to content

Commit

Permalink
Signalements - Retouches UI (#3644)
Browse files Browse the repository at this point in the history
## Linked issues

- Resolve #3188
- Resolve #3183
- #3594
- Ajout de documentation dans le Makefile:
![Screenshot from 2024-09-13
11-27-53](https://github.com/user-attachments/assets/ec585dca-0432-4c6e-b468-b74623ff3bba)

----

- [ ] Tests E2E (Cypress)
  • Loading branch information
louptheron committed Sep 13, 2024
2 parents 50651aa + a1135c5 commit 3095b37
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 93 deletions.
171 changes: 114 additions & 57 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,37 @@
INFRA_FOLDER="$(shell pwd)/infra/configurations/"
HOST_MIGRATIONS_FOLDER=$(shell pwd)/backend/src/main/resources/db/migration

.PHONY: clean install test
SHELL := /bin/bash
.SHELLFLAGS = -ec
.SILENT:
MAKEFLAGS += --silent
.ONESHELL:

.DEFAULT_GOAL: help

.PHONY: help ##OTHER 🛟 To display this prompts. This will list all available targets with their documentation
help:
echo "❓ Use \`make <target>' where <target> is one of 👇"
echo ""
echo -e "\033[1mLocal Development\033[0m:"
grep -E '^\.PHONY: [a-zA-Z0-9_-]+ .*?##LOCAL' $(MAKEFILE_LIST) | \
awk 'BEGIN {FS = "(: |##LOCAL)"}; {printf "\033[36m%-30s\033[0m %s\n", $$2, $$3}'
echo ""
echo -e "\033[1mTesting\033[0m:"
grep -E '^\.PHONY: [a-zA-Z0-9_-]+ .*?##TEST' $(MAKEFILE_LIST) | \
awk 'BEGIN {FS = "(: |##TEST)"}; {printf "\033[36m%-30s\033[0m %s\n", $$2, $$3}'
echo ""
echo -e "\033[1mCommands for RUN (STAGING and PROD)\033[0m:"
grep -E '^\.PHONY: [a-zA-Z0-9_-]+ .*?##RUN' $(MAKEFILE_LIST) | \
awk 'BEGIN {FS = "(: |##RUN)"}; {printf "\033[36m%-30s\033[0m %s\n", $$2, $$3}'
echo ""
echo -e "\033[1mOther commands\033[0m:"
grep -E '^\.PHONY: [a-zA-Z0-9_-]+ .*?##OTHER' $(MAKEFILE_LIST) | \
awk 'BEGIN {FS = "(: |##OTHER)"}; {printf "\033[36m%-30s\033[0m %s\n", $$2, $$3}'
echo ""
echo "Tips 💡"
echo " - use tab for auto-completion"
echo " - use the dry run option '-n' to show what make is attempting to do. example: environmentName=dev make -n deploy"

docker-env:
cd ./infra/docker && ../../frontend/node_modules/.bin/import-meta-env-prepare -u -x ./.env.local.defaults\
Expand All @@ -10,9 +40,11 @@ docker-env:
################################################################################
# Local Development

check-clean-archi:
.PHONY: check-clean-archi ##LOCAL Check clean architecture imports
check-clean-archi:
cd backend/tools && ./check-clean-architecture.sh

.PHONY: clean ##LOCAL Clean all backend assets and stop docker containers
clean: docker-env
rm -Rf ./backend/target
docker compose down -v
Expand All @@ -26,31 +58,39 @@ compile-back:
init-local-sig:
./infra/local/postgis_insert_layers.sh && ./infra/init/geoserver_init_layers.sh

.PHONY: install-front ##LOCAL ⬇️ Install frontend dependencies
install-front:
cd ./frontend && npm i

.PHONY: run-back ##LOCAL ▶️ Run backend API
run-back: run-stubbed-apis
docker compose up -d --quiet-pull --wait db keycloak
cd backend && ./gradlew bootRun --args='--spring.profiles.active=local --spring.config.additional-location=$(INFRA_FOLDER)'

run-back-for-cypress: run-stubbed-apis
docker compose up -d --quiet-pull --wait db keycloak
cd backend && MONITORFISH_OIDC_ENABLED=false ./gradlew bootRun --args='--spring.profiles.active=local --spring.config.additional-location=$(INFRA_FOLDER)'
.PHONY: run-front ##LOCAL ▶️ Run frontend for development
run-front:
cd ./frontend && npm run dev

.PHONY: run-back-with-monitorenv ##LOCAL ▶️ Run backend API when running MonitorEnv app (in another terminal)
run-back-with-monitorenv: run-monitorenv
docker compose up -d --quiet-pull --wait db
cd backend && MONITORENV_URL=http://localhost:9880 ./gradlew bootRun --args='--spring.profiles.active=local --spring.config.additional-location=$(INFRA_FOLDER)'

run-front:
cd ./frontend && npm run dev

.PHONY: run-monitorenv ##LOCAL ▶️ Run MonitorEnv app containers
run-monitorenv: docker-env
docker compose \
--project-directory ./infra/docker \
--env-file ./infra/docker/.env \
-f ./infra/docker/docker-compose.monitorenv.dev.yml \
up -d monitorenv_app

.PHONY: lint-back ##LOCAL 🪮 ✨ Lint and format backend code
lint-back:
cd ./backend && ./gradlew ktlintFormat | grep -v \
-e "Exceeded max line length" \
-e "Package name must not contain underscore" \
-e "Wildcard import"

run-stubbed-apis:
docker compose stop geoserver-monitorenv-stubs
docker compose up -d --quiet-pull --wait geoserver-monitorenv-stubs
Expand All @@ -71,6 +111,72 @@ dev-restore-db:
@export CONFIG_FILE_PATH=$$(pwd)/infra/dev/database/pg_backup.config; \
./infra/remote/backup/pg_restore.sh -t "$(TAG)"

################################################################################
# Testing

.PHONY: test ##TEST ✅ Run all tests
test: test-back
cd frontend && CI=true npm run test:unit -- --coverage

.PHONY: run-back-for-cypress ##TEST ▶️ Run backend API when using Cypress 📝
run-back-for-cypress: run-stubbed-apis
docker compose up -d --quiet-pull --wait db keycloak
cd backend && MONITORFISH_OIDC_ENABLED=false ./gradlew bootRun --args='--spring.profiles.active=local --spring.config.additional-location=$(INFRA_FOLDER)'

.PHONY: run-front-for-cypress ##TEST ▶️ Run frontend when using Cypress 📝
run-front-for-cypress:
cd ./frontend && npm run dev-cypress

.PHONY: run-cypress ##TEST ▶️ Run Cypress 📝
run-cypress:
cd ./frontend && npm run test:e2e:open

test-back: check-clean-archi
@if [ -z "$(class)" ]; then \
echo "Running all Backend tests..."; \
cd backend && ./gradlew clean test; \
else \
echo "Running single Backend test class $(class)..."; \
cd backend && ./gradlew test --console plain --no-continue --parallel --tests "$(class)"; \
fi

.PHONY: test-back-watch ##TEST ✅ Watch backend tests
test-back-watch:
./backend/scripts/test-watch.sh

.PHONY: run-back-for-puppeteer ##TEST ▶️ Run backend API when using Puppeteer 📝
run-back-for-puppeteer: docker-env run-stubbed-apis
docker compose up -d --quiet-pull --wait db
docker compose -f ./infra/docker/docker-compose.puppeteer.yml up -d monitorenv-app
cd backend && MONITORENV_URL=http://localhost:9880 ./gradlew bootRun --args='--spring.profiles.active=local --spring.config.additional-location=$(INFRA_FOLDER)'

.PHONY: run-front-for-puppeteer ##TEST ▶️ Run frontend when using Puppeteer 📝
run-front-for-puppeteer:
cd ./frontend && npm run dev-puppeteer

################################################################################
# Remote (Integration / Production)

# ----------------------------------------------------------
# Remote: Run commands

.PHONY: restart-remote-app ##RUN ▶️ Restart app
restart-remote-app:
cd infra/remote && docker compose pull && docker compose up -d --build app --force-recreate

.PHONY: register-pipeline-flows-prod ##RUN ▶️ Register pipeline flows in PROD
register-pipeline-flows-prod:
docker pull docker.pkg.github.com/mtes-mct/monitorfish/monitorfish-pipeline:$(MONITORFISH_VERSION) && \
infra/remote/data-pipeline/register-flows-prod.sh

.PHONY: register-pipeline-flows-int ##RUN ▶️ Register pipeline flows in STAGING
register-pipeline-flows-int:
docker pull docker.pkg.github.com/mtes-mct/monitorfish/monitorfish-pipeline:$(MONITORFISH_VERSION) && \
infra/remote/data-pipeline/register-flows-int.sh

.PHONY: init-remote-sig ##RUN Initialize Geoserver layers
init-remote-sig:
./infra/remote/postgis_insert_layers.sh && ./infra/init/geoserver_init_layers.sh

################################################################################
# Database upgrade
Expand Down Expand Up @@ -113,38 +219,6 @@ add_timescaledb_to_shared_preload_libraries:
bash -c "echo \"shared_preload_libraries = 'timescaledb'\" >> /var/lib/postgresql/data/postgresql.conf";


################################################################################
# Testing

test: test-back
cd frontend && CI=true npm run test:unit -- --coverage

test-back: check-clean-archi
@if [ -z "$(class)" ]; then \
echo "Running all Backend tests..."; \
cd backend && ./gradlew clean test; \
else \
echo "Running single Backend test class $(class)..."; \
cd backend && ./gradlew test --console plain --no-continue --parallel --tests "$(class)"; \
fi

test-back-watch:
./backend/scripts/test-watch.sh

lint-back:
cd ./backend && ./gradlew ktlintFormat | grep -v \
-e "Exceeded max line length" \
-e "Package name must not contain underscore" \
-e "Wildcard import"

run-back-for-puppeteer: docker-env run-stubbed-apis
docker compose up -d --quiet-pull --wait db
docker compose -f ./infra/docker/docker-compose.puppeteer.yml up -d monitorenv-app
cd backend && MONITORENV_URL=http://localhost:9880 ./gradlew bootRun --args='--spring.profiles.active=local --spring.config.additional-location=$(INFRA_FOLDER)'

run-front-for-puppeteer:
cd ./frontend && npm run dev-puppeteer


################################################################################
# CI
Expand Down Expand Up @@ -195,23 +269,6 @@ docker-push-pipeline:
docker push docker.pkg.github.com/mtes-mct/monitorfish/monitorfish-pipeline:$(VERSION)


################################################################################
# Remote (Integration / Production)

# ----------------------------------------------------------
# Remote: Run commands

init-remote-sig:
./infra/remote/postgis_insert_layers.sh && ./infra/init/geoserver_init_layers.sh
restart-remote-app:
cd infra/remote && docker compose pull && docker compose up -d --build app --force-recreate

register-pipeline-flows-prod:
docker pull docker.pkg.github.com/mtes-mct/monitorfish/monitorfish-pipeline:$(MONITORFISH_VERSION) && \
infra/remote/data-pipeline/register-flows-prod.sh
register-pipeline-flows-int:
docker pull docker.pkg.github.com/mtes-mct/monitorfish/monitorfish-pipeline:$(MONITORFISH_VERSION) && \
infra/remote/data-pipeline/register-flows-int.sh

# ----------------------------------------------------------
# Remote: Pipeline commands
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import fr.gouv.cnsp.monitorfish.domain.repositories.ReportingRepository
import fr.gouv.cnsp.monitorfish.domain.use_cases.control_units.GetAllControlUnits
import org.slf4j.LoggerFactory
import java.time.ZonedDateTime
import kotlin.time.measureTimedValue

@UseCase
class GetVesselReportings(
Expand All @@ -29,41 +30,51 @@ class GetVesselReportings(
vesselIdentifier: VesselIdentifier?,
fromDate: ZonedDateTime,
): VesselReportings {
val controlUnits = getAllControlUnits.execute()

val reportings =
findReportings(
val (controlUnits, controlUnitsTimeTaken) = measureTimedValue { getAllControlUnits.execute() }
logger.info("TIME_RECORD - 'getAllControlUnits' took $controlUnitsTimeTaken")

val (reportings, reportingsTimeTaken) =
measureTimedValue { findReportings(
vesselId,
vesselIdentifier,
internalReferenceNumber,
fromDate,
ircs,
externalReferenceNumber,
)
) }
logger.info("TIME_RECORD - 'findReportings' took $reportingsTimeTaken")

val current =
getReportingsAndOccurrences(reportings.filter { !it.isArchived })
.sortedWith(compareByDescending { it.reporting.validationDate ?: it.reporting.creationDate })
.map { reportingAndOccurrences ->
enrichWithInfractionAndControlUnit(reportingAndOccurrences, controlUnits)
}

val yearsRange = fromDate.year..ZonedDateTime.now().year
val archivedYearsToReportings =
yearsRange.associateWith { year ->
val reportingsOfYear =
reportings
.filter { it.isArchived }
.filter { filterByYear(it, year) }

getReportingsAndOccurrences(reportingsOfYear)
val (current, currentTimeTaken) =
measureTimedValue {
getReportingsAndOccurrences(reportings.filter { !it.isArchived })
.sortedWith(compareByDescending { it.reporting.validationDate ?: it.reporting.creationDate })
.map { reportingAndOccurrences ->
enrichWithInfractionAndControlUnit(reportingAndOccurrences, controlUnits)
}
}
logger.info("TIME_RECORD - 'current' took $currentTimeTaken")

val yearsRange = fromDate.year..ZonedDateTime.now().year
val (archivedYearsToReportings, archivedYearsToReportingsTimeTaken) =
measureTimedValue {
yearsRange.associateWith { year ->
val reportingsOfYear =
reportings
.filter { it.isArchived }
.filter { filterByYear(it, year) }

getReportingsAndOccurrences(reportingsOfYear)
.sortedWith(compareByDescending { it.reporting.validationDate ?: it.reporting.creationDate })
.map { reportingAndOccurrences ->
enrichWithInfractionAndControlUnit(reportingAndOccurrences, controlUnits)
}
}
}
logger.info("TIME_RECORD - 'archivedYearsToReportings' took $archivedYearsToReportingsTimeTaken")

val infractionSuspicionsSummary = getInfractionSuspicionsSummary(reportings.filter { it.isArchived })
val (infractionSuspicionsSummary, infractionSuspicionsSummaryTimeTaken) = measureTimedValue { getInfractionSuspicionsSummary(reportings.filter { it.isArchived }) }
logger.info("TIME_RECORD - 'infractionSuspicionsSummary' took $infractionSuspicionsSummaryTimeTaken")
val numberOfInfractionSuspicions = infractionSuspicionsSummary.sumOf { it.numberOfOccurrences }
val numberOfObservation =
reportings
Expand Down Expand Up @@ -93,7 +104,7 @@ class GetVesselReportings(
.groupBy { (it.value as AlertType).type }
.map { (type, reportings) ->
ReportingTitleAndNumberOfOccurrences(
title = type.alertName,
title = "${type.alertName} (NATINF ${reportings[0].value.natinfCode})",
numberOfOccurrences = reportings.size,
)
}
Expand All @@ -113,7 +124,7 @@ class GetVesselReportings(
}

return@map ReportingTitleAndNumberOfOccurrences(
title = infraction?.infraction ?: "NATINF $natinfCode",
title = infraction?.infraction?.let {"$it (NATINF $natinfCode)"} ?: "NATINF $natinfCode",
numberOfOccurrences = reportings.size,
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -413,14 +413,14 @@ class GetVesselReportingsUTests {
val infractionSuspicionsSummary = result.summary.infractionSuspicionsSummary
assertThat(result.summary.infractionSuspicionsSummary).hasSize(4)
assertThat(infractionSuspicionsSummary[0].numberOfOccurrences).isEqualTo(2)
assertThat(infractionSuspicionsSummary[0].title).isEqualTo("12 milles - Pêche sans droits historiques")
assertThat(infractionSuspicionsSummary[0].title).isEqualTo("12 milles - Pêche sans droits historiques (NATINF 2610)")
assertThat(infractionSuspicionsSummary[1].numberOfOccurrences).isEqualTo(1)
assertThat(infractionSuspicionsSummary[1].title).isEqualTo("Non-emission de message \"FAR\" en 48h")
assertThat(infractionSuspicionsSummary[1].title).isEqualTo("Non-emission de message \"FAR\" en 48h (NATINF 27689)")
assertThat(infractionSuspicionsSummary[2].numberOfOccurrences).isEqualTo(1)
assertThat(
infractionSuspicionsSummary[2].title,
).isEqualTo(
"Peche maritime non autorisee dans les eaux maritimes ou salees francaises par un navire de pays tiers a l'union europeenne",
"Peche maritime non autorisee dans les eaux maritimes ou salees francaises par un navire de pays tiers a l'union europeenne (NATINF 7059)",
)
assertThat(infractionSuspicionsSummary[3].numberOfOccurrences).isEqualTo(1)
assertThat(infractionSuspicionsSummary[3].title).isEqualTo("NATINF 123456")
Expand Down
5 changes: 1 addition & 4 deletions frontend/cypress/e2e/vessel_sidebar/reporting.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,17 +141,14 @@ context('Vessel sidebar reporting tab', () => {
// Then
// Summary
cy.get('[data-cy="vessel-reporting-summary"]').contains('Résumé des derniers signalements (6 dernières années)')
cy.get('[data-cy="vessel-reporting-summary"]').contains('Signalements "3 milles - Chaluts"')
cy.get('[data-cy="vessel-reporting-summary"]').contains('Signalements "3 milles - Chaluts (NATINF 7059)"')

// Dates occurrences of an alert
cy.get('*[data-cy="vessel-sidebar-reporting-tab-archive-year"]').eq(0).click()
cy.get('[data-cy="reporting-card"]').should('not.contain', '2è alerte le')
cy.get('[data-cy="reporting-card"]').should('not.contain', '1ère alerte le')
cy.clickLink('Voir les dates des autres alertes')
cy.get('[data-cy="reporting-card"]').should('contain', '2è alerte le')
cy.get('[data-cy="reporting-card"]').should('contain', '1ère alerte le')
cy.clickLink('Masquer les dates des autres alertes')
cy.get('[data-cy="reporting-card"]').should('not.contain', '2è alerte le')
cy.get('[data-cy="reporting-card"]').should('not.contain', '1ère alerte le')

cy.get('*[data-cy^="vessel-search-selected-vessel-close-title"]', { timeout: 10000 }).click()
Expand Down
Loading

0 comments on commit 3095b37

Please sign in to comment.