From f5a06f4f1c3498ea7424452b18fbfc939c602dfc Mon Sep 17 00:00:00 2001 From: y72wvh Date: Fri, 24 Nov 2023 13:41:52 +0100 Subject: [PATCH] fix: sonar bugs --- pom.xml | 5 + .../config/CorsGlobalConfig.java | 2 +- .../{util => dataloader}/Dataloader.java | 127 +++++++-------- .../{util => dataloader}/DataloaderPoc.java | 2 +- .../query/controller/WebclientController.java | 10 +- .../service/impl/UploadServiceImpl.java | 48 +++--- .../user/controller/UserController.java | 47 +++--- .../user/controller/UserEventController.java | 7 +- .../user/dto/UserEventDto.java | 3 +- .../user/service/UserService.java | 6 +- .../user/service/impl/UserServiceImpl.java | 6 +- .../validation/UserEventTypeValidator.java | 2 +- .../user/validation/UserRoleValidator.java | 2 +- .../DataloaderTest.java | 15 +- .../controller/UserControllerTest.java | 144 ++++++++++++++++++ .../controller/UserEventControllerTest.java | 57 +++++++ 16 files changed, 356 insertions(+), 127 deletions(-) rename src/main/java/fr/insee/survey/datacollectionmanagement/{util => dataloader}/Dataloader.java (87%) rename src/main/java/fr/insee/survey/datacollectionmanagement/{util => dataloader}/DataloaderPoc.java (99%) rename src/test/java/fr/insee/survey/datacollectionmanagement/{config => dataloader}/DataloaderTest.java (97%) create mode 100644 src/test/java/fr/insee/survey/datacollectionmanagement/user/controller/controller/UserControllerTest.java create mode 100644 src/test/java/fr/insee/survey/datacollectionmanagement/user/controller/controller/UserEventControllerTest.java diff --git a/pom.xml b/pom.xml index 1ca885cb..dfc7f90f 100644 --- a/pom.xml +++ b/pom.xml @@ -141,6 +141,11 @@ org.jacoco jacoco-maven-plugin 0.8.11 + + + **/dataloader/**/*.class + + prepare-agent diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/config/CorsGlobalConfig.java b/src/main/java/fr/insee/survey/datacollectionmanagement/config/CorsGlobalConfig.java index 928fec41..5c387d8f 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/config/CorsGlobalConfig.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/config/CorsGlobalConfig.java @@ -19,7 +19,7 @@ public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { - String ao = applicationConfig.getAllowedOrigin().isPresent() ? applicationConfig.getAllowedOrigin().get() : applicationConfig.getAllowedOrigin().orElse("*"); + String ao = applicationConfig.getAllowedOrigin().orElse("*"); registry.addMapping("/**") .allowedOrigins(ao) .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE") diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/util/Dataloader.java b/src/main/java/fr/insee/survey/datacollectionmanagement/dataloader/Dataloader.java similarity index 87% rename from src/main/java/fr/insee/survey/datacollectionmanagement/util/Dataloader.java rename to src/main/java/fr/insee/survey/datacollectionmanagement/dataloader/Dataloader.java index bd7b4461..74440182 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/util/Dataloader.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/dataloader/Dataloader.java @@ -1,4 +1,4 @@ -package fr.insee.survey.datacollectionmanagement.util; +package fr.insee.survey.datacollectionmanagement.dataloader; import com.github.javafaker.Faker; import com.github.javafaker.Name; @@ -77,7 +77,7 @@ public void init() { Faker faker = new Faker(); EasyRandom generator = new EasyRandom(); - initOrder(); + initOrder(); // initContact(faker); // initMetadata(faker, generator); // initQuestionning(faker, generator); @@ -180,7 +180,7 @@ private void initOrder() { Long nbExistingOrders = orderRepository.count(); log.info("{} orders in database", nbExistingOrders); - if (nbExistingOrders !=8 ) { + if (nbExistingOrders != 8) { // Creating table order log.info("loading eventorder data"); orderRepository.deleteAll(); @@ -317,8 +317,8 @@ private void initMetadata(Faker faker, EasyRandom generator2) { while (sourceRepository.count() < 10) { Source source = new Source(); - - String nameSource = "LOAD"+String.valueOf((char)(sourceRepository.count() + 'A')); + + String nameSource = "LOAD" + String.valueOf((char) (sourceRepository.count() + 'A')); if (!StringUtils.contains(nameSource, " ") && sourceRepository.findById(nameSource).isEmpty()) { @@ -361,7 +361,7 @@ private void initMetadata(Faker faker, EasyRandom generator2) { for (int k = 0; k < 12; k++) { Campaign campaign = new Campaign(); int month = k + 1; - String period = month<10? "M0" + month:"M"+month; + String period = month < 10 ? "M0" + month : "M" + month; campaign.setYear(year - j); campaign.setPeriod(PeriodEnum.valueOf(period)); campaign.setId(nameSource + (year - j) + period); @@ -400,13 +400,13 @@ private void initMetadata(Faker faker, EasyRandom generator2) { sourceRepository.save(source); ownerInsee.setSources(setSourcesInsee); ownerAgri.setSources(setSourcesSsp); - ownerRepository.saveAll(Arrays.asList(new Owner[] { + ownerRepository.saveAll(Arrays.asList(new Owner[]{ ownerInsee, ownerAgri })); supportInseeHdf.setSources(setSourcesSupportInsee); supportSsne.setSources(setSourcesSupportSsne); - supportRepository.saveAll(Arrays.asList(new Support[] { + supportRepository.saveAll(Arrays.asList(new Support[]{ supportInseeHdf, supportSsne })); } @@ -549,62 +549,63 @@ private void initQuestioningEvents(Faker faker, EasyRandom generator) { // questioning events // everybody in INITLA Optional part = partitioningRepository.findById(qu.getIdPartitioning()); - Date eventDate = faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()); - qe.setType(TypeQuestioningEvent.INITLA); - qe.setDate(eventDate); - qe.setQuestioning(qu); - qeList.add(qe); - - int qeProfile = qeRan.nextInt(10); - - switch (qeProfile) { - case 0: - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.REFUSAL, qu)); - break; - case 1: - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.PND, qu)); - break; - case 2: - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.FOLLOWUP, qu)); - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.FOLLOWUP, qu)); - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.PARTIELINT, qu)); - break; - case 3: - case 4: - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.FOLLOWUP, qu)); - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.FOLLOWUP, qu)); - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.VALINT, qu)); - break; - case 5: - case 6: - case 7: - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.PARTIELINT, qu)); - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.VALINT, qu)); - break; - } - - qeList.stream().forEach(questEvent -> questioningEventRepository.save(questEvent)); + if (part.isPresent()) { + Date eventDate = faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()); + qe.setType(TypeQuestioningEvent.INITLA); + qe.setDate(eventDate); + qe.setQuestioning(qu); + qeList.add(qe); + + int qeProfile = qeRan.nextInt(10); + + switch (qeProfile) { + case 0: + qeList.add(new QuestioningEvent( + faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), + TypeQuestioningEvent.REFUSAL, qu)); + break; + case 1: + qeList.add(new QuestioningEvent( + faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), + TypeQuestioningEvent.PND, qu)); + break; + case 2: + qeList.add(new QuestioningEvent( + faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), + TypeQuestioningEvent.FOLLOWUP, qu)); + qeList.add(new QuestioningEvent( + faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), + TypeQuestioningEvent.FOLLOWUP, qu)); + qeList.add(new QuestioningEvent( + faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), + TypeQuestioningEvent.PARTIELINT, qu)); + break; + case 3: + case 4: + qeList.add(new QuestioningEvent( + faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), + TypeQuestioningEvent.FOLLOWUP, qu)); + qeList.add(new QuestioningEvent( + faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), + TypeQuestioningEvent.FOLLOWUP, qu)); + qeList.add(new QuestioningEvent( + faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), + TypeQuestioningEvent.VALINT, qu)); + break; + case 5: + case 6: + case 7: + qeList.add(new QuestioningEvent( + faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), + TypeQuestioningEvent.PARTIELINT, qu)); + qeList.add(new QuestioningEvent( + faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), + TypeQuestioningEvent.VALINT, qu)); + break; + } + qeList.stream().forEach(questEvent -> questioningEventRepository.save(questEvent)); + } } } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/util/DataloaderPoc.java b/src/main/java/fr/insee/survey/datacollectionmanagement/dataloader/DataloaderPoc.java similarity index 99% rename from src/main/java/fr/insee/survey/datacollectionmanagement/util/DataloaderPoc.java rename to src/main/java/fr/insee/survey/datacollectionmanagement/dataloader/DataloaderPoc.java index 7a469b12..30b36ee5 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/util/DataloaderPoc.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/dataloader/DataloaderPoc.java @@ -1,4 +1,4 @@ -package fr.insee.survey.datacollectionmanagement.util; +package fr.insee.survey.datacollectionmanagement.dataloader; import com.github.javafaker.Faker; import com.github.javafaker.Name; diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/WebclientController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/WebclientController.java index 2d5ebf45..84c84f51 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/WebclientController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/WebclientController.java @@ -158,7 +158,7 @@ public ResponseEntity putQuestioning(@RequestBody QuestioningWebclientDto que // save questioning and su questioningService.saveQuestioning(questioning); su.getQuestionings().add(questioning); - su = surveyUnitService.saveSurveyUnitAndAddress(su); + surveyUnitService.saveSurveyUnitAndAddress(su); questioningReturn.setIdPartitioning(idPartitioning); @@ -400,8 +400,12 @@ public ResponseEntity getMainContact( List listQa = questioning.getQuestioningAccreditations().stream() .filter(qa -> qa.isMain()).toList(); if (listQa != null && !listQa.isEmpty()) { - Contact c = contactService.findByIdentifier(listQa.get(0).getIdContact()).get(); - return ResponseEntity.status(HttpStatus.OK).body(convertToDto((c))); + Optional c = contactService.findByIdentifier(listQa.get(0).getIdContact()); + if(c.isPresent()) + return ResponseEntity.status(HttpStatus.OK).body(convertToDto((c.get()))); + else + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("No contact found"); + } } return ResponseEntity.status(HttpStatus.NOT_FOUND).body("No contact found"); diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/UploadServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/UploadServiceImpl.java index fcfabcb6..f034f877 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/UploadServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/UploadServiceImpl.java @@ -67,7 +67,7 @@ public ResultUpload save(String idCampaign, UploadDto uploadDto) throws Ressourc if (setParts.isEmpty()) { throw new RessourceNotValidatedException("No partitionings found for campaign ", idCampaign); } - + Set questionings = questioningService.findBySurveyUnitIdSu(mmDto.getIdSu()); List listIdParts = campaignService.findById(idCampaign).get().getPartitionings().stream().map(Partitioning::getId).toList(); @@ -83,7 +83,7 @@ public ResultUpload save(String idCampaign, UploadDto uploadDto) throws Ressourc qe.setPayload(objectMapper.readTree(jo.toString())); qe.setDate(today); liste.add(questioningEventService.saveQuestioningEvent(qe)); - if(quest.isPresent()){ + if (quest.isPresent()) { quest.get().getQuestioningEvents().add(qe); questioningService.saveQuestioning(quest.get()); } @@ -99,7 +99,7 @@ public ResultUpload save(String idCampaign, UploadDto uploadDto) throws Ressourc return result; } up.setQuestioningEvents(liste); - up = saveAndFlush(up); + saveAndFlush(up); return result; } @@ -113,14 +113,17 @@ public Optional findById(long id) { public List findAllByIdCampaign(String idCampaign) { Optional campaign = campaignService.findById(idCampaign); + if (campaign.isPresent()) { - List partitioningIds = campaign.get().getPartitionings().stream().map(Partitioning::getId).toList(); + List partitioningIds = campaign.get().getPartitionings().stream().map(Partitioning::getId).toList(); - // Keeps the uploads which first managementMonitoringInfo belongs to the survey - return uploadRepository.findAll().stream().filter(upload -> !upload.getQuestioningEvents().isEmpty()) - .filter(upload -> partitioningIds.contains(upload.getQuestioningEvents().stream().findFirst().get().getQuestioning().getIdPartitioning() - )) - .toList(); + // Keeps the uploads which first managementMonitoringInfo belongs to the survey + return uploadRepository.findAll().stream().filter(upload -> !upload.getQuestioningEvents().isEmpty()) + .filter(upload -> partitioningIds.contains(upload.getQuestioningEvents().stream().findFirst().get().getQuestioning().getIdPartitioning() + )) + .toList(); + } + return Collections.emptyList(); } @@ -137,18 +140,27 @@ public Upload saveAndFlush(Upload up) { @Override public boolean checkUploadDate(String idCampaign, Date date) { Optional campaign = campaignService.findById(idCampaign); - Long timestamp = date.getTime(); - Long start = campaign.get().getPartitionings().stream().map(Partitioning::getOpeningDate) - .toList().stream() - .min(Comparator.comparing(Date::getTime)).get().getTime(); - Long end = campaign.get().getPartitionings().stream().map(Partitioning::getClosingDate) - .toList().stream() - .max(Comparator.comparing(Date::getTime)).get().getTime(); - return (start < timestamp && timestamp < end); + long timestamp = date.getTime(); + if (campaign.isPresent()) { + Optional openingDate = campaign.get().getPartitionings().stream().map(Partitioning::getOpeningDate) + .toList().stream() + .min(Comparator.comparing(Date::getTime)); + Optional closingDate = campaign.get().getPartitionings().stream().map(Partitioning::getClosingDate) + .toList().stream() + .max(Comparator.comparing(Date::getTime)); + if(openingDate.isPresent() && closingDate.isPresent()){ + long start = openingDate.get().getTime(); + long end = closingDate.get().getTime(); + return (start < timestamp && timestamp < end); + + } + + } + return false; } @Override public void removeEmptyUploads() { - uploadRepository.findByQuestioningEventsIsEmpty().forEach(u -> uploadRepository.delete(u)); + uploadRepository.findByQuestioningEventsIsEmpty().forEach(uploadRepository::delete); } } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/user/controller/UserController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/user/controller/UserController.java index 45e7c142..2fff5d6d 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/user/controller/UserController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/user/controller/UserController.java @@ -5,9 +5,7 @@ import fr.insee.survey.datacollectionmanagement.metadata.service.SourceService; import fr.insee.survey.datacollectionmanagement.user.domain.SourceAccreditation; import fr.insee.survey.datacollectionmanagement.user.domain.User; -import fr.insee.survey.datacollectionmanagement.user.domain.UserEvent; import fr.insee.survey.datacollectionmanagement.user.dto.UserDto; -import fr.insee.survey.datacollectionmanagement.user.exception.RoleException; import fr.insee.survey.datacollectionmanagement.user.service.SourceAccreditationService; import fr.insee.survey.datacollectionmanagement.user.service.UserService; import io.swagger.v3.oas.annotations.Operation; @@ -32,9 +30,10 @@ import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import java.text.ParseException; -import java.util.*; -import java.util.stream.Collectors; -import java.util.stream.Stream; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Optional; +import java.util.Set; @RestController @PreAuthorize("@AuthorizeMethodDecider.isInternalUser() " @@ -59,7 +58,7 @@ public class UserController { @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = UserController.UserPage.class))) }) - public ResponseEntity getUsers( + public ResponseEntity getUsers( @RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "20") Integer size, @RequestParam(defaultValue = "identifier") String sort) { @@ -76,7 +75,7 @@ public ResponseEntity getUsers( @ApiResponse(responseCode = "404", description = "Not found"), @ApiResponse(responseCode = "400", description = "Bad Request") }) - public ResponseEntity getUser(@PathVariable("id") String id) { + public ResponseEntity getUser(@PathVariable("id") String id) { Optional user = userService.findByIdentifier(id); try { if (user.isPresent()) @@ -96,7 +95,7 @@ public ResponseEntity getUser(@PathVariable("id") String id) { @ApiResponse(responseCode = "201", description = "Created", content = @Content(schema = @Schema(implementation = UserDto.class))), @ApiResponse(responseCode = "400", description = "Bad request") }) - public ResponseEntity putUser(@PathVariable("id") String id, @Valid @RequestBody UserDto userDto) { + public ResponseEntity putUser(@PathVariable("id") String id, @Valid @RequestBody UserDto userDto) { if (StringUtils.isBlank(userDto.getIdentifier()) || !userDto.getIdentifier().equalsIgnoreCase(id)) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("id and user identifier don't match"); } @@ -110,21 +109,16 @@ public ResponseEntity putUser(@PathVariable("id") String id, @Valid @RequestB } catch (ParseException e) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Impossible to parse user"); - } catch (RoleException e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST) - .body("Role not recognized: only [" + Stream.of(User.UserRoleType.values()) - .map(User.UserRoleType::name).collect(Collectors.joining(", ")) + "] are possible"); - } catch (NoSuchElementException e) { log.info("Creating user with the identifier {}", userDto.getIdentifier()); - user = convertToEntityNewContact(userDto); + user = convertToEntityNewUser(userDto); - User userCreate = userService.createUserEvent(user, null); + User userCreate = userService.createUser(user, null); return ResponseEntity.status(HttpStatus.CREATED).headers(responseHeaders).body(convertToDto(userCreate)); } log.info("Updating user with the identifier {}", userDto.getIdentifier()); - User userUpdate = userService.updateUserEvent(user, null); + User userUpdate = userService.updateUser(user, null); return ResponseEntity.ok().headers(responseHeaders).body(convertToDto(userUpdate)); } @@ -137,11 +131,11 @@ public ResponseEntity putUser(@PathVariable("id") String id, @Valid @RequestB @ApiResponse(responseCode = "400", description = "Bad Request") }) @Transactional - public ResponseEntity deleteUser(@PathVariable("id") String id) { + public ResponseEntity deleteUser(@PathVariable("id") String id) { try { Optional user = userService.findByIdentifier(id); if (user.isPresent()) { - userService.deleteContactAddressEvent(user.get()); + userService.deleteUserAndEvents(user.get()); sourceAccreditationService.findByUserIdentifier(id).stream().forEach(acc -> { Source source = sourceService.findById(acc.getSource().getId()).get(); @@ -169,7 +163,7 @@ public ResponseEntity deleteUser(@PathVariable("id") String id) { @ApiResponse(responseCode = "404", description = "Not found"), @ApiResponse(responseCode = "400", description = "Bad Request") }) - public ResponseEntity getUserSources(@PathVariable("id") String id) { + public ResponseEntity getUserSources(@PathVariable("id") String id) { Optional user = userService.findByIdentifier(id); if (user.isPresent()) { List accreditedSources = userService.findAccreditedSources(id); @@ -180,30 +174,27 @@ public ResponseEntity getUserSources(@PathVariable("id") String id) { } - private User convertToEntity(UserDto userDto) throws ParseException, NoSuchElementException, RoleException { - User user = modelMapper.map(userDto, User.class); - - if (user.getRole() == null || Arrays.stream(UserEvent.UserEventType.values()).anyMatch(v -> userDto.getRole().equals(v))) { - throw new RoleException("Role missing or not recognized. Only [" + Stream.of(User.UserRoleType.values()).map(User.UserRoleType::name).collect(Collectors.joining(", ")) + "] are possible"); - } + private User convertToEntity(UserDto userDto) throws ParseException, NoSuchElementException { Optional oldUser = userService.findByIdentifier(userDto.getIdentifier()); if (!oldUser.isPresent()) { throw new NoSuchElementException(); } + User user = modelMapper.map(userDto, User.class); + user.setRole(User.UserRoleType.valueOf(userDto.getRole().toUpperCase())); user.setUserEvents(oldUser.get().getUserEvents()); return user; } - private User convertToEntityNewContact(UserDto userDto) { + private User convertToEntityNewUser(UserDto userDto) { User user = modelMapper.map(userDto, User.class); + user.setRole(User.UserRoleType.valueOf(userDto.getRole().toUpperCase())); return user; } private UserDto convertToDto(User user) { - UserDto userDto = modelMapper.map(user, UserDto.class); - return userDto; + return modelMapper.map(user, UserDto.class); } class UserPage extends PageImpl { diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/user/controller/UserEventController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/user/controller/UserEventController.java index f1bdcceb..03dab014 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/user/controller/UserEventController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/user/controller/UserEventController.java @@ -15,6 +15,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.modelmapper.ModelMapper; @@ -22,6 +23,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; @@ -37,6 +39,7 @@ @Slf4j @Tag(name = "7-User", description = "Enpoints to create, update, delete and find users, their events and accreditations") @RequiredArgsConstructor +@Validated public class UserEventController { private final ModelMapper modelMapper; @@ -76,7 +79,7 @@ public ResponseEntity getUserUserEvents(@PathVariable("id") String identifier @ApiResponse(responseCode = "400", description = "Bad request"), @ApiResponse(responseCode = "404", description = "Not found") }) - public ResponseEntity postUserEvent(@RequestBody UserEventDto userEventDto) { + public ResponseEntity postUserEvent(@Valid @RequestBody UserEventDto userEventDto) { try { Optional optUser = userService.findByIdentifier(userEventDto.getIdentifier()); @@ -137,8 +140,6 @@ private UserEventDto convertToDto(UserEvent userEvent) { private UserEvent convertToEntity(UserEventDto userEventDto) throws EventException { UserEvent userEvent = modelMapper.map(userEventDto, UserEvent.class); - if (userEvent.getType() == null) - throw new EventException("User event not recognized"); return userEvent; } } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/user/dto/UserEventDto.java b/src/main/java/fr/insee/survey/datacollectionmanagement/user/dto/UserEventDto.java index cf991a54..f266060d 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/user/dto/UserEventDto.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/user/dto/UserEventDto.java @@ -1,6 +1,7 @@ package fr.insee.survey.datacollectionmanagement.user.dto; import com.fasterxml.jackson.databind.JsonNode; +import fr.insee.survey.datacollectionmanagement.user.validation.UserEventTypeValid; import jakarta.validation.constraints.NotBlank; import lombok.Getter; import lombok.Setter; @@ -15,7 +16,7 @@ public class UserEventDto { @NotBlank(message = "identifier can't be blank") private String identifier; private Date eventDate; - + @UserEventTypeValid private String type; private JsonNode payload; diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/UserService.java b/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/UserService.java index 34df6b61..604371ab 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/UserService.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/UserService.java @@ -43,11 +43,11 @@ public interface UserService { */ public void deleteUser(String identifier); - public User createUserEvent(User user, JsonNode payload); + public User createUser(User user, JsonNode payload); - public User updateUserEvent(User user, JsonNode payload); + public User updateUser(User user, JsonNode payload); - public void deleteContactAddressEvent(User user); + public void deleteUserAndEvents(User user); List findAccreditedSources(String identifier); } \ No newline at end of file diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/impl/UserServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/impl/UserServiceImpl.java index c4613fc0..02ced26a 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/impl/UserServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/impl/UserServiceImpl.java @@ -48,7 +48,7 @@ public void deleteUser(String identifier) { @Override - public User createUserEvent(User user, JsonNode payload) { + public User createUser(User user, JsonNode payload) { UserEvent newUserEvent = userEventService.createUserEvent(user, UserEvent.UserEventType.CREATE, payload); @@ -57,7 +57,7 @@ public User createUserEvent(User user, JsonNode payload) { } @Override - public User updateUserEvent(User user, JsonNode payload) { + public User updateUser(User user, JsonNode payload) { User existingUser = findByIdentifier(user.getIdentifier()).get(); @@ -70,7 +70,7 @@ public User updateUserEvent(User user, JsonNode payload) { } @Override - public void deleteContactAddressEvent(User user) { + public void deleteUserAndEvents(User user) { deleteUser(user.getIdentifier()); } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/user/validation/UserEventTypeValidator.java b/src/main/java/fr/insee/survey/datacollectionmanagement/user/validation/UserEventTypeValidator.java index 2d65f372..dac2ba8f 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/user/validation/UserEventTypeValidator.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/user/validation/UserEventTypeValidator.java @@ -18,6 +18,6 @@ public void initialize(UserEventTypeValid constraintAnnotation) { public boolean isValid(String value, ConstraintValidatorContext context) { if (value == null) return false; - return Arrays.stream(UserEvent.UserEventType.values()).anyMatch(v -> value.equals(v)); + return Arrays.stream(UserEvent.UserEventType.values()).anyMatch(v -> value.equalsIgnoreCase(v.name())); } } \ No newline at end of file diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/user/validation/UserRoleValidator.java b/src/main/java/fr/insee/survey/datacollectionmanagement/user/validation/UserRoleValidator.java index 545b193d..a57b620d 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/user/validation/UserRoleValidator.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/user/validation/UserRoleValidator.java @@ -18,6 +18,6 @@ public void initialize(UserRoleValid constraintAnnotation) { public boolean isValid(String value, ConstraintValidatorContext context) { if(value == null) return false; - return Arrays.stream(User.UserRoleType.values()).anyMatch(v -> value.equals(v)); + return Arrays.stream(User.UserRoleType.values()).anyMatch(v -> value.equalsIgnoreCase(v.name())); } } diff --git a/src/test/java/fr/insee/survey/datacollectionmanagement/config/DataloaderTest.java b/src/test/java/fr/insee/survey/datacollectionmanagement/dataloader/DataloaderTest.java similarity index 97% rename from src/test/java/fr/insee/survey/datacollectionmanagement/config/DataloaderTest.java rename to src/test/java/fr/insee/survey/datacollectionmanagement/dataloader/DataloaderTest.java index 5f893961..65cd570f 100644 --- a/src/test/java/fr/insee/survey/datacollectionmanagement/config/DataloaderTest.java +++ b/src/test/java/fr/insee/survey/datacollectionmanagement/dataloader/DataloaderTest.java @@ -1,4 +1,4 @@ -package fr.insee.survey.datacollectionmanagement.config; +package fr.insee.survey.datacollectionmanagement.dataloader; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; @@ -18,6 +18,8 @@ import fr.insee.survey.datacollectionmanagement.questioning.domain.*; import fr.insee.survey.datacollectionmanagement.questioning.repository.*; import fr.insee.survey.datacollectionmanagement.questioning.util.TypeQuestioningEvent; +import fr.insee.survey.datacollectionmanagement.user.domain.User; +import fr.insee.survey.datacollectionmanagement.user.service.UserService; import fr.insee.survey.datacollectionmanagement.view.domain.View; import fr.insee.survey.datacollectionmanagement.view.repository.ViewRepository; import jakarta.annotation.PostConstruct; @@ -84,6 +86,9 @@ public class DataloaderTest { @Autowired private ViewRepository viewRepository; + @Autowired + private UserService userService; + @PostConstruct public void init() throws ParseException { @@ -94,7 +99,15 @@ public void init() throws ParseException { initMetadata(); initQuestionning(faker); initView(); + initUser(); + + } + private void initUser() { + User user = new User(); + user.setIdentifier("USER1"); + user.setRole(User.UserRoleType.ASSISTANCE); + userService.createUser(user,null); } private void initOrder() { diff --git a/src/test/java/fr/insee/survey/datacollectionmanagement/user/controller/controller/UserControllerTest.java b/src/test/java/fr/insee/survey/datacollectionmanagement/user/controller/controller/UserControllerTest.java new file mode 100644 index 00000000..e0bfedf1 --- /dev/null +++ b/src/test/java/fr/insee/survey/datacollectionmanagement/user/controller/controller/UserControllerTest.java @@ -0,0 +1,144 @@ +package fr.insee.survey.datacollectionmanagement.user.controller.controller; + +import fr.insee.survey.datacollectionmanagement.constants.Constants; +import fr.insee.survey.datacollectionmanagement.user.domain.User; +import fr.insee.survey.datacollectionmanagement.user.domain.UserEvent; +import fr.insee.survey.datacollectionmanagement.user.domain.UserEvent.UserEventType; +import fr.insee.survey.datacollectionmanagement.user.repository.UserRepository; +import fr.insee.survey.datacollectionmanagement.user.service.UserEventService; +import fr.insee.survey.datacollectionmanagement.user.service.UserService; +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.servlet.MockMvc; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@AutoConfigureMockMvc +@SpringBootTest +@ActiveProfiles("test") +public class UserControllerTest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private UserService userService; + + @Autowired + private UserEventService userEventService; + + @Autowired + private UserRepository userRepository; + + @Test + public void getUserNotFound() throws Exception { + String identifier = "CONT500"; + this.mockMvc.perform(get(Constants.API_USERS_ID, identifier)).andDo(print()) + .andExpect(status().is(HttpStatus.NOT_FOUND.value())); + + } + + @Test + public void getUserOk() throws Exception { + String identifier = "CONT1"; + this.mockMvc.perform(get(Constants.API_USERS_ID, identifier)).andDo(print()) + .andExpect(status().is(HttpStatus.OK.value())); + + } + + @Test + public void getUsersOk() throws Exception { + JSONObject jo = new JSONObject(); + jo.put("totalElements", userRepository.count()); + jo.put("numberOfElements", userRepository.count()); + + this.mockMvc.perform(get(Constants.API_USERS_ALL)).andDo(print()).andExpect(status().isOk()) + .andExpect(content().json(jo.toString(), false)); + } + + @Test + public void putUserCreateUpdateDelete() throws Exception { + String identifier = "TESTPUT"; + + // create user - status created + User user = initGestionnaire(identifier); + String jsonUser = createJson(user); + mockMvc.perform( + put(Constants.API_USERS_ID, identifier).content(jsonUser).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isCreated()) + .andExpect(content().json(jsonUser.toString(), false)); + User userFound = userService.findByIdentifier(identifier).get(); + assertEquals(user.getIdentifier(), userFound.getIdentifier()); + assertEquals(user.getRole(), userFound.getRole()); + + // update user - status ok + user.setRole(User.UserRoleType.ASSISTANCE); + String jsonUserUpdate = createJson(user); + mockMvc.perform(put(Constants.API_USERS_ID, identifier).content(jsonUserUpdate) + .contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) + .andExpect(content().json(jsonUserUpdate.toString(), false)); + User userFoundAfterUpdate = userService.findByIdentifier(identifier).get(); + assertEquals(User.UserRoleType.ASSISTANCE, userFoundAfterUpdate.getRole()); + List listUpdate = new ArrayList<>( + userEventService.findUserEventsByUser(userFoundAfterUpdate)); + assertEquals(listUpdate.size(), 2); + assertEquals(listUpdate.get(1).getType(), UserEventType.UPDATE); + + // delete user + mockMvc.perform(delete(Constants.API_USERS_ID, identifier).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isNoContent()); + assertFalse(userService.findByIdentifier(identifier).isPresent()); + assertTrue(userEventService.findUserEventsByUser(userFoundAfterUpdate).isEmpty()); + + // delete user not found + mockMvc.perform(delete("/users/" + identifier).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isNotFound()); + + } + + @Test + public void putUsersErrorId() throws Exception { + String identifier = "NEWONE"; + String otherIdentifier = "WRONG"; + User user = initGestionnaire(identifier); + String jsonUser = createJson(user); + mockMvc.perform(put(Constants.API_USERS_ID, otherIdentifier).content(jsonUser) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isBadRequest()) + .andExpect(content().string("id and user identifier don't match")); + + } + + private User initGestionnaire(String identifier) { + return initUser(identifier, User.UserRoleType.GESTIONNAIRE); + } + + private User initUser(String identifier, User.UserRoleType role) { + User userMock = new User(); + userMock.setIdentifier(identifier); + userMock.setRole(role); + return userMock; + } + + + private String createJson(User user) throws JSONException { + JSONObject jo = new JSONObject(); + jo.put("identifier", user.getIdentifier()); + jo.put("role", user.getRole().name()); + return jo.toString(); + } +} diff --git a/src/test/java/fr/insee/survey/datacollectionmanagement/user/controller/controller/UserEventControllerTest.java b/src/test/java/fr/insee/survey/datacollectionmanagement/user/controller/controller/UserEventControllerTest.java new file mode 100644 index 00000000..9c7d6705 --- /dev/null +++ b/src/test/java/fr/insee/survey/datacollectionmanagement/user/controller/controller/UserEventControllerTest.java @@ -0,0 +1,57 @@ +package fr.insee.survey.datacollectionmanagement.user.controller.controller; + +import fr.insee.survey.datacollectionmanagement.constants.Constants; +import fr.insee.survey.datacollectionmanagement.user.domain.UserEvent; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpStatus; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.servlet.MockMvc; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@AutoConfigureMockMvc +@SpringBootTest +@ActiveProfiles("test") +public class UserEventControllerTest { + + @Autowired + private MockMvc mockMvc; + + @Test + public void getUserEventOk() throws Exception { + String identifier = "USER1"; + + String json = createJsonUserEvent(identifier, null); + this.mockMvc.perform(get(Constants.API_USERS_ID_USEREVENTS,identifier)).andDo(print()).andExpect(status().isOk()) + .andExpect(content().json(json, false)); + } + + @Test + public void getUserEventNotFound() throws Exception { + String identifier = "CONT500"; + this.mockMvc.perform(get(Constants.API_USERS_ID_USEREVENTS,identifier)).andDo(print()) + .andExpect(status().is(HttpStatus.NOT_FOUND.value())); + + } + + private String createJsonUserEvent(String identifier, JSONObject payload ) throws JSONException { + JSONObject jo = new JSONObject(); + JSONObject joPayload = new JSONObject(); + joPayload.put("identifier", identifier); + joPayload.put("type", UserEvent.UserEventType.CREATE.name()); + jo.put("payload", payload); + JSONArray ja = new JSONArray(); + ja.put(jo); + return ja.toString(); + } + +}