diff --git a/pom.xml b/pom.xml index a9f0ad38..de579a52 100644 --- a/pom.xml +++ b/pom.xml @@ -6,12 +6,12 @@ org.springframework.boot spring-boot-starter-parent - 3.2.4 + 3.3.0 fr.insee.survey platine-management - 2.2.3 + 2.3.0 platine-management REST API for communication between DB and Platine-Management UI and Platine-My-Surveys UI @@ -202,4 +202,4 @@ - + \ No newline at end of file diff --git a/renovate.json b/renovate.json index 17869171..1a9060f2 100644 --- a/renovate.json +++ b/renovate.json @@ -43,4 +43,3 @@ "schedule": ["every weekend"], "timezone": "Europe/Paris" } -} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/constants/CheckHabilitationsRoles.java b/src/main/java/fr/insee/survey/datacollectionmanagement/constants/UserRoles.java similarity index 60% rename from src/main/java/fr/insee/survey/datacollectionmanagement/constants/CheckHabilitationsRoles.java rename to src/main/java/fr/insee/survey/datacollectionmanagement/constants/UserRoles.java index 365f581e..df7c0020 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/constants/CheckHabilitationsRoles.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/constants/UserRoles.java @@ -1,6 +1,10 @@ package fr.insee.survey.datacollectionmanagement.constants; -public class CheckHabilitationsRoles { +public class UserRoles { + + private UserRoles() { + throw new IllegalStateException("Utility class"); + } public static final String INTERVIEWER = "interviewer"; public static final String REVIEWER = "reviewer"; } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/CampaignController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/CampaignController.java index 2299032a..8cb6139e 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/CampaignController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/CampaignController.java @@ -5,11 +5,13 @@ import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; import fr.insee.survey.datacollectionmanagement.exception.NotMatchException; import fr.insee.survey.datacollectionmanagement.metadata.domain.Campaign; +import fr.insee.survey.datacollectionmanagement.metadata.domain.Parameters; import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; import fr.insee.survey.datacollectionmanagement.metadata.domain.Survey; import fr.insee.survey.datacollectionmanagement.metadata.dto.CampaignDto; import fr.insee.survey.datacollectionmanagement.metadata.dto.CampaignPartitioningsDto; import fr.insee.survey.datacollectionmanagement.metadata.dto.OnGoingDto; +import fr.insee.survey.datacollectionmanagement.metadata.dto.ParamsDto; import fr.insee.survey.datacollectionmanagement.metadata.service.CampaignService; import fr.insee.survey.datacollectionmanagement.metadata.service.SurveyService; import fr.insee.survey.datacollectionmanagement.questioning.domain.Upload; @@ -37,8 +39,13 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import java.util.Arrays; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; + +import static fr.insee.survey.datacollectionmanagement.questioning.util.UrlTypeEnum.values; +import static java.util.stream.Collectors.joining; @RestController @PreAuthorize("@AuthorizeMethodDecider.isInternalUser() " @@ -109,6 +116,38 @@ public ResponseEntity getCampaign(@PathVariable("id") String id) { } + + @Operation(summary = "Get campaign parameters") + @GetMapping(value = "/api/campaigns/{id}/params", produces = "application/json") + public ResponseEntity> getParams(@PathVariable("id") String id) { + Campaign campaign = campaignService.findById(StringUtils.upperCase(id)); + List listParams = campaign.getParams().stream().map(this::convertToDto).toList(); + return ResponseEntity.ok().body(listParams); + } + + + @Operation(summary = "Create a parameter for a campaign") + @PutMapping(value = "/api/campaigns/{id}/params", produces = "application/json") + public void putParams(@PathVariable("id") String id, @RequestBody @Valid ParamsDto paramsDto) { + Campaign campaign = campaignService.findById(StringUtils.upperCase(id)); + + if (paramsDto.getParamId().equalsIgnoreCase(Parameters.ParameterEnum.URL_TYPE.name()) + && Arrays.stream(values()).noneMatch(p -> p.name().equalsIgnoreCase(paramsDto.getParamValue()))) { + + throw new NotMatchException(String.format("Only %s are valid values for URL_TYPE", Arrays.stream(values()).map(item -> item.name()) + .collect(joining(" ")))); + } + Parameters param = convertToEntity(paramsDto); + param.setMetadataId(StringUtils.upperCase(id)); + Set setParams = campaign.getParams().stream() + .filter(parameter -> !parameter.getParamId().equals(param.getParamId())) + .collect(Collectors.toSet()); + setParams.add(param); + campaign.setParams(setParams); + campaignService.insertOrUpdateCampaign(campaign); + } + + @Operation(summary = "Update or create a campaign") @PutMapping(value = Constants.API_CAMPAIGNS_ID, produces = "application/json", consumes = "application/json") @ApiResponses(value = { @@ -189,6 +228,10 @@ private CampaignDto convertToDto(Campaign campaign) { return modelmapper.map(campaign, CampaignDto.class); } + private ParamsDto convertToDto(Parameters params) { + return modelmapper.map(params, ParamsDto.class); + } + private CampaignPartitioningsDto convertToCampaignPartitioningsDto(Campaign campaign) { return modelmapper.map(campaign, CampaignPartitioningsDto.class); } @@ -197,6 +240,13 @@ private Campaign convertToEntity(CampaignDto campaignDto) { return modelmapper.map(campaignDto, Campaign.class); } + private Parameters convertToEntity(ParamsDto paramsDto) { + + Parameters params = modelmapper.map(paramsDto, Parameters.class); + params.setParamId(Parameters.ParameterEnum.valueOf(paramsDto.getParamId())); + return params; + } + class CampaignPage extends PageImpl { public CampaignPage(List content, Pageable pageable, long total) { diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Campaign.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Campaign.java index 26a15a1d..9f533506 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Campaign.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Campaign.java @@ -33,6 +33,10 @@ public class Campaign { @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) private Set partitionings; + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @Enumerated(EnumType.STRING) + private Set params; + @ManyToOne private Survey survey; diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Parameters.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Parameters.java new file mode 100644 index 00000000..379bae31 --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Parameters.java @@ -0,0 +1,30 @@ +package fr.insee.survey.datacollectionmanagement.metadata.domain; + +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.Id; +import jakarta.persistence.*; +import lombok.Data; +import lombok.Getter; + +@Entity +@Data +public class Parameters { + + @Getter + public enum ParameterEnum { + URL_REDIRECTION,URL_TYPE; + } + + @Id + private String metadataId; + + @Id + @Enumerated(EnumType.STRING) + private ParameterEnum paramId; + + @Column(length = 2000) + private String paramValue; + +} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Partitioning.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Partitioning.java index 29c661a2..f3bb0ab1 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Partitioning.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Partitioning.java @@ -5,6 +5,7 @@ import lombok.Setter; import java.util.Date; +import java.util.Set; @Entity @Getter @@ -24,4 +25,8 @@ public class Partitioning { @ManyToOne private Campaign campaign; + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @Enumerated(EnumType.STRING) + private Set params; + } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Source.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Source.java index c730b59a..ccf0a4e0 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Source.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Source.java @@ -40,4 +40,8 @@ public class Source { @NonNull private Support support; + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @Enumerated(EnumType.STRING) + private Set params; + } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Survey.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Survey.java index 2d65b999..3e80e42d 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Survey.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Survey.java @@ -39,6 +39,10 @@ public class Survey { @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) private Set campaigns; + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @Enumerated(EnumType.STRING) + private Set params; + @ManyToOne private Source source; diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/ParamsDto.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/ParamsDto.java new file mode 100644 index 00000000..fda19559 --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/ParamsDto.java @@ -0,0 +1,13 @@ +package fr.insee.survey.datacollectionmanagement.metadata.dto; + +import fr.insee.survey.datacollectionmanagement.metadata.validation.ParameterEnumValid; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class ParamsDto { + @ParameterEnumValid + private String paramId; + private String paramValue; +} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/PartitioningService.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/PartitioningService.java index 88d46070..60bbea05 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/PartitioningService.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/PartitioningService.java @@ -1,5 +1,6 @@ package fr.insee.survey.datacollectionmanagement.metadata.service; +import fr.insee.survey.datacollectionmanagement.metadata.domain.Parameters; import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; import java.util.Date; @@ -14,4 +15,8 @@ public interface PartitioningService { boolean isOnGoing(Partitioning part, Date date); + String findSuitableParameterValue(Partitioning part, Parameters.ParameterEnum paramValue); + + + } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/impl/PartioningServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/impl/PartioningServiceImpl.java index e1972d07..c643451f 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/impl/PartioningServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/impl/PartioningServiceImpl.java @@ -1,6 +1,7 @@ package fr.insee.survey.datacollectionmanagement.metadata.service.impl; import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; +import fr.insee.survey.datacollectionmanagement.metadata.domain.Parameters; import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; import fr.insee.survey.datacollectionmanagement.metadata.repository.PartitioningRepository; import fr.insee.survey.datacollectionmanagement.metadata.service.PartitioningService; @@ -9,6 +10,8 @@ import org.springframework.stereotype.Service; import java.util.Date; +import java.util.Optional; +import java.util.Set; @Service @Slf4j @@ -40,4 +43,23 @@ public void deletePartitioningById(String id) { public boolean isOnGoing(Partitioning part, Date date) { return part.getClosingDate().compareTo(date) > 0 && part.getOpeningDate().compareTo(date) < 0; } + + @Override + public String findSuitableParameterValue(Partitioning part, Parameters.ParameterEnum paramValue) { + return findParameterValueInSet(part.getParams(), paramValue) + .orElse(findParameterValueInSet(part.getCampaign().getParams(), paramValue) + .orElse(findParameterValueInSet(part.getCampaign().getSurvey().getParams(), paramValue) + .orElse(findParameterValueInSet(part.getCampaign().getSurvey().getSource().getParams(), paramValue) + .orElse("")))); + } + + private Optional findParameterValueInSet(Set params, Parameters.ParameterEnum paramValue) { + return params.stream() + .filter(param -> param.getParamId().equals(paramValue)) + .map(Parameters::getParamValue) + .findFirst(); + } + + + } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/validation/ParameterEnumValid.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/validation/ParameterEnumValid.java new file mode 100644 index 00000000..471b9487 --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/validation/ParameterEnumValid.java @@ -0,0 +1,26 @@ +package fr.insee.survey.datacollectionmanagement.metadata.validation; + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; + +@Target({FIELD, PARAMETER, METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Constraint(validatedBy = ParameterEnumValidator.class) +public @interface ParameterEnumValid { + //error message + String message() default "Type missing or not recognized. Only URL_REDIRECTION,URL_TYPE are valid"; + + //represents group of constraints + Class[] groups() default {}; + + //represents additional information about annotation + Class[] payload() default {}; +} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/validation/ParameterEnumValidator.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/validation/ParameterEnumValidator.java new file mode 100644 index 00000000..4a57206c --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/validation/ParameterEnumValidator.java @@ -0,0 +1,23 @@ +package fr.insee.survey.datacollectionmanagement.metadata.validation; + +import fr.insee.survey.datacollectionmanagement.metadata.domain.Parameters; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; + +import java.util.Arrays; + +public class ParameterEnumValidator implements ConstraintValidator { + + + @Override + public void initialize(ParameterEnumValid constraintAnnotation) { + ConstraintValidator.super.initialize(constraintAnnotation); + } + + @Override + public boolean isValid(String value, ConstraintValidatorContext context) { + if (value == null) + return false; + return Arrays.stream(Parameters.ParameterEnum.values()).anyMatch(v -> value.equalsIgnoreCase(v.name())); + } +} \ No newline at end of file diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/CheckHabilitationServiceImplOidc.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/CheckHabilitationServiceImplOidc.java index 7a6b39a8..2d59e1a0 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/CheckHabilitationServiceImplOidc.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/CheckHabilitationServiceImplOidc.java @@ -3,7 +3,7 @@ import fr.insee.survey.datacollectionmanagement.config.ApplicationConfig; import fr.insee.survey.datacollectionmanagement.config.auth.user.AuthUser; import fr.insee.survey.datacollectionmanagement.constants.AuthConstants; -import fr.insee.survey.datacollectionmanagement.constants.CheckHabilitationsRoles; +import fr.insee.survey.datacollectionmanagement.constants.UserRoles; import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; import fr.insee.survey.datacollectionmanagement.query.service.CheckHabilitationService; import fr.insee.survey.datacollectionmanagement.user.domain.User; @@ -40,7 +40,7 @@ public boolean checkHabilitation(String role, String idSu, String campaignId, Au } //respondents - if (role == null || role.isBlank() || role.equals(CheckHabilitationsRoles.INTERVIEWER)) { + if (role == null || role.isBlank() || role.equals(UserRoles.INTERVIEWER)) { if (isUserInRole(authUser.getRoles(), applicationConfig.getRoleRespondent())) { boolean habilitated = viewService.countViewByIdentifierIdSuCampaignId(userId.toUpperCase(), idSu, campaignId) != 0; log.info("Check habilitation of interviewer {} for accessing survey-unit {} of campaign {} resulted in {}", userId, idSu, campaignId, habilitated); @@ -52,7 +52,7 @@ public boolean checkHabilitation(String role, String idSu, String campaignId, Au // internal users - if (!role.equals(CheckHabilitationsRoles.REVIEWER)) { + if (!role.equals(UserRoles.REVIEWER)) { log.warn("User {} - internal user habilitation not found in token - Check habilitation:false", userId); return false; } @@ -76,7 +76,7 @@ public boolean checkHabilitation(String role, String idSu, String campaignId, Au } - log.warn("Only '{}' and '{}' are accepted as a role in query argument", CheckHabilitationsRoles.REVIEWER, CheckHabilitationsRoles.INTERVIEWER); + log.warn("Only '{}' and '{}' are accepted as a role in query argument", UserRoles.REVIEWER, UserRoles.INTERVIEWER); return false; } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/MoogServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/MoogServiceImpl.java index 562d5aef..4a9a4171 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/MoogServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/MoogServiceImpl.java @@ -1,13 +1,15 @@ package fr.insee.survey.datacollectionmanagement.query.service.impl; -import fr.insee.survey.datacollectionmanagement.config.ApplicationConfig; import fr.insee.survey.datacollectionmanagement.config.JSONCollectionWrapper; +import fr.insee.survey.datacollectionmanagement.constants.UserRoles; import fr.insee.survey.datacollectionmanagement.contact.domain.Contact; import fr.insee.survey.datacollectionmanagement.contact.service.ContactService; import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; import fr.insee.survey.datacollectionmanagement.metadata.domain.Campaign; +import fr.insee.survey.datacollectionmanagement.metadata.domain.Parameters; import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; import fr.insee.survey.datacollectionmanagement.metadata.service.CampaignService; +import fr.insee.survey.datacollectionmanagement.metadata.service.PartitioningService; import fr.insee.survey.datacollectionmanagement.query.domain.MoogCampaign; import fr.insee.survey.datacollectionmanagement.query.dto.MoogExtractionRowDto; import fr.insee.survey.datacollectionmanagement.query.dto.MoogQuestioningEventDto; @@ -22,7 +24,10 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; @Service @Slf4j @@ -41,7 +46,7 @@ public class MoogServiceImpl implements MoogService { private final QuestioningService questioningService; - private final ApplicationConfig applicationConfig; + private final PartitioningService partitioningService; @Override public List moogSearch(String field) { @@ -58,7 +63,7 @@ public List transformListViewToListMoogSearchDto(List listV MoogSearchDto moogSearchDto = new MoogSearchDto(); Contact c = contactService.findByIdentifier(view.getIdentifier()); Campaign camp = campaignService.findById(view.getCampaignId()); - MoogCampaign moogCampaign = new MoogCampaign(); + MoogCampaign moogCampaign = new MoogCampaign(); moogCampaign.setId(view.getCampaignId()); moogCampaign.setLabel(camp.getCampaignWording()); moogCampaign @@ -108,19 +113,16 @@ public Collection getSurveyUnitsToFollowUp(String idCampai public String getReadOnlyUrl(String idCampaign, String surveyUnitId) throws NotFoundException { Campaign campaign = campaignService.findById(idCampaign); Set setParts = campaign.getPartitionings(); - Questioning questioning = null; - for (Partitioning part : setParts){ - Questioning qTemp = questioningService.findByIdPartitioningAndSurveyUnitIdSu(part.getId(), surveyUnitId); - if(qTemp!=null){ - questioning =qTemp; - break; + for (Partitioning part : setParts) { + Questioning questioning = questioningService.findByIdPartitioningAndSurveyUnitIdSu(part.getId(), surveyUnitId); + if (questioning != null) { + String accessBaseUrl = partitioningService.findSuitableParameterValue(part, Parameters.ParameterEnum.URL_REDIRECTION); + String typeUrl = partitioningService.findSuitableParameterValue(part, Parameters.ParameterEnum.URL_TYPE); + String sourceId = campaign.getSurvey().getSource().getId().toLowerCase(); + return questioningService.getAccessUrl(accessBaseUrl, typeUrl, UserRoles.REVIEWER, questioning, surveyUnitId, sourceId); } } - if(questioning!=null) { - return applicationConfig.getQuestioningUrl() + READONLY_QUESTIONNAIRE + questioning.getModelName() - + UNITE_ENQUETEE + surveyUnitId; - } - String msg = "0 questioning found for campaign "+idCampaign+" and survey unit "+ surveyUnitId; + String msg = "0 questioning found for campaign " + idCampaign + " and survey unit " + surveyUnitId; log.error(msg); throw new NotFoundException(msg); } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/MySurveysServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/MySurveysServiceImpl.java index aa55bd8c..c2755375 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/MySurveysServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/MySurveysServiceImpl.java @@ -1,5 +1,7 @@ package fr.insee.survey.datacollectionmanagement.query.service.impl; +import fr.insee.survey.datacollectionmanagement.constants.UserRoles; +import fr.insee.survey.datacollectionmanagement.metadata.domain.Parameters; import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; import fr.insee.survey.datacollectionmanagement.metadata.domain.Survey; import fr.insee.survey.datacollectionmanagement.metadata.service.PartitioningService; @@ -48,8 +50,11 @@ public List getListMySurveys(String id) { String surveyUnitId = questioning.getSurveyUnit().getIdSu(); surveyDto.setSurveyWording(survey.getLongWording()); surveyDto.setSurveyObjectives(survey.getLongObjectives()); + String accessBaseUrl = partitioningService.findSuitableParameterValue(part, Parameters.ParameterEnum.URL_REDIRECTION); + String typeUrl = partitioningService.findSuitableParameterValue(part, Parameters.ParameterEnum.URL_TYPE); + String sourceId = survey.getSource().getId().toLowerCase(); surveyDto.setAccessUrl( - questioningService.getAccessUrl(questioning, surveyUnitId)); + questioningService.getAccessUrl(accessBaseUrl,typeUrl, UserRoles.INTERVIEWER, questioning, surveyUnitId, sourceId)); surveyDto.setIdentificationCode(surveyUnitId); surveyDto.setOpeningDate(new Timestamp(part.getOpeningDate().getTime())); surveyDto.setClosingDate(new Timestamp(part.getClosingDate().getTime())); diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/QuestioningService.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/QuestioningService.java index cd35e88d..26b250d7 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/QuestioningService.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/QuestioningService.java @@ -23,7 +23,7 @@ public interface QuestioningService { /** * Delete questionings attached to one partitioning - * + * * @param partitioning * @return nb questioning deleted */ @@ -31,8 +31,7 @@ public interface QuestioningService { public Set findBySurveyUnitIdSu(String idSu); - public String getAccessUrl(Questioning questioning, String surveyUnitId); - + public String getAccessUrl(String baseUrl, String typeUrl, String role, Questioning questioning, String surveyUnitId, String sourceId); } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/QuestioningServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/QuestioningServiceImpl.java index bce0bfd7..453e86ae 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/QuestioningServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/QuestioningServiceImpl.java @@ -1,6 +1,7 @@ package fr.insee.survey.datacollectionmanagement.questioning.service.impl; import fr.insee.survey.datacollectionmanagement.config.ApplicationConfig; +import fr.insee.survey.datacollectionmanagement.constants.UserRoles; import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; import fr.insee.survey.datacollectionmanagement.questioning.domain.Questioning; @@ -11,12 +12,18 @@ import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningService; import fr.insee.survey.datacollectionmanagement.questioning.service.SurveyUnitService; import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.StringUtils; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; +import org.springframework.web.util.UriComponentsBuilder; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.util.Set; +import static fr.insee.survey.datacollectionmanagement.questioning.util.UrlTypeEnum.*; + @Service @RequiredArgsConstructor public class QuestioningServiceImpl implements QuestioningService { @@ -31,6 +38,9 @@ public class QuestioningServiceImpl implements QuestioningService { private final ApplicationConfig applicationConfig; + private static final String PATH_LOGOUT = "pathLogout"; + private static final String PATH_ASSISTANCE = "pathAssistance"; + @Override public Page findAll(Pageable pageable) { return questioningRepository.findAll(pageable); @@ -56,6 +66,13 @@ public Set findByIdPartitioning(String idPartitioning) { return questioningRepository.findByIdPartitioning(idPartitioning); } + @Override + public Questioning findByIdPartitioningAndSurveyUnitIdSu(String idPartitioning, + String surveyUnitIdSu) { + return questioningRepository.findByIdPartitioningAndSurveyUnitIdSu(idPartitioning, + surveyUnitIdSu); + } + @Override public int deleteQuestioningsOfOnePartitioning(Partitioning partitioning) { int nbQuestioningDeleted = 0; @@ -66,7 +83,7 @@ public int deleteQuestioningsOfOnePartitioning(Partitioning partitioning) { surveyUnitService.saveSurveyUnit(su); q.getQuestioningEvents().stream().forEach(qe -> questioningEventService.deleteQuestioningEvent(qe.getId())); q.getQuestioningAccreditations().stream() - .forEach(qa -> questioningAccreditationService.deleteAccreditation(qa)); + .forEach(questioningAccreditationService::deleteAccreditation); deleteQuestioning(q.getId()); nbQuestioningDeleted++; } @@ -78,18 +95,95 @@ public Set findBySurveyUnitIdSu(String idSu) { return questioningRepository.findBySurveyUnitIdSu(idSu); } - @Override - public String getAccessUrl(Questioning questioning, String surveyUnitId) { - return applicationConfig.getQuestioningUrl() + "/questionnaire/" + questioning.getModelName() - + "/unite-enquetee/" + surveyUnitId; + + /** + * Generates an access URL based on the provided parameters. + * + * @param baseUrl The base URL for the access. + * @param typeUrl The type of URL (V1 or V2). + * @param role The user role (REVIEWER or INTERVIEWER). + * @param questioning The questioning object. + * @param surveyUnitId The survey unit ID. + * @return The generated access URL. + */ + public String getAccessUrl(String baseUrl, String typeUrl, String role, Questioning questioning, String surveyUnitId, String sourceId) { + // Set default values if baseUrl or typeUrl is empty + baseUrl = StringUtils.defaultIfEmpty(baseUrl, applicationConfig.getQuestioningUrl()); + typeUrl = StringUtils.defaultIfEmpty(typeUrl, V2.name()); + + if (typeUrl.equalsIgnoreCase(V1.name())) { + return buildV1Url(baseUrl, role, questioning.getModelName(), surveyUnitId); + } + if (typeUrl.equalsIgnoreCase(V2.name())) { + return buildV2Url(baseUrl, role, questioning.getModelName(), surveyUnitId); + } + if (typeUrl.equalsIgnoreCase(V3.name())) { + return buildV3Url(baseUrl, role, questioning.getModelName(), surveyUnitId, sourceId, questioning.getId()); + } + + return ""; } - @Override - public Questioning findByIdPartitioningAndSurveyUnitIdSu(String idPartitioning, - String surveyUnitIdSu) { - return questioningRepository.findByIdPartitioningAndSurveyUnitIdSu(idPartitioning, - surveyUnitIdSu); + + /** + * Builds a V1 access URL based on the provided parameters. + * + * @param baseUrl The base URL for the access. + * @param role The user role (REVIEWER or INTERVIEWER). + * @param campaignId The campaign ID. + * @param surveyUnitId The survey unit ID. + * @return The generated V1 access URL. + */ + protected String buildV1Url(String baseUrl, String role, String campaignId, String surveyUnitId) { + if (role.equalsIgnoreCase(UserRoles.REVIEWER)) { + return String.format("%s/visualiser/%s/%s", baseUrl, campaignId, surveyUnitId); + } + if (role.equalsIgnoreCase(UserRoles.INTERVIEWER)) { + return String.format("%s/repondre/%s/%s", baseUrl, campaignId, surveyUnitId); + } + return ""; + } + + /** + * Builds a V3 access URL based on the provided parameters + * @param baseUrl host url + * @param role + * @param modelName + * @param surveyUnitId + * @return The generated V3 access URL. + */ + + protected String buildV2Url(String baseUrl, String role, String modelName, String surveyUnitId) { + if (UserRoles.REVIEWER.equalsIgnoreCase(role)) { + return String.format("%s/readonly/questionnaire/%s/unite-enquetee/%s", baseUrl, modelName, surveyUnitId); + } + if (UserRoles.INTERVIEWER.equalsIgnoreCase(role)) { + return String.format("%s/questionnaire/%s/unite-enquetee/%s", baseUrl, modelName, surveyUnitId); + } + return ""; + } + + /** + * Builds a V3 access URL based on the provided parameters + * @param baseUrl + * @param role + * @param modelName + * @param surveyUnitId + * @param sourceId + * @return The generated V3 access URL. + */ + protected String buildV3Url(String baseUrl, String role, String modelName, String surveyUnitId, String sourceId, Long questioningId) { + if (UserRoles.REVIEWER.equalsIgnoreCase(role)) { + return UriComponentsBuilder.fromHttpUrl(String.format("%s/v3/review/questionnaire/%s/unite-enquetee/%s", baseUrl, modelName, surveyUnitId)).toUriString(); + } + if (UserRoles.INTERVIEWER.equalsIgnoreCase(role)) { + return UriComponentsBuilder.fromHttpUrl(String.format("%s/v3/questionnaire/%s/unite-enquetee/%s", baseUrl, modelName, surveyUnitId)) + .queryParam(PATH_LOGOUT, URLEncoder.encode("/" + sourceId, StandardCharsets.UTF_8)) + .queryParam(PATH_ASSISTANCE, URLEncoder.encode("/" + sourceId + "/contacter-assistance/auth?questioningId=" + questioningId, StandardCharsets.UTF_8)) + .build().toUriString(); + } + return ""; } -} + } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/util/UrlTypeEnum.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/util/UrlTypeEnum.java new file mode 100644 index 00000000..fe2251cf --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/util/UrlTypeEnum.java @@ -0,0 +1,7 @@ +package fr.insee.survey.datacollectionmanagement.questioning.util; + +public enum UrlTypeEnum { + V1, + V2, + V3, +} diff --git a/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/repository/dummy/QuestioningRepositoryDummy.java b/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/repository/dummy/QuestioningRepositoryDummy.java new file mode 100644 index 00000000..625976e1 --- /dev/null +++ b/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/repository/dummy/QuestioningRepositoryDummy.java @@ -0,0 +1,181 @@ +package fr.insee.survey.datacollectionmanagement.questioning.repository.dummy; + +import fr.insee.survey.datacollectionmanagement.questioning.domain.Questioning; +import fr.insee.survey.datacollectionmanagement.questioning.repository.QuestioningRepository; +import org.springframework.data.domain.Example; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.repository.query.FluentQuery; + +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.function.Function; + +public class QuestioningRepositoryDummy implements QuestioningRepository { + @Override + public Set findByIdPartitioning(String idPartitioning) { + return null; + } + + @Override + public Questioning findByIdPartitioningAndSurveyUnitIdSu(String idPartitioning, String surveyUnitIdSu) { + return null; + } + + @Override + public Set findBySurveyUnitIdSu(String idSu) { + return null; + } + + @Override + public void flush() { + + } + + @Override + public S saveAndFlush(S entity) { + return null; + } + + @Override + public List saveAllAndFlush(Iterable entities) { + return null; + } + + @Override + public void deleteAllInBatch(Iterable entities) { + + } + + @Override + public void deleteAllByIdInBatch(Iterable longs) { + + } + + @Override + public void deleteAllInBatch() { + + } + + @Override + public Questioning getOne(Long aLong) { + return null; + } + + @Override + public Questioning getById(Long aLong) { + return null; + } + + @Override + public Questioning getReferenceById(Long aLong) { + return null; + } + + @Override + public Optional findOne(Example example) { + return Optional.empty(); + } + + @Override + public List findAll(Example example) { + return null; + } + + @Override + public List findAll(Example example, Sort sort) { + return null; + } + + @Override + public Page findAll(Example example, Pageable pageable) { + return null; + } + + @Override + public long count(Example example) { + return 0; + } + + @Override + public boolean exists(Example example) { + return false; + } + + @Override + public R findBy(Example example, Function, R> queryFunction) { + return null; + } + + @Override + public S save(S entity) { + return null; + } + + @Override + public List saveAll(Iterable entities) { + return null; + } + + @Override + public Optional findById(Long aLong) { + return Optional.empty(); + } + + @Override + public boolean existsById(Long aLong) { + return false; + } + + @Override + public List findAll() { + return null; + } + + @Override + public List findAllById(Iterable longs) { + return null; + } + + @Override + public long count() { + return 0; + } + + @Override + public void deleteById(Long aLong) { + + } + + @Override + public void delete(Questioning entity) { + + } + + @Override + public void deleteAllById(Iterable longs) { + + } + + @Override + public void deleteAll(Iterable entities) { + + } + + @Override + public void deleteAll() { + + } + + @Override + public List findAll(Sort sort) { + return null; + } + + @Override + public Page findAll(Pageable pageable) { + return null; + } +} diff --git a/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/service/dummy/QuestioningAccreditationServiceDummy.java b/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/service/dummy/QuestioningAccreditationServiceDummy.java new file mode 100644 index 00000000..d0088fac --- /dev/null +++ b/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/service/dummy/QuestioningAccreditationServiceDummy.java @@ -0,0 +1,35 @@ +package fr.insee.survey.datacollectionmanagement.questioning.service.dummy; + +import fr.insee.survey.datacollectionmanagement.questioning.domain.QuestioningAccreditation; +import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningAccreditationService; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +import java.util.List; + +public class QuestioningAccreditationServiceDummy implements QuestioningAccreditationService { + @Override + public List findByContactIdentifier(String id) { + return null; + } + + @Override + public Page findAll(Pageable pageable) { + return null; + } + + @Override + public QuestioningAccreditation findById(Long id) { + return null; + } + + @Override + public QuestioningAccreditation saveQuestioningAccreditation(QuestioningAccreditation questioningAccreditation) { + return null; + } + + @Override + public void deleteAccreditation(QuestioningAccreditation c) { + + } +} diff --git a/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/service/dummy/QuestioningEventServiceDummy.java b/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/service/dummy/QuestioningEventServiceDummy.java new file mode 100644 index 00000000..660a3ebc --- /dev/null +++ b/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/service/dummy/QuestioningEventServiceDummy.java @@ -0,0 +1,36 @@ +package fr.insee.survey.datacollectionmanagement.questioning.service.dummy; + +import fr.insee.survey.datacollectionmanagement.questioning.domain.Questioning; +import fr.insee.survey.datacollectionmanagement.questioning.domain.QuestioningEvent; +import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningEventService; +import fr.insee.survey.datacollectionmanagement.questioning.util.TypeQuestioningEvent; + +import java.util.List; +import java.util.Optional; + +public class QuestioningEventServiceDummy implements QuestioningEventService { + @Override + public QuestioningEvent findbyId(Long id) { + return null; + } + + @Override + public QuestioningEvent saveQuestioningEvent(QuestioningEvent questioningEvent) { + return null; + } + + @Override + public void deleteQuestioningEvent(Long id) { + + } + + @Override + public Optional getLastQuestioningEvent(Questioning questioning, List events) { + return Optional.empty(); + } + + @Override + public List findbyIdUpload(Long id) { + return null; + } +} diff --git a/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/service/dummy/SurveyUnitServiceDummy.java b/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/service/dummy/SurveyUnitServiceDummy.java new file mode 100644 index 00000000..63d0c6c7 --- /dev/null +++ b/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/service/dummy/SurveyUnitServiceDummy.java @@ -0,0 +1,50 @@ +package fr.insee.survey.datacollectionmanagement.questioning.service.dummy; + +import fr.insee.survey.datacollectionmanagement.questioning.domain.SurveyUnit; +import fr.insee.survey.datacollectionmanagement.questioning.service.SurveyUnitService; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +import java.util.List; + +public class SurveyUnitServiceDummy implements SurveyUnitService { + @Override + public SurveyUnit findbyId(String idSu) { + return null; + } + + @Override + public List findbyIdentificationCode(String identificationCode) { + return null; + } + + @Override + public List findbyIdentificationName(String identificationName) { + return null; + } + + @Override + public Page findAll(Pageable pageable) { + return null; + } + + @Override + public Page findByParameters(String idSu, String identificationCode, String identificationName, Pageable pageable) { + return null; + } + + @Override + public SurveyUnit saveSurveyUnit(SurveyUnit surveyUnit) { + return null; + } + + @Override + public SurveyUnit saveSurveyUnitAndAddress(SurveyUnit surveyUnit) { + return null; + } + + @Override + public void deleteSurveyUnit(String id) { + + } +} diff --git a/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/QuestioningServiceImplTest.java b/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/QuestioningServiceImplTest.java new file mode 100644 index 00000000..ad9c13ad --- /dev/null +++ b/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/QuestioningServiceImplTest.java @@ -0,0 +1,108 @@ +package fr.insee.survey.datacollectionmanagement.questioning.service.impl; + +import fr.insee.survey.datacollectionmanagement.config.ApplicationConfig; +import fr.insee.survey.datacollectionmanagement.constants.UserRoles; +import fr.insee.survey.datacollectionmanagement.questioning.repository.QuestioningRepository; +import fr.insee.survey.datacollectionmanagement.questioning.repository.dummy.QuestioningRepositoryDummy; +import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningAccreditationService; +import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningEventService; +import fr.insee.survey.datacollectionmanagement.questioning.service.SurveyUnitService; +import fr.insee.survey.datacollectionmanagement.questioning.service.dummy.QuestioningAccreditationServiceDummy; +import fr.insee.survey.datacollectionmanagement.questioning.service.dummy.QuestioningEventServiceDummy; +import fr.insee.survey.datacollectionmanagement.questioning.service.dummy.SurveyUnitServiceDummy; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class QuestioningServiceImplTest { + + QuestioningServiceImpl questioningService; + + @BeforeEach + void init() { + QuestioningRepository questioningRepository = new QuestioningRepositoryDummy(); + SurveyUnitService surveyUnitService = new SurveyUnitServiceDummy(); + QuestioningEventService questioningEventService = new QuestioningEventServiceDummy(); + QuestioningAccreditationService questioningAccreditationService = new QuestioningAccreditationServiceDummy(); + ApplicationConfig applicationConfig = new ApplicationConfig(); + questioningService = new QuestioningServiceImpl(questioningRepository, surveyUnitService, questioningEventService, questioningAccreditationService, applicationConfig); + } + + @Test + @DisplayName("Check the V1 url in interviewer mode") + void getV1UrlInterviewer() { + String baseUrl = "https://urlBase"; + String role = UserRoles.INTERVIEWER; + String modelName = "m1"; + String surveyUnitId = "999999999"; + String url= questioningService.buildV1Url(baseUrl, role, modelName, surveyUnitId); + String expected = "https://urlBase/repondre/m1/999999999"; + assertThat(url).isEqualTo(expected); + } + + @Test + @DisplayName("Check the V1 url in reviewer mode") + void getV1UrlReviewer() { + String baseUrl = "https://urlBase"; + String role = UserRoles.REVIEWER; + String modelName = "m1"; + String surveyUnitId = "999999999"; + String url= questioningService.buildV1Url(baseUrl, role, modelName, surveyUnitId); + String expected = "https://urlBase/visualiser/m1/999999999"; + assertThat(url).isEqualTo(expected); + } + + @Test + @DisplayName("Check the V2 url in interviewer mode") + void getV2UrlInterviewer() { + String baseUrl = "https://urlBase"; + String role = UserRoles.INTERVIEWER; + String modelName = "model"; + String surveyUnitId = "999999999"; + String url= questioningService.buildV2Url(baseUrl, role, modelName, surveyUnitId); + String expected = "https://urlBase/questionnaire/model/unite-enquetee/999999999"; + assertThat(url).isEqualTo(expected); + } + + @Test + @DisplayName("Check the V2 url in reviewer mode") + void getV2UrlReviewer() { + String baseUrl = "https://urlBase"; + String role = UserRoles.REVIEWER; + String modelName = "model"; + String surveyUnitId = "999999999"; + String url= questioningService.buildV2Url(baseUrl, role, modelName, surveyUnitId); + String expected = "https://urlBase/readonly/questionnaire/model/unite-enquetee/999999999"; + assertThat(url).isEqualTo(expected); + } + @Test + @DisplayName("Check the V3 url in interviewer mode") + void getV3UrlInterviewer() { + String baseUrl = "https://urlBase"; + String role = UserRoles.INTERVIEWER; + String modelName = "model"; + String surveyUnitId = "999999999"; + String sourceId = "enq"; + Long questioningId = 123456789L; + String url= questioningService.buildV3Url(baseUrl, role, modelName, surveyUnitId, sourceId, questioningId); + String expected = "https://urlBase/v3/questionnaire/model/unite-enquetee/999999999?pathLogout=%2Fenq&pathAssistance=%2Fenq%2Fcontacter-assistance%2Fauth%3FquestioningId%3D123456789"; + assertThat(url).isEqualTo(expected); + } + + @Test + @DisplayName("Check the V3 url in reviewer mode") + void getV3UrlReviewer() { + String baseUrl = "https://urlBase"; + String role = UserRoles.REVIEWER; + String modelName = "model"; + String surveyUnitId = "999999999"; + String sourceId = "enq"; + Long questioningId = 123456789L; + String url= questioningService.buildV3Url(baseUrl, role, modelName, surveyUnitId, sourceId, questioningId); + String expected = "https://urlBase/v3/review/questionnaire/model/unite-enquetee/999999999"; + assertThat(url).isEqualTo(expected); + } + +} \ No newline at end of file