-
Notifications
You must be signed in to change notification settings - Fork 4
Validation date and questionnaire state process fix #365
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
Merged
alexisszmundy
merged 9 commits into
devFixUsualSurveyUnitId
from
devFixNewVariablesExport
Jan 5, 2026
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
a8f4542
test: bug reproducing
alexisszmundy 3e8c4cc
test: exceptions tests and nested
alexisszmundy 5085be9
fix: questionnaire state into survey unit model
alexisszmundy 3639846
test: validation date time KO test
alexisszmundy d003eef
refactor: tests methods extractions
alexisszmundy dcb99e2
refactor: inline
alexisszmundy 188d756
refactor: method names camel case
alexisszmundy e1fab5e
fix: validation date parsing
alexisszmundy 5b241df
Merge branch 'devFixUsualSurveyUnitId' into devFixNewVariablesExport
alexisszmundy File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
318 changes: 318 additions & 0 deletions
318
src/test/java/fr/insee/genesis/domain/service/rawdata/RawResponseServiceUnitTest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,318 @@ | ||
| package fr.insee.genesis.domain.service.rawdata; | ||
|
|
||
| import fr.insee.bpm.metadata.model.MetadataModel; | ||
| import fr.insee.bpm.metadata.model.VariablesMap; | ||
| import fr.insee.genesis.TestConstants; | ||
| import fr.insee.genesis.controller.utils.ControllerUtils; | ||
| import fr.insee.genesis.domain.model.surveyunit.Mode; | ||
| import fr.insee.genesis.domain.model.surveyunit.SurveyUnitModel; | ||
| import fr.insee.genesis.domain.model.surveyunit.rawdata.RawResponse; | ||
| import fr.insee.genesis.domain.ports.spi.RawResponsePersistencePort; | ||
| import fr.insee.genesis.domain.ports.spi.SurveyUnitQualityToolPort; | ||
| import fr.insee.genesis.domain.service.context.DataProcessingContextService; | ||
| import fr.insee.genesis.domain.service.metadata.QuestionnaireMetadataService; | ||
| import fr.insee.genesis.domain.service.surveyunit.SurveyUnitQualityService; | ||
| import fr.insee.genesis.domain.service.surveyunit.SurveyUnitService; | ||
| import fr.insee.genesis.exceptions.GenesisException; | ||
| import fr.insee.genesis.infrastructure.utils.FileUtils; | ||
| import fr.insee.genesis.stubs.ConfigStub; | ||
| import fr.insee.modelefiliere.RawResponseDto; | ||
| import lombok.SneakyThrows; | ||
| import org.assertj.core.api.Assertions; | ||
| import org.junit.jupiter.api.BeforeEach; | ||
| import org.junit.jupiter.api.DisplayName; | ||
| import org.junit.jupiter.api.Nested; | ||
| import org.junit.jupiter.api.Test; | ||
| import org.junit.jupiter.params.ParameterizedTest; | ||
| import org.junit.jupiter.params.provider.EnumSource; | ||
| import org.mockito.ArgumentCaptor; | ||
|
|
||
| import java.time.LocalDateTime; | ||
| import java.time.format.DateTimeFormatter; | ||
| import java.util.ArrayList; | ||
| import java.util.Collections; | ||
| import java.util.HashMap; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
| import java.util.Set; | ||
|
|
||
| import static org.mockito.ArgumentMatchers.any; | ||
| import static org.mockito.Mockito.doReturn; | ||
| import static org.mockito.Mockito.mock; | ||
| import static org.mockito.Mockito.verify; | ||
|
|
||
| class RawResponseServiceUnitTest { | ||
|
|
||
| static RawResponseService rawResponseService; | ||
| static RawResponsePersistencePort rawResponsePersistencePort; | ||
| static ControllerUtils controllerUtils; | ||
| static QuestionnaireMetadataService metadataService; | ||
| static SurveyUnitService surveyUnitService; | ||
|
|
||
| private ArgumentCaptor<List<SurveyUnitModel>> surveyUnitModelsCaptor; | ||
|
|
||
| private static final String TEST_VALIDATION_DATE = "2025-11-11T06:00:00Z"; | ||
|
|
||
| @BeforeEach | ||
| @SuppressWarnings("unchecked") | ||
| void init() { | ||
| rawResponsePersistencePort = mock(RawResponsePersistencePort.class); | ||
| controllerUtils = mock(ControllerUtils.class); | ||
| metadataService = mock(QuestionnaireMetadataService.class); | ||
| surveyUnitService = mock(SurveyUnitService.class); | ||
|
|
||
| rawResponseService = new RawResponseService( | ||
| controllerUtils, | ||
| metadataService, | ||
| surveyUnitService, | ||
| mock(SurveyUnitQualityService.class), | ||
| mock(SurveyUnitQualityToolPort.class), | ||
| mock(DataProcessingContextService.class), | ||
| new FileUtils(new ConfigStub()), | ||
| new ConfigStub(), | ||
| rawResponsePersistencePort | ||
| ); | ||
|
|
||
| surveyUnitModelsCaptor = ArgumentCaptor.forClass(List.class); | ||
| } | ||
|
|
||
| @Nested | ||
| @DisplayName("Non regression tests of #22875 : validation date and questionnaire state in processed responses") | ||
| class ValidationDateAndQuestionnaireStateTests{ | ||
| //OK cases | ||
| @ParameterizedTest | ||
| @DisplayName("Process by collection instrument id OK test") | ||
| @EnumSource(RawResponseDto.QuestionnaireStateEnum.class) | ||
| @SneakyThrows | ||
| void processRawResponses_byCollectionInstrumentId_validation_date_questionnaire_state_test( | ||
| RawResponseDto.QuestionnaireStateEnum questionnaireState | ||
| ) { | ||
| //GIVEN | ||
| givenOkCase(questionnaireState); | ||
|
|
||
| //WHEN | ||
| List<SurveyUnitModel> createdModels = whenProcessByCollectionInstrumentIdAndInterrogationIdList(); | ||
|
|
||
| //THEN | ||
| processRawResponsesThen(questionnaireState, createdModels); | ||
| } | ||
|
|
||
| @ParameterizedTest | ||
| @EnumSource(RawResponseDto.QuestionnaireStateEnum.class) | ||
| @DisplayName("Process by collection instrument id and interrogation id OK test") | ||
| @SneakyThrows | ||
| void processRawResponses_byCollectionInstrumentIdAndInterrogationList_validation_date_questionnaire_state_test( | ||
| RawResponseDto.QuestionnaireStateEnum questionnaireState | ||
| ) { | ||
| //GIVEN | ||
| givenOkCase(questionnaireState); | ||
|
|
||
| //WHEN | ||
| List<SurveyUnitModel> createdModels = whenProcessRawResponsesCollectionInstrumentId(); | ||
|
|
||
| //THEN | ||
| processRawResponsesThen(questionnaireState, createdModels); | ||
| } | ||
|
|
||
| //Non-blocking exception tests | ||
| //Invalid questionnaire state | ||
| @Test | ||
| @DisplayName("Invalid questionnaireState test (process by collection id)") | ||
| @SneakyThrows | ||
| void processRawResponses_byCollectionInstrumentId_invalid_questionnaire_state_test() { | ||
| //GIVEN | ||
| givenInvalidQuestionnaireState(); | ||
|
|
||
| //WHEN | ||
| List<SurveyUnitModel> createdModels = whenProcessRawResponsesCollectionInstrumentId(); | ||
|
|
||
| //THEN | ||
| processRawResponsesThenQuestionnaireStateNull(createdModels); | ||
| } | ||
| @Test | ||
| @DisplayName("Invalid questionnaireState test (process by collection id and interrogation id list)") | ||
| @SneakyThrows | ||
| void processRawResponses_byCollectionInstrumentIdAndInterrogationList_invalid_questionnaire_state_test() { | ||
| //GIVEN | ||
| givenInvalidQuestionnaireState(); | ||
|
|
||
| //WHEN | ||
| List<SurveyUnitModel> createdModels = whenProcessByCollectionInstrumentIdAndInterrogationIdList(); | ||
|
|
||
| //THEN | ||
| processRawResponsesThenQuestionnaireStateNull(createdModels); | ||
| } | ||
|
|
||
| //Invalid validationDate | ||
| @Test | ||
| @DisplayName("Invalid validationDate test (process by collection id)") | ||
| @SneakyThrows | ||
| void processRawResponses_byCollectionId_invalid_validation_date_test(){ | ||
| //GIVEN | ||
| givenInvalidValidationDate(); | ||
|
|
||
| //WHEN | ||
| List<SurveyUnitModel> createdModels = whenProcessByCollectionInstrumentIdAndInterrogationIdList(); | ||
|
|
||
| //THEN | ||
| processRawResponsesThenValidationDateNull(createdModels); | ||
| } | ||
| @Test | ||
| @DisplayName("Invalid validationDate test (process by collection id and interrogation id list)") | ||
| @SneakyThrows | ||
| void processRawResponses_byCollectionIdAndInterrogationIds_invalid_validation_date_test(){ | ||
| //GIVEN | ||
| givenInvalidValidationDate(); | ||
|
|
||
| //WHEN | ||
| List<SurveyUnitModel> createdModels = whenProcessRawResponsesCollectionInstrumentId(); | ||
|
|
||
| //THEN | ||
| processRawResponsesThenValidationDateNull(createdModels); | ||
| } | ||
|
|
||
| //GIVENS | ||
| @SneakyThrows | ||
| private void givenOkCase(RawResponseDto.QuestionnaireStateEnum questionnaireState){ | ||
| VariablesMap variablesMap = new VariablesMap(); | ||
| MetadataModel metadataModel = new MetadataModel(); | ||
| metadataModel.setVariables(variablesMap); | ||
| String validationDate = questionnaireState.equals(RawResponseDto.QuestionnaireStateEnum.FINISHED) ? | ||
| TEST_VALIDATION_DATE : null; | ||
|
|
||
| List<RawResponse> rawResponses = new ArrayList<>(); | ||
| RawResponse rawResponse = new RawResponse( | ||
| null, | ||
| TestConstants.DEFAULT_INTERROGATION_ID, | ||
| TestConstants.DEFAULT_COLLECTION_INSTRUMENT_ID, | ||
| Mode.WEB, | ||
| new HashMap<>(), | ||
| LocalDateTime.now(), | ||
| null | ||
| ); | ||
| rawResponse.payload().put("validationDate", validationDate); | ||
| rawResponse.payload().put("questionnaireState", questionnaireState); | ||
| rawResponse.payload().put("usualSurveyUnitId", TestConstants.DEFAULT_SURVEY_UNIT_ID); | ||
| rawResponse.payload().put("majorModelVersion", 2); | ||
| Map<String, Map<String, Map<String, String>>> dataMap = new HashMap<>(); | ||
| dataMap.put("COLLECTED", new HashMap<>()); | ||
| dataMap.get("COLLECTED").put("VAR1", new HashMap<>()); | ||
| dataMap.get("COLLECTED").get("VAR1").put("COLLECTED", "value"); | ||
| rawResponse.payload().put("data", dataMap); | ||
| rawResponses.add(rawResponse); | ||
|
|
||
| //Mocks behaviour | ||
| doReturn(Collections.singletonList(Mode.WEB)).when(controllerUtils).getModesList(any(),any()); | ||
| doReturn(Set.of(TestConstants.DEFAULT_INTERROGATION_ID)) | ||
| .when(rawResponsePersistencePort).findUnprocessedInterrogationIdsByCollectionInstrumentId(any()); | ||
| doReturn(metadataModel).when(metadataService).loadAndSaveIfNotExists(any(), any(), any(), any(), any()); | ||
| doReturn(rawResponses).when(rawResponsePersistencePort).findRawResponses(any(), any(), any()); | ||
| } | ||
| @SneakyThrows | ||
| private void givenInvalidQuestionnaireState(){ | ||
| VariablesMap variablesMap = new VariablesMap(); | ||
| MetadataModel metadataModel = new MetadataModel(); | ||
| metadataModel.setVariables(variablesMap); | ||
|
|
||
| List<RawResponse> rawResponses = new ArrayList<>(); | ||
| RawResponse rawResponse = new RawResponse( | ||
| null, | ||
| TestConstants.DEFAULT_INTERROGATION_ID, | ||
| TestConstants.DEFAULT_COLLECTION_INSTRUMENT_ID, | ||
| Mode.WEB, | ||
| new HashMap<>(), | ||
| LocalDateTime.now(), | ||
| null | ||
| ); | ||
| rawResponse.payload().put("validationDate", TEST_VALIDATION_DATE); | ||
| rawResponse.payload().put("questionnaireState", "not a questionnaire state"); | ||
| rawResponse.payload().put("usualSurveyUnitId", TestConstants.DEFAULT_SURVEY_UNIT_ID); | ||
| rawResponse.payload().put("majorModelVersion", 2); | ||
| Map<String, Map<String, Map<String, String>>> dataMap = new HashMap<>(); | ||
| dataMap.put("COLLECTED", new HashMap<>()); | ||
| dataMap.get("COLLECTED").put("VAR1", new HashMap<>()); | ||
| dataMap.get("COLLECTED").get("VAR1").put("COLLECTED", "value"); | ||
| rawResponse.payload().put("data", dataMap); | ||
| rawResponses.add(rawResponse); | ||
|
|
||
| //Mocks behaviour | ||
| doReturn(Collections.singletonList(Mode.WEB)).when(controllerUtils).getModesList(any(),any()); | ||
| doReturn(Set.of(TestConstants.DEFAULT_INTERROGATION_ID)) | ||
| .when(rawResponsePersistencePort).findUnprocessedInterrogationIdsByCollectionInstrumentId(any()); | ||
| doReturn(metadataModel).when(metadataService).loadAndSaveIfNotExists(any(), any(), any(), any(), any()); | ||
| doReturn(rawResponses).when(rawResponsePersistencePort).findRawResponses(any(), any(), any()); | ||
| } | ||
| @SneakyThrows | ||
| private void givenInvalidValidationDate(){ | ||
| VariablesMap variablesMap = new VariablesMap(); | ||
| MetadataModel metadataModel = new MetadataModel(); | ||
| metadataModel.setVariables(variablesMap); | ||
|
|
||
| List<RawResponse> rawResponses = new ArrayList<>(); | ||
| RawResponse rawResponse = new RawResponse( | ||
| null, | ||
| TestConstants.DEFAULT_INTERROGATION_ID, | ||
| TestConstants.DEFAULT_COLLECTION_INSTRUMENT_ID, | ||
| Mode.WEB, | ||
| new HashMap<>(), | ||
| LocalDateTime.now(), | ||
| null | ||
| ); | ||
| rawResponse.payload().put("validationDate", "not a validation date"); | ||
| rawResponse.payload().put("questionnaireState", RawResponseDto.QuestionnaireStateEnum.FINISHED); | ||
| rawResponse.payload().put("usualSurveyUnitId", TestConstants.DEFAULT_SURVEY_UNIT_ID); | ||
| rawResponse.payload().put("majorModelVersion", 2); | ||
| Map<String, Map<String, Map<String, String>>> dataMap = new HashMap<>(); | ||
| dataMap.put("COLLECTED", new HashMap<>()); | ||
| dataMap.get("COLLECTED").put("VAR1", new HashMap<>()); | ||
| dataMap.get("COLLECTED").get("VAR1").put("COLLECTED", "value"); | ||
| rawResponse.payload().put("data", dataMap); | ||
| rawResponses.add(rawResponse); | ||
|
|
||
| //Mocks behaviour | ||
| doReturn(Collections.singletonList(Mode.WEB)).when(controllerUtils).getModesList(any(),any()); | ||
| doReturn(Set.of(TestConstants.DEFAULT_INTERROGATION_ID)) | ||
| .when(rawResponsePersistencePort).findUnprocessedInterrogationIdsByCollectionInstrumentId(any()); | ||
| doReturn(metadataModel).when(metadataService).loadAndSaveIfNotExists(any(), any(), any(), any(), any()); | ||
| doReturn(rawResponses).when(rawResponsePersistencePort).findRawResponses(any(), any(), any()); | ||
| } | ||
|
|
||
| //WHENS | ||
| private List<SurveyUnitModel> whenProcessByCollectionInstrumentIdAndInterrogationIdList() throws GenesisException { | ||
| rawResponseService.processRawResponses(TestConstants.DEFAULT_COLLECTION_INSTRUMENT_ID); | ||
| verify(surveyUnitService).saveSurveyUnits(surveyUnitModelsCaptor.capture()); | ||
| return surveyUnitModelsCaptor.getValue(); | ||
| } | ||
| private List<SurveyUnitModel> whenProcessRawResponsesCollectionInstrumentId() throws GenesisException { | ||
| rawResponseService.processRawResponses( | ||
| TestConstants.DEFAULT_COLLECTION_INSTRUMENT_ID, | ||
| Collections.singletonList(TestConstants.DEFAULT_INTERROGATION_ID), | ||
| new ArrayList<>() | ||
| ); | ||
| verify(surveyUnitService).saveSurveyUnits(surveyUnitModelsCaptor.capture()); | ||
| return surveyUnitModelsCaptor.getValue(); | ||
| } | ||
|
|
||
| //THENS | ||
| private void processRawResponsesThen(RawResponseDto.QuestionnaireStateEnum questionnaireState, | ||
| List<SurveyUnitModel> createdModels) { | ||
| Assertions.assertThat(createdModels).hasSize(1); | ||
| if(questionnaireState.equals(RawResponseDto.QuestionnaireStateEnum.FINISHED)){ | ||
| Assertions.assertThat(createdModels.getFirst().getValidationDate()).isEqualTo( | ||
| LocalDateTime.parse(TEST_VALIDATION_DATE, DateTimeFormatter.ISO_OFFSET_DATE_TIME) | ||
| ); | ||
| } | ||
| Assertions.assertThat(createdModels.getFirst().getQuestionnaireState()).isEqualTo(questionnaireState); | ||
| } | ||
| private void processRawResponsesThenValidationDateNull( | ||
| List<SurveyUnitModel> createdModels | ||
| ){ | ||
| Assertions.assertThat(createdModels).hasSize(1); | ||
| Assertions.assertThat(createdModels.getFirst().getValidationDate()).isNull(); | ||
| } | ||
| private void processRawResponsesThenQuestionnaireStateNull(List<SurveyUnitModel> createdModels){ | ||
| Assertions.assertThat(createdModels).hasSize(1); | ||
| Assertions.assertThat(createdModels.getFirst().getQuestionnaireState()).isNull(); | ||
| } | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor suggestion: the RawResponse setup and mocks are repeated in several given methods.
Extracting a small helper could simplify the tests and make the variations (questionnaireState, validationDate) clearer.
@alexisszmundy