From feec0f6c766d961cc78cbf231da3f9792a9fe645 Mon Sep 17 00:00:00 2001 From: Emmanuel Date: Fri, 22 Nov 2024 09:54:37 +0000 Subject: [PATCH] feat: add year to operation --- .../operations/OperationsUtils.java | 11 ++- .../rmes/model/operations/Operation.java | 13 ++- .../rmes/persistance/ontologies/INSEE.java | 4 +- .../request/operations/getOperation.ftlh | 39 ++++---- .../operations/OperationsUtilsTest.java | 93 +++++++++++++++++++ .../operations/OperationsQueriesTest.java | 8 ++ .../operations/OperationsResourcesTest.java | 2 +- .../all-operations-and-indicators.trig | 2 + 8 files changed, 148 insertions(+), 24 deletions(-) create mode 100644 src/test/java/fr/insee/rmes/bauhaus_services/operations/operations/OperationsUtilsTest.java diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/operations/operations/OperationsUtils.java b/src/main/java/fr/insee/rmes/bauhaus_services/operations/operations/OperationsUtils.java index cf48310e9..be29fab0f 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/operations/operations/OperationsUtils.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/operations/operations/OperationsUtils.java @@ -117,6 +117,7 @@ public String setOperation(String body) throws RmesException { if(!stampsRestrictionsService.canCreateOperation(seriesURI)) { throw new RmesUnauthorizedException(ErrorCodes.OPERATION_CREATION_RIGHTS_DENIED, "Only an admin or a series manager can create a new operation."); } + operation.setCreated(DateUtils.getCurrentDate()); operation.setModified(DateUtils.getCurrentDate()); @@ -140,12 +141,10 @@ public String setOperation(String id, String body) throws RmesException { throw new RmesUnauthorizedException(ErrorCodes.OPERATION_MODIFICATION_RIGHTS_DENIED, "Only authorized users can modify operations."); } - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); Operation operation = new Operation(id); try { - operation = mapper.readerForUpdating(operation).readValue(body); - } catch (IOException e) { + operation = Deserializer.deserializeJsonString(body, Operation.class); + } catch (RmesException e) { logger.error(e.getMessage()); } @@ -179,6 +178,10 @@ private void createRdfOperation(Operation operation, IRI serieUri, ValidationSta RdfUtils.addTripleDateTime(operationURI, DCTERMS.CREATED, operation.getCreated(), model, RdfUtils.operationsGraph()); RdfUtils.addTripleDateTime(operationURI, DCTERMS.MODIFIED, operation.getModified(), model, RdfUtils.operationsGraph()); + if(operation.getYear() != null){ + RdfUtils.addTripleInt(operationURI, INSEE.YEAR, operation.getYear().toString(), model, RdfUtils.operationsGraph()); + } + if (serieUri != null) { //case CREATION : link operation to series RdfUtils.addTripleUri(operationURI, DCTERMS.IS_PART_OF, serieUri, model, RdfUtils.operationsGraph()); diff --git a/src/main/java/fr/insee/rmes/model/operations/Operation.java b/src/main/java/fr/insee/rmes/model/operations/Operation.java index b99b12c98..99bb2e4ca 100644 --- a/src/main/java/fr/insee/rmes/model/operations/Operation.java +++ b/src/main/java/fr/insee/rmes/model/operations/Operation.java @@ -36,8 +36,11 @@ public class Operation { @Schema(description = "Validation State") private String validationState; + @Schema(description = "millesime") + private Integer year; + public Operation(String id, String prefLabelLg1, String prefLabelLg2, String altLabelLg1, String altLabelLg2, - IdLabelTwoLangs series, String idSims, String validationState) { + IdLabelTwoLangs series, String idSims, String validationState, int year) { super(); this.id = id; this.prefLabelLg1 = prefLabelLg1; @@ -145,4 +148,12 @@ public String getValidationState() { public void setValidationState(String validationState) { this.validationState = validationState; } + + public Integer getYear() { + return year; + } + + public void setYear(Integer year) { + this.year = year; + } } diff --git a/src/main/java/fr/insee/rmes/persistance/ontologies/INSEE.java b/src/main/java/fr/insee/rmes/persistance/ontologies/INSEE.java index ccd8486a7..8f0f0d527 100644 --- a/src/main/java/fr/insee/rmes/persistance/ontologies/INSEE.java +++ b/src/main/java/fr/insee/rmes/persistance/ontologies/INSEE.java @@ -8,7 +8,7 @@ import org.eclipse.rdf4j.model.impl.SimpleValueFactory; public class INSEE { - private static final ValueFactory factory = SimpleValueFactory.getInstance(); + private static final ValueFactory factory = SimpleValueFactory.getInstance(); private INSEE() { throw new IllegalStateException("Utility class"); @@ -23,6 +23,8 @@ private INSEE() { private static IRI createIRI(String suffix) { return factory.createIRI(NAMESPACE, suffix); } + public static final IRI YEAR = INSEE.createIRI("year"); + public static final IRI LAST_CODE_URI_SEGMENT = INSEE.createIRI("lastCodeUriSegment"); public static final IRI DISSEMINATIONSTATUS = INSEE.createIRI("disseminationStatus"); public static final IRI ADDITIONALMATERIAL = INSEE.createIRI("additionalMaterial"); diff --git a/src/main/resources/request/operations/getOperation.ftlh b/src/main/resources/request/operations/getOperation.ftlh index a93bc4aee..a56de5707 100644 --- a/src/main/resources/request/operations/getOperation.ftlh +++ b/src/main/resources/request/operations/getOperation.ftlh @@ -1,20 +1,25 @@ -SELECT ?id ?prefLabelLg1 ?prefLabelLg2 ?altLabelLg1 ?altLabelLg2 ?idSims ?validationState ?created ?modified +SELECT ?id ?prefLabelLg1 ?prefLabelLg2 ?altLabelLg1 ?altLabelLg2 ?idSims ?validationState ?created ?modified ?year WHERE { GRAPH <${OPERATIONS_GRAPH}> { -?operation skos:prefLabel ?prefLabelLg1 . -FILTER(STRENDS(STR(?operation),'/operations/operation/${ID}')) . -BIND(STRAFTER(STR(?operation),'/operation/') AS ?id) . -FILTER (lang(?prefLabelLg1) = '${LG1}') . -OPTIONAL {?operation skos:prefLabel ?prefLabelLg2 . -FILTER (lang(?prefLabelLg2) = '${LG2}') } . -OPTIONAL {?operation skos:altLabel ?altLabelLg1 . -FILTER (lang(?altLabelLg1) = '${LG1}') } . -OPTIONAL {?operation skos:altLabel ?altLabelLg2 . -FILTER (lang(?altLabelLg2) = '${LG2}') } . -}OPTIONAL { ?operation dcterms:created ?created } . -OPTIONAL { ?operation dcterms:modified ?modified } . -OPTIONAL{ ?report rdf:type sdmx-mm:MetadataReport . ?report sdmx-mm:target ?operation BIND(STRAFTER(STR(?report),'/rapport/') AS ?idSims) . -} -OPTIONAL {?operation insee:validationState ?validationState . -} + ?operation skos:prefLabel ?prefLabelLg1 . + FILTER(STRENDS(STR(?operation),'/operations/operation/${ID}')) . + BIND(STRAFTER(STR(?operation),'/operation/') AS ?id) . + FILTER (lang(?prefLabelLg1) = '${LG1}') . + OPTIONAL { + ?operation skos:prefLabel ?prefLabelLg2 . + FILTER (lang(?prefLabelLg2) = '${LG2}') + } . + OPTIONAL { + ?operation skos:altLabel ?altLabelLg1 . + FILTER (lang(?altLabelLg1) = '${LG1}') + } . + OPTIONAL { + ?operation skos:altLabel ?altLabelLg2 . + FILTER (lang(?altLabelLg2) = '${LG2}') } . + } + OPTIONAL { ?operation dcterms:created ?created } . + OPTIONAL { ?operation dcterms:modified ?modified } . + OPTIONAL{ ?report rdf:type sdmx-mm:MetadataReport . ?report sdmx-mm:target ?operation BIND(STRAFTER(STR(?report),'/rapport/') AS ?idSims) . } + OPTIONAL {?operation insee:validationState ?validationState .} + OPTIONAL {?operation insee:year ?year .} } LIMIT 1 \ No newline at end of file diff --git a/src/test/java/fr/insee/rmes/bauhaus_services/operations/operations/OperationsUtilsTest.java b/src/test/java/fr/insee/rmes/bauhaus_services/operations/operations/OperationsUtilsTest.java new file mode 100644 index 000000000..dad3542d0 --- /dev/null +++ b/src/test/java/fr/insee/rmes/bauhaus_services/operations/operations/OperationsUtilsTest.java @@ -0,0 +1,93 @@ +package fr.insee.rmes.bauhaus_services.operations.operations; + +import fr.insee.rmes.bauhaus_services.operations.ParentUtils; +import fr.insee.rmes.bauhaus_services.operations.famopeserind_utils.FamOpeSerIndUtils; +import fr.insee.rmes.bauhaus_services.rdf_utils.ObjectType; +import fr.insee.rmes.bauhaus_services.rdf_utils.RdfUtils; +import fr.insee.rmes.bauhaus_services.rdf_utils.RepositoryGestion; +import fr.insee.rmes.config.Config; +import fr.insee.rmes.config.auth.security.restrictions.StampsRestrictionsService; +import fr.insee.rmes.exceptions.RmesException; +import fr.insee.rmes.persistance.sparql_queries.operations.operations.OperationsQueries; +import org.eclipse.rdf4j.model.IRI; +import org.eclipse.rdf4j.model.Model; +import org.eclipse.rdf4j.model.impl.SimpleValueFactory; +import org.json.JSONObject; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.*; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +class OperationsUtilsTest { + @InjectMocks + OperationsUtils operationsUtils; + + @Mock + FamOpeSerIndUtils famOpeSerIndUtils; + + @Mock + ParentUtils parentUtils; + + @Mock + StampsRestrictionsService stampsRestrictionsService; + + @Mock + RepositoryGestion repositoryGestion; + + @Mock + Config config; + + @Test + void shouldStoreYearProperty() throws RmesException { + + when(repositoryGestion.getResponseAsBoolean("unicity-labelLg1")).thenReturn(false); + when(repositoryGestion.getResponseAsBoolean("unicity-labelLg2")).thenReturn(false); + when(config.getLg1()).thenReturn("fr"); + when(config.getLg2()).thenReturn("en"); + when(famOpeSerIndUtils.createId()).thenReturn("1"); + when(famOpeSerIndUtils.checkIfObjectExists(ObjectType.SERIES, "2")).thenReturn(true); + when(parentUtils.checkIfSeriesHasSims(anyString())).thenReturn(false); + when(stampsRestrictionsService.canCreateOperation(any(IRI.class))).thenReturn(true); + + try (MockedStatic mockedFactory = Mockito.mockStatic(RdfUtils.class); + MockedStatic operationsQueriesMockedStatic = Mockito.mockStatic(OperationsQueries.class) + ) { + SimpleValueFactory valueFactory = SimpleValueFactory.getInstance(); + IRI operationIRI = valueFactory.createIRI("http://operation/2"); + mockedFactory.when(() -> RdfUtils.setLiteralInt(anyString())).thenCallRealMethod(); + mockedFactory.when(() -> RdfUtils.addTripleInt(any(), any(), any(), any(), any())).thenCallRealMethod(); + mockedFactory.when(() -> RdfUtils.setLiteralString(anyString(), anyString())).thenCallRealMethod(); + mockedFactory.when(() -> RdfUtils.setLiteralString(anyString())).thenCallRealMethod(); + mockedFactory.when(() -> RdfUtils.operationsGraph()).thenReturn(valueFactory.createIRI("http://operations-graph/")); + mockedFactory.when(() -> RdfUtils.objectIRI(eq(ObjectType.SERIES), eq("2"))).thenReturn(valueFactory.createIRI("http://series/2")); + mockedFactory.when(() -> RdfUtils.objectIRI(eq(ObjectType.OPERATION), eq("1"))).thenReturn(operationIRI); + operationsQueriesMockedStatic.when(() -> OperationsQueries.checkPrefLabelUnicity(eq("1"), eq("prefLabelLg1"), eq("fr"))).thenReturn("unicity-labelLg1"); + operationsQueriesMockedStatic.when(() -> OperationsQueries.checkPrefLabelUnicity(eq("1"), eq("prefLabelLg2"), eq("en"))).thenReturn("unicity-labelLg2"); + + JSONObject operation = new JSONObject(); + JSONObject series = new JSONObject() + .put("id", "2"); + operation + .put("prefLabelLg1", "prefLabelLg1") + .put("prefLabelLg2", "prefLabelLg2") + .put("year", 2024) + .put("series", series); + + operationsUtils.setOperation(operation.toString()); + + ArgumentCaptor model = ArgumentCaptor.forClass(Model.class); + + verify(repositoryGestion, times(1)).loadSimpleObject(eq(operationIRI), model.capture()); + + Assertions.assertEquals("[(http://operation/2, http://www.w3.org/1999/02/22-rdf-syntax-ns#type, http://rdf.insee.fr/def/base#StatisticalOperation, http://operations-graph/) [http://operations-graph/], (http://operation/2, http://www.w3.org/2004/02/skos/core#prefLabel, \"prefLabelLg1\"@fr, http://operations-graph/) [http://operations-graph/], (http://operation/2, http://rdf.insee.fr/def/base#validationState, \"Unpublished\", http://operations-graph/) [http://operations-graph/], (http://operation/2, http://rdf.insee.fr/def/base#year, \"2024\"^^, http://operations-graph/) [http://operations-graph/]]", model.getValue().toString()); + + } + + + } +} \ No newline at end of file diff --git a/src/test/java/fr/insee/rmes/testcontainers/queries/sparql_queries/operations/operations/OperationsQueriesTest.java b/src/test/java/fr/insee/rmes/testcontainers/queries/sparql_queries/operations/operations/OperationsQueriesTest.java index 6974b060e..64b81dc36 100644 --- a/src/test/java/fr/insee/rmes/testcontainers/queries/sparql_queries/operations/operations/OperationsQueriesTest.java +++ b/src/test/java/fr/insee/rmes/testcontainers/queries/sparql_queries/operations/operations/OperationsQueriesTest.java @@ -8,6 +8,7 @@ import fr.insee.rmes.persistance.sparql_queries.operations.series.OpSeriesQueries; import fr.insee.rmes.testcontainers.queries.WithGraphDBContainer; import org.json.JSONArray; +import org.json.JSONObject; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -32,4 +33,11 @@ void should_return_all_operations() throws Exception { assertNotNull(result.getJSONObject(i).getString("iri")); } } + + @Test + void should_return_one_operation() throws Exception { + OpSeriesQueries.setConfig(new ConfigStub()); + JSONObject result = repositoryGestion.getResponseAsObject(OperationsQueries.operationQuery("s1447")); + assertEquals("2024", result.getString("year")); + } } diff --git a/src/test/java/fr/insee/rmes/webservice/operations/OperationsResourcesTest.java b/src/test/java/fr/insee/rmes/webservice/operations/OperationsResourcesTest.java index 1a11f5900..b3dc28f3f 100644 --- a/src/test/java/fr/insee/rmes/webservice/operations/OperationsResourcesTest.java +++ b/src/test/java/fr/insee/rmes/webservice/operations/OperationsResourcesTest.java @@ -40,7 +40,7 @@ class OperationsResourcesTest { @CsvSource({ "1, '"+MediaType.APPLICATION_JSON_VALUE+"', '{\"id\":\"1\"}'", - "1, '"+MediaType.APPLICATION_XML_VALUE+"', '1'", + "1, '"+MediaType.APPLICATION_XML_VALUE+"', '1'", }) @ParameterizedTest void getOperationByID_resultFormatFitAccessHeader(String id, String mediaType, String expected) throws Exception { diff --git a/src/test/resources/testcontainers/all-operations-and-indicators.trig b/src/test/resources/testcontainers/all-operations-and-indicators.trig index ae0ced2b1..50c08f17d 100644 --- a/src/test/resources/testcontainers/all-operations-and-indicators.trig +++ b/src/test/resources/testcontainers/all-operations-and-indicators.trig @@ -801,6 +801,8 @@ "2008" ; "Validated" ; + + "2024" ; "EPCV scheme 2008"@en , "EPCV 2008"@fr ;