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

feat: merge into main #257

Merged
merged 40 commits into from
Jul 10, 2024
Merged
Changes from 1 commit
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
afc1745
fix: handle null state data in DB when saving survey unit state data
davdarras Apr 8, 2024
f8af35d
fix: use previousDate instead of newDate for null integrity in updati…
davdarras Apr 8, 2024
cfc8445
fix: allow patch methods in cors (#232)
davdarras Apr 8, 2024
5f64bc9
Merge branch 'develop' into fix/cors-headers
davdarras Apr 8, 2024
3927a36
Merge pull request #235 from InseeFr/fix/cors-headers
davdarras Apr 8, 2024
46aef0d
Merge pull request #236 from InseeFr/fix/allow-put-su-from-surveyunit
davdarras Apr 8, 2024
81ecb01
fix: resolve native insert when current data has no collected attribu…
davdarras Apr 10, 2024
060f419
fix: improve perf on native insert of collected data (#238)
davdarras Apr 10, 2024
7b1c5d7
fix: schema names for input output on openapi spec (#239)
davdarras Apr 15, 2024
a0634f6
fix: from string to json node objects (#240)
davdarras Apr 15, 2024
a4836f1
fix: disable app collected update
davdarras Apr 16, 2024
621a835
fix: add openapi schema for arraynode/objectnode
davdarras Apr 16, 2024
6867d82
fix(deps): update dependencies
davdarras Apr 16, 2024
049ac00
fix: add collected data even if data is null
davdarras Apr 16, 2024
4bc676e
feat: add endpoint to retrieve questionnaire data directly (#243)
davdarras Apr 30, 2024
a68cd7c
feat: add endpoint to update partial collected data/state data at the…
davdarras Apr 30, 2024
533c2ea
feat: add json validation for metadata/personalization/data/collected…
davdarras May 17, 2024
8442f57
ci: handle develop snapshots on demand
davdarras May 22, 2024
59f6eaf
feat: add new campaign creation endpoint
davdarras May 22, 2024
4f308bb
feat: restrict module usages from domain modules
davdarras May 22, 2024
4fd84b7
chore(deps): update all minor dependencies
davdarras May 22, 2024
f0eea0e
feat: add default configuration when no role claim configured
davdarras May 22, 2024
649dba7
fix: add json validation for survey unit temp zone
davdarras May 23, 2024
fc4962f
fix: resolve schema correctly in swagger
davdarras May 23, 2024
9765e0d
fix: allow empty data when saving diff data/state data (#248)
davdarras May 27, 2024
54b49b1
feat: add endpoint retrieving survey unit metadata (#249)
davdarras Jun 6, 2024
611f790
fix: add survey units unique constraints in DB (#250)
davdarras Jun 7, 2024
b440495
doc: resolve openapi scpe for deposit proof
davdarras Jun 7, 2024
df8cad7
doc: openapi depositproof add binary format in content schema
davdarras Jun 7, 2024
11b699f
fix: comment buggy annotation for openapi in deposit proof controller
davdarras Jun 7, 2024
fe35483
fix: avoid manipulating metadata cache object
davdarras Jun 14, 2024
acf8e5b
Merge branch 'develop' into renovate/all-minor-patch
davdarras Jun 14, 2024
5542d4d
Merge pull request #251 from InseeFr/renovate/all-minor-patch
davdarras Jun 14, 2024
5671ec1
fix: temporarily enable additional properties for data
davdarras Jun 14, 2024
cd59115
test: temporarily enable additional properties for data
davdarras Jun 14, 2024
af58eb6
fix: loosen types on json schemas (#252)
davdarras Jun 14, 2024
611f53f
fix: add required metadata attributes when retrieving survey unit met…
davdarras Jun 18, 2024
ed54b65
fix: disallow reviewers to put data/state-data
davdarras Jun 24, 2024
c41a5e9
fix: when deleting campaign, reset survey unit cache
davdarras Jun 24, 2024
5435d7d
fix: when updating survey-unit, allow null state (#256)
davdarras Jul 4, 2024
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
Prev Previous commit
Next Next commit
fix: add json validation for survey unit temp zone
  • Loading branch information
davdarras committed May 23, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
commit 649dba70c218f6fc5171719cf9c5cbb71dae6cec
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@
<description>Modules for queen back-office</description>

<properties>
<revision>4.3.0</revision>
<revision>4.3.1</revision>
<changelist></changelist>
<java.version>21</java.version>
<maven.compiler.source>21</maven.compiler.source>
Original file line number Diff line number Diff line change
@@ -4,9 +4,12 @@
import fr.insee.queen.application.configuration.auth.AuthorityPrivileges;
import fr.insee.queen.application.surveyunittempzone.dto.output.SurveyUnitTempZoneDto;
import fr.insee.queen.application.web.validation.IdValid;
import fr.insee.queen.application.web.validation.json.JsonValid;
import fr.insee.queen.application.web.validation.json.SchemaType;
import fr.insee.queen.domain.surveyunittempzone.service.SurveyUnitTempZoneService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
@@ -43,7 +46,11 @@ public class SurveyUnitTempZoneController {
@PreAuthorize(AuthorityPrivileges.HAS_INTERVIEWER_PRIVILEGES)
@ResponseStatus(HttpStatus.CREATED)
public void postSurveyUnitByIdInTempZone(@IdValid @PathVariable(value = "id") String surveyUnitId,
@NotNull @RequestBody ObjectNode surveyUnit,
@NotNull
@RequestBody
@Schema(ref = SchemaType.Names.SURVEY_UNIT_TEMP_ZONE)
@JsonValid(SchemaType.SURVEY_UNIT_TEMP_ZONE)
ObjectNode surveyUnit,
@CurrentSecurityContext(expression = "authentication.name") String userId) {
surveyUnitTempZoneService.saveSurveyUnitToTempZone(surveyUnitId, userId, surveyUnit);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package fr.insee.queen.application.surveyunittempzone.dto.output;

import com.fasterxml.jackson.databind.node.ObjectNode;
import fr.insee.queen.application.web.validation.json.SchemaType;
import fr.insee.queen.domain.surveyunittempzone.model.SurveyUnitTempZone;
import io.swagger.v3.oas.annotations.media.Schema;

@@ -12,6 +13,7 @@ public record SurveyUnitTempZoneDto(
String surveyUnitId,
String userId,
Long date,
@Schema(ref = SchemaType.Names.SURVEY_UNIT_TEMP_ZONE)
ObjectNode surveyUnit) {

public static SurveyUnitTempZoneDto fromModel(SurveyUnitTempZone surveyUnit) {
Original file line number Diff line number Diff line change
@@ -12,7 +12,8 @@ public enum SchemaType {
METADATA(Names.METADATA),
PERSONALIZATION(Names.PERSONALIZATION),
NOMENCLATURE(Names.NOMENCLATURE),
VARIABLE_TYPE(Names.VARIABLE_TYPE);
VARIABLE_TYPE(Names.VARIABLE_TYPE),
SURVEY_UNIT_TEMP_ZONE(Names.SURVEY_UNIT_TEMP_ZONE);

public static class Names {
public static final String CAMPAIGN_INTEGRATION = "schema.campaign-integration.json";
@@ -24,6 +25,7 @@ public static class Names {
public static final String PERSONALIZATION = "schema.personalization.json";
public static final String NOMENCLATURE = "schema.nomenclature.json";
public static final String VARIABLE_TYPE = "schema.variable-type.json";
public static final String SURVEY_UNIT_TEMP_ZONE = "schema.survey-unit-temp-zone.json";

private Names() {

Original file line number Diff line number Diff line change
@@ -2,7 +2,6 @@
"$schema": "http://json-schema.org/draft/2020-12/schema",
"$id": "https://insee.fr/schema.metadata.json",
"type": "object",
"required": ["inseeContext"],
"additionalProperties": true,
"properties": {
"inseeContext": {
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://insee.fr/schema.survey-unit-temp-zone.json",
"title": "Survey unit temp zone schema",
"description": "Validation of survey unit temp zone",
"type": "object",
"additionalProperties": false,
"required": ["data", "stateData", "questionnaireId"],
"properties": {
"data": {
"$ref": "schema.data.json#"
},
"comment": {
"type": "object"
},
"personalization": {
"$ref": "schema.personalization.json#"
},
"questionnaireId": {
"type": "string",
"minLength": 1
},
"stateData": {
"$ref": "#/$defs/stateData"
}
},
"$defs": {
"stateData": {
"type": "object",
"required": ["date", "state", "currentPage"],
"additionalProperties": false,
"properties": {
"date": {
"type": "number"
},
"state": {
"enum": ["INIT", "COMPLETED", "VALIDATED", "TOEXTRACT", "EXTRACTED"]
},
"currentPage": {
"type": "string",
"minLength": 1
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -51,8 +51,13 @@ void on_create_survey_unit_then_survey_unit_created() throws Exception {
}
},
"comment": {"plip": "plop"},
"personalization": [{},{}],
"questionnaireId":"questionnaire-11"
"personalization": [{"name": "name", "value": "value"}],
"questionnaireId":"questionnaire-11",
"stateData": {
"state": "EXTRACTED",
"date": 123456789,
"currentPage": "2.3"
}
}""";
mockMvc.perform(post("/api/survey-unit/" + surveyUnitId + "/temp-zone")
.accept(MediaType.APPLICATION_JSON)
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.networknt.schema.ValidationMessage;
import com.networknt.schema.ValidatorTypeCode;
import fr.insee.queen.application.utils.JsonTestHelper;
@@ -182,6 +183,102 @@ void testMetadata02() throws IOException {
assertForbiddenProperty(error, "$.variables[2]", "forbidden-property");
}

@Test
@DisplayName("when validating valid survey unit temp zone, no errors returned")
void testTempZone01() throws IOException {
String surveyUnitTempZoneJson = JsonTestHelper.getResourceFileAsString("json-schema-validation/surveyunittempzone/valid-tempzone.json");
JsonNode surveyUnitTempZoneNode = mapper.readValue(surveyUnitTempZoneJson, JsonNode.class);
Set<ValidationMessage> errors = validatorComponent.validate(SchemaType.SURVEY_UNIT_TEMP_ZONE, surveyUnitTempZoneNode);
assertThat(errors).isEmpty();
}

@Test
@DisplayName("when validating survey unit temp zone with missing attributes, return json schema errors")
void testTempZone02() {
Set<ValidationMessage> errors = validatorComponent.validate(SchemaType.SURVEY_UNIT_TEMP_ZONE, JsonNodeFactory.instance.objectNode());
assertThat(errors).hasSize(3);

ValidationMessage[] messages = errors.toArray(ValidationMessage[]::new);

ValidationMessage error = messages[0];
assertRequiredProperty(error, "$", "data");

error = messages[1];
assertRequiredProperty(error, "$", "stateData");

error = messages[2];
assertRequiredProperty(error, "$", "questionnaireId");
}

@Test
@DisplayName("when validating survey unit temp zone with missing stateData attributes, return json schema errors")
void testTempZone03() throws IOException {
String surveyUnitTempZoneJson = JsonTestHelper.getResourceFileAsString("json-schema-validation/surveyunittempzone/invalid-missing-statedata-attributes-tempzone.json");
JsonNode surveyUnitTempZoneNode = mapper.readValue(surveyUnitTempZoneJson, JsonNode.class);
Set<ValidationMessage> errors = validatorComponent.validate(SchemaType.SURVEY_UNIT_TEMP_ZONE, surveyUnitTempZoneNode);
assertThat(errors).hasSize(3);

ValidationMessage[] messages = errors.toArray(ValidationMessage[]::new);

ValidationMessage error = messages[0];
assertRequiredProperty(error, "$.stateData", "date");

error = messages[1];
assertRequiredProperty(error, "$.stateData", "state");

error = messages[2];
assertRequiredProperty(error, "$.stateData", "currentPage");
}

@Test
@DisplayName("when validating survey unit temp zone with incorrect types, return json schema errors")
void testTempZone04() throws IOException {
String surveyUnitTempZoneJson = JsonTestHelper.getResourceFileAsString("json-schema-validation/surveyunittempzone/invalid-types.json");
JsonNode surveyUnitTempZoneNode = mapper.readValue(surveyUnitTempZoneJson, JsonNode.class);
Set<ValidationMessage> errors = validatorComponent.validate(SchemaType.SURVEY_UNIT_TEMP_ZONE, surveyUnitTempZoneNode);
assertThat(errors).hasSize(7);

ValidationMessage[] messages = errors.toArray(ValidationMessage[]::new);

ValidationMessage error = messages[0];
assertBadType(error, "$.comment");

error = messages[1];
assertBadType(error, "$.questionnaireId");

error = messages[2];
assertBadType(error, "$.stateData.date");

error = messages[3];
assertBadEnum(error, "$.stateData.state");

error = messages[4];
assertBadType(error, "$.stateData.currentPage");

error = messages[5];
assertForbiddenProperty(error, "$.stateData", "forbidden-property");

error = messages[6];
assertForbiddenProperty(error, "$", "forbidden-property");
}

@Test
@DisplayName("when validating survey unit temp zone with incorrect attributes length, return json schema errors")
void testTempZone05() throws IOException {
String surveyUnitTempZoneJson = JsonTestHelper.getResourceFileAsString("json-schema-validation/surveyunittempzone/invalid-lengths.json");
JsonNode surveyUnitTempZoneNode = mapper.readValue(surveyUnitTempZoneJson, JsonNode.class);
Set<ValidationMessage> errors = validatorComponent.validate(SchemaType.SURVEY_UNIT_TEMP_ZONE, surveyUnitTempZoneNode);
assertThat(errors).hasSize(2);

ValidationMessage[] messages = errors.toArray(ValidationMessage[]::new);

ValidationMessage error = messages[0];
assertBadLength(error, "$.questionnaireId");

error = messages[1];
assertBadLength(error, "$.stateData.currentPage");
}

private void assertBadPattern(ValidationMessage error, String instanceLocation) {
assertThat(error.getInstanceLocation()).hasToString(instanceLocation);
ValidatorTypeCode typeCode = ValidatorTypeCode.fromValue(error.getType());
@@ -207,4 +304,16 @@ private void assertRequiredProperty(ValidationMessage error, String instanceLoca
ValidatorTypeCode typeCode = ValidatorTypeCode.fromValue(error.getType());
assertThat(typeCode).isEqualTo(ValidatorTypeCode.REQUIRED);
}

private void assertBadEnum(ValidationMessage error, String instanceLocation) {
assertThat(error.getInstanceLocation()).hasToString(instanceLocation);
ValidatorTypeCode typeCode = ValidatorTypeCode.fromValue(error.getType());
assertThat(typeCode).isEqualTo(ValidatorTypeCode.ENUM);
}

private void assertBadLength(ValidationMessage error, String instanceLocation) {
assertThat(error.getInstanceLocation()).hasToString(instanceLocation);
ValidatorTypeCode typeCode = ValidatorTypeCode.fromValue(error.getType());
assertThat(typeCode).isEqualTo(ValidatorTypeCode.MIN_LENGTH);
}
}
Original file line number Diff line number Diff line change
@@ -12,5 +12,5 @@
"forbidden-property": true
}
],
"inseeContext":"forbidden-value"
"inseeContext": "forbidden-value"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"data": {
"EXTERNAL": {
"BOOLEAN_VAR": false,
"NULL_VAR": null,
"STRING_VAR": "string",
"NUM_VAR": 1,
"ARRAY_BOOLEAN": [true, false],
"ARRAY_NULL": [null, null],
"ARRAY_STRING": ["string", "string"],
"ARRAY_NUM": [1, 2]
},
"CALCULATED": {
"BOOLEAN_VAR": false,
"NULL_VAR": null,
"STRING_VAR": "string",
"NUM_VAR": 1,
"ARRAY_BOOLEAN": [true, false],
"ARRAY_NULL": [null, null],
"ARRAY_STRING": ["string", "string"],
"ARRAY_NUM": [1, 2]
},
"COLLECTED": {
"VALUE": {
"EDITED": false,
"FORCED": null,
"INPUTED": "string",
"COLLECTED": 1
},
"ARRAY": {
"EDITED": [true, false],
"FORCED": [null, null],
"INPUTED": ["string", "string"],
"PREVIOUS": [1, 2],
"INPUTTED": "string"
}
}
},
"stateData": {
"state": "INIT",
"date": 123456789,
"currentPage": ""
},
"questionnaireId": ""
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"data": {
"EXTERNAL": {
"BOOLEAN_VAR": false,
"NULL_VAR": null,
"STRING_VAR": "string",
"NUM_VAR": 1,
"ARRAY_BOOLEAN": [true, false],
"ARRAY_NULL": [null, null],
"ARRAY_STRING": ["string", "string"],
"ARRAY_NUM": [1, 2]
},
"CALCULATED": {
"BOOLEAN_VAR": false,
"NULL_VAR": null,
"STRING_VAR": "string",
"NUM_VAR": 1,
"ARRAY_BOOLEAN": [true, false],
"ARRAY_NULL": [null, null],
"ARRAY_STRING": ["string", "string"],
"ARRAY_NUM": [1, 2]
},
"COLLECTED": {
"VALUE": {
"EDITED": false,
"FORCED": null,
"INPUTED": "string",
"COLLECTED": 1
},
"ARRAY": {
"EDITED": [true, false],
"FORCED": [null, null],
"INPUTED": ["string", "string"],
"PREVIOUS": [1, 2],
"INPUTTED": "string"
}
}
},
"comment": {
"commentaire": "hello"
},
"stateData": {
},
"questionnaireId": "QUESTIONNAIRE-1"
}
Loading