diff --git a/.vscode/settings.json b/.vscode/settings.json index dc3b895..d3ec7ba 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,4 @@ { - "java.configuration.updateBuildConfiguration": "interactive" + "java.configuration.updateBuildConfiguration": "interactive", + "java.compile.nullAnalysis.mode": "automatic" } \ No newline at end of file diff --git a/backend/.gitlab-ci.yml b/backend/.gitlab-ci.yml index 69f6c02..f11510d 100644 --- a/backend/.gitlab-ci.yml +++ b/backend/.gitlab-ci.yml @@ -1,47 +1,21 @@ -# You can override the included template(s) by including variable overrides -# SAST customization: https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings -# Secret Detection customization: https://docs.gitlab.com/ee/user/application_security/secret_detection/#customizing-settings -# Dependency Scanning customization: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/#customizing-the-dependency-scanning-settings -# Container Scanning customization: https://docs.gitlab.com/ee/user/application_security/container_scanning/#customizing-the-container-scanning-settings -# Note that environment variables can be set in several places -# See https://docs.gitlab.com/ee/ci/variables/#cicd-variable-precedence -stages: -- build -- test -- deploy +image: maven:3.8.5-openjdk-17 -# Inclure le template Auto-DevOps pour des configurations automatiques -include: - - template: Auto-DevOps.gitlab-ci.yml +stages: + - build + - test + - quality -# Configuration des jobs build: stage: build - image: maven:3.8.5-jdk-17 # Utilisez l'image Docker Maven avec Java 17 - script: - - mvn clean package # Commande Maven pour compiler et empaqueter l'application - artifacts: - paths: - - target/*.jar # Spécifie les artefacts à archiver (fichier JAR de l'application) + script: + - ./mvnw package test: stage: test - image: maven:3.8.5-jdk-17 - script: - - mvn test # Exécute les tests Maven - artifacts: - reports: - junit: target/surefire-reports/*.xml # Spécifie les rapports de tests à archiver - -deploy: - stage: deploy - image: openjdk:17-jdk # Utilisez l'image Docker OpenJDK 17 pour le déploiement - script: - - java -jar target/*.jar # Commande pour démarrer l'application Spring Boot - environment: - name: production # Nom de l'environnement de déploiement - only: - - main # Déployer uniquement à partir de la branche main + script: + - ./mvnw test -include: -- template: Auto-DevOps.gitlab-ci.yml +quality: + stage: quality + script: + - ./mvnw site \ No newline at end of file diff --git a/backend/pom.xml b/backend/pom.xml index 4d24672..b68ba22 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.3.0 + 3.3.1 com.epsyl @@ -18,6 +18,12 @@ 17 + + + org.springframework.boot + spring-boot-starter-actuator + + org.springframework.boot @@ -44,11 +50,28 @@ spring-boot-starter-tomcat provided + + + org.springframework.boot + spring-boot-starter-mail + org.springframework.boot spring-boot-starter-test test + + + junit + junit + + + + + org.mockito + mockito-core + 3.12.4 + test @@ -68,6 +91,11 @@ com.fasterxml.jackson.core jackson-databind + + de.undercouch + bson4jackson + 2.15.1 + io.jsonwebtoken @@ -86,8 +114,8 @@ - org.springframework.security - spring-security-crypto + org.springframework.security + spring-security-crypto diff --git a/backend/src/main/java/com/epsyl/eps/config/JacksonConfig.java b/backend/src/main/java/com/epsyl/eps/config/JacksonConfig.java new file mode 100644 index 0000000..36d4a16 --- /dev/null +++ b/backend/src/main/java/com/epsyl/eps/config/JacksonConfig.java @@ -0,0 +1,27 @@ +package com.epsyl.eps.config; + +import org.bson.types.ObjectId; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; + +import com.epsyl.eps.serialization.ObjectIdDeserrializer; +import com.epsyl.eps.serialization.ObjectIdSerializer; +import com.fasterxml.jackson.databind.module.SimpleModule; + +@Configuration +public class JacksonConfig { + + @Bean + public Jackson2ObjectMapperBuilder jacksonBuilder() { + Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); + SimpleModule module = new SimpleModule(); + + module.addSerializer(ObjectId.class, new ObjectIdSerializer()); + module.addDeserializer(ObjectId.class, new ObjectIdDeserrializer()); + + builder.modules(module); + + return builder; + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/epsyl/eps/config/ObjectMapperConfig.java b/backend/src/main/java/com/epsyl/eps/config/ObjectMapperConfig.java new file mode 100644 index 0000000..f81d37f --- /dev/null +++ b/backend/src/main/java/com/epsyl/eps/config/ObjectMapperConfig.java @@ -0,0 +1,24 @@ +package com.epsyl.eps.config; + +import org.bson.types.ObjectId; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.epsyl.eps.serialization.ObjectIdDeserrializer; +import com.epsyl.eps.serialization.ObjectIdSerializer; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; + +@Configuration +public class ObjectMapperConfig { + @Bean + public ObjectMapper objectMapper() { + ObjectMapper mapper = new ObjectMapper(); + SimpleModule module = new SimpleModule(); + + module.addSerializer(ObjectId.class, new ObjectIdSerializer()); + module.addDeserializer(ObjectId.class, new ObjectIdDeserrializer()); + mapper.registerModule(module); + return mapper; + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/epsyl/eps/configuration_global/WebConfig.java b/backend/src/main/java/com/epsyl/eps/config/WebConfig.java similarity index 94% rename from backend/src/main/java/com/epsyl/eps/configuration_global/WebConfig.java rename to backend/src/main/java/com/epsyl/eps/config/WebConfig.java index debfb36..2cb2baa 100644 --- a/backend/src/main/java/com/epsyl/eps/configuration_global/WebConfig.java +++ b/backend/src/main/java/com/epsyl/eps/config/WebConfig.java @@ -1,4 +1,4 @@ -package com.epsyl.eps.configuration_global; +package com.epsyl.eps.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/backend/src/main/java/com/epsyl/eps/configuration_global/ObjectIdDeserrializer.java b/backend/src/main/java/com/epsyl/eps/configuration_global/ObjectIdDeserrializer.java deleted file mode 100644 index 13fd721..0000000 --- a/backend/src/main/java/com/epsyl/eps/configuration_global/ObjectIdDeserrializer.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.epsyl.eps.configuration_global; - -import java.io.IOException; - -import org.bson.types.ObjectId; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; - -public class ObjectIdDeserrializer extends JsonDeserializer { - - @Override - public ObjectId deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException { - return new ObjectId(jsonParser.getText()); - } -} \ No newline at end of file diff --git a/backend/src/main/java/com/epsyl/eps/controllers/ArchiveProspectController.java b/backend/src/main/java/com/epsyl/eps/controllers/ArchiveProspectController.java new file mode 100644 index 0000000..14f82df --- /dev/null +++ b/backend/src/main/java/com/epsyl/eps/controllers/ArchiveProspectController.java @@ -0,0 +1,54 @@ +package com.epsyl.eps.controllers; + +import org.springframework.web.bind.annotation.RestController; + +import com.epsyl.eps.entities.ArchiveProspect; +import com.epsyl.eps.services.ArchiveProspectService; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; + +@RestController +@RequestMapping("/api/v1/archive") +public class ArchiveProspectController { + + @Autowired + private ArchiveProspectService archiveProspectService; + + // GET api/v1/archive/all + @GetMapping("/all") + public Iterable getAllArchive() { + return archiveProspectService.listAll(); + } + + // GET api/v1/archive/id + @GetMapping("/{id}") + public ArchiveProspect getArchive(@PathVariable String id) { + return archiveProspectService.getArchiveProspectByID(id).get(); + } + + // POST api/v1/archive/save + @RequestMapping("/save") + public ArchiveProspect saveArchive(@RequestBody ArchiveProspect archive) { + return archiveProspectService.save(archive); + } + + // PUT api/v1/archive/id + // @PutMapping("/{id}") + // public ArchiveProspect updateArchive(@RequestBody ArchiveProspect archive, @PathVariable String id) { + // archive.set_id(id); + // archiveProspectService.save(archive); + // return archive; + // } + + // DELETE api/v1/archive/delete/id + @RequestMapping("/delete/{id}") + public ResponseEntity deleteArchive(@PathVariable String _id) { + archiveProspectService.deleteArchive(_id); + return ResponseEntity.noContent().build(); + } +} diff --git a/backend/src/main/java/com/epsyl/eps/controllers/FileStorageController.java b/backend/src/main/java/com/epsyl/eps/controllers/FileStorageController.java index e2f3a7c..167fede 100644 --- a/backend/src/main/java/com/epsyl/eps/controllers/FileStorageController.java +++ b/backend/src/main/java/com/epsyl/eps/controllers/FileStorageController.java @@ -19,6 +19,7 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; +import org.bson.types.ObjectId; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -51,7 +52,7 @@ public ResponseEntity> uploadFile(@RequestParam("file") Mult } @GetMapping("/download/{id}") - public ResponseEntity downloadFile(@PathVariable String _id) { + public ResponseEntity downloadFile(@PathVariable ObjectId _id) { FileStorage fileStorage = fileStorageService.getFile(_id); if(fileStorage != null) { HttpHeaders headers = new HttpHeaders(); diff --git a/backend/src/main/java/com/epsyl/eps/controllers/ProspectsController.java b/backend/src/main/java/com/epsyl/eps/controllers/ProspectsController.java index 478d113..63a4b7c 100644 --- a/backend/src/main/java/com/epsyl/eps/controllers/ProspectsController.java +++ b/backend/src/main/java/com/epsyl/eps/controllers/ProspectsController.java @@ -4,6 +4,7 @@ import java.util.List; import java.util.Optional; +import org.bson.types.ObjectId; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -69,7 +70,7 @@ public List getAllProspects() { // GET /api/v1/prospect/id @RequestMapping("/{id}") - public ResponseEntity getProspectById(@PathVariable String _id) { + public ResponseEntity getProspectById(@PathVariable ObjectId _id) { Optional prospect = prospectService.getProspectByID(_id); if (prospect.isPresent()) { return ResponseEntity.ok(prospect.get()); @@ -87,20 +88,20 @@ public boolean checkTrigram(@RequestParam String trigramme) { // POST /api/v1/prospect/save @PostMapping("/save") public Prospect saveProspect(@RequestBody Prospect prospect) { - return prospectService.save(prospect); + return prospectService.createProspect(prospect); } // PUT /api/v1/prospect/id @PutMapping("/{id}") - public Prospect updateProspect(@PathVariable String _id, @RequestBody Prospect prospect) { - return prospectService.updateProspect(_id, prospect); + public ResponseEntity updateProspect(@PathVariable ObjectId id, @RequestBody Prospect prospect) { + Prospect updatedProspect = prospectService.updateProspect(id, prospect); + return ResponseEntity.ok(updatedProspect); } // DELETE /api/v1/prospect/delete/id @DeleteMapping("/delete/{id}") - public ResponseEntity deleteProspect(@PathVariable String _id) { - prospectService.deleteProspectById(_id); + public ResponseEntity deleteProspect(@PathVariable ObjectId id) { + prospectService.deleteProspectById(id); return ResponseEntity.noContent().build(); } - } diff --git a/backend/src/main/java/com/epsyl/eps/controllers/RolesController.java b/backend/src/main/java/com/epsyl/eps/controllers/RolesController.java new file mode 100644 index 0000000..e7a507a --- /dev/null +++ b/backend/src/main/java/com/epsyl/eps/controllers/RolesController.java @@ -0,0 +1,28 @@ +package com.epsyl.eps.controllers; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.epsyl.eps.entities.Role; +import com.epsyl.eps.services.RoleService; + +import lombok.RequiredArgsConstructor; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; + + +@RestController +@RequestMapping("/api/v1/roles") +@RequiredArgsConstructor +public class RolesController { + + @Autowired + private RoleService roleService; + + @GetMapping("/all") + public Iterable getRoles() { + return roleService.getAllRoles(); + } + +} diff --git a/backend/src/main/java/com/epsyl/eps/controllers/UsersController.java b/backend/src/main/java/com/epsyl/eps/controllers/UsersController.java index a55d02f..52eab2b 100644 --- a/backend/src/main/java/com/epsyl/eps/controllers/UsersController.java +++ b/backend/src/main/java/com/epsyl/eps/controllers/UsersController.java @@ -2,6 +2,7 @@ import java.util.Optional; +import org.bson.types.ObjectId; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -36,7 +37,7 @@ public ResponseEntity login(@RequestBody LoginRequestDto user) // GET api/v1/user/id @RequestMapping("/{id}") - public ResponseEntity getUser(@PathVariable String id) { + public ResponseEntity getUser(@PathVariable ObjectId id) { Optional user = userService.getUserByID(id); if (user.isPresent()) { return ResponseEntity.ok(user.get()); @@ -60,7 +61,7 @@ public User saveUser(@RequestBody User user) { // PUT api/v1/user/id @PutMapping("/{id}") - public User updateUser(@RequestBody User user, @PathVariable String id) { + public User updateUser(@RequestBody User user, @PathVariable ObjectId id) { user.set_id(id); userService.saveUser(user); return user; @@ -68,7 +69,7 @@ public User updateUser(@RequestBody User user, @PathVariable String id) { // DELETE api/v1/user/delete/id @DeleteMapping("/delete/{id}") - public ResponseEntity deleteUser(@PathVariable String userId) { + public ResponseEntity deleteUser(@PathVariable ObjectId userId) { userService.deleteUser(userId); return ResponseEntity.noContent().build(); } diff --git a/backend/src/main/java/com/epsyl/eps/dtos/ArchiveProspectDTO.java b/backend/src/main/java/com/epsyl/eps/dtos/ArchiveProspectDTO.java new file mode 100644 index 0000000..ed228f7 --- /dev/null +++ b/backend/src/main/java/com/epsyl/eps/dtos/ArchiveProspectDTO.java @@ -0,0 +1,45 @@ +package com.epsyl.eps.dtos; + +import java.time.LocalDateTime; + +import com.epsyl.eps.entities.ArchiveProspect; +import com.epsyl.eps.entities.FileStorage; +import com.epsyl.eps.serialization.FileStorageDeserializer; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +public class ArchiveProspectDTO { + + private String _id; + private String firstName; + private String lastName; + private String trigramme; + private String email; + private String phone; + private String profil; + private String niveauEtude; + private String avis; + + @JsonDeserialize(using = FileStorageDeserializer.class) + private FileStorage cv; // ObjectId + + private LocalDateTime createdDate; + + public ArchiveProspectDTO(ArchiveProspect prospect, FileStorage cv) { + this._id = prospect.get_id().toString(); + this.firstName = prospect.getFirstName(); + this.lastName = prospect.getLastName(); + this.trigramme = prospect.getTrigramme(); + this.email = prospect.getEmail(); + this.phone = prospect.getPhone(); + this.profil = prospect.getProfil(); + this.niveauEtude = prospect.getNiveauEtude(); + this.avis = prospect.getAvis(); + this.cv = cv; + this.createdDate = prospect.getCreatedDate(); + } +} diff --git a/backend/src/main/java/com/epsyl/eps/dtos/ProspectDTO.java b/backend/src/main/java/com/epsyl/eps/dtos/ProspectDTO.java index 51a5e09..c1db807 100644 --- a/backend/src/main/java/com/epsyl/eps/dtos/ProspectDTO.java +++ b/backend/src/main/java/com/epsyl/eps/dtos/ProspectDTO.java @@ -22,48 +22,58 @@ public class ProspectDTO { private String email; private String phone; private String profil; - private Date dateContact; - private Date dateEntretien; - private String statutProspect; + private Date contactDate; + private Date meetingDate; private User bum; private User rh; private String source; - private Double pretentionSalariale; + private String pretentionSalarial; private String niveauEtude; + private Boolean frenchNationality; + private String nationality; + private String experience; + private String englishLevel; + private String avis; private String disponibilite; - private String mobiliteGeo; - private Boolean goNogo; + private String[] mobiliteGeo; private FileStorage cv; private FileStorage grille; private Integer pr; + private Boolean prValidated; private FileStorage dc; - private PushQualif pushQualif; + private PushQualif[] pushQualif; private LocalDateTime createdDate; public ProspectDTO(Prospect prospect, User bum, User rh, FileStorage cv, FileStorage grille, FileStorage dc) { - this._id = prospect.get_id(); + this._id = prospect.get_id().toString(); this.firstName = prospect.getFirstName(); this.lastName = prospect.getLastName(); this.trigramme = prospect.getTrigramme(); this.email = prospect.getEmail(); this.phone = prospect.getPhone(); this.profil = prospect.getProfil(); - this.dateContact = prospect.getDateContact(); - this.dateEntretien = prospect.getDateEntretien(); - this.statutProspect = prospect.getStatutProspect(); + this.contactDate = prospect.getContactDate(); + this.meetingDate = prospect.getMeetingDate(); this.bum = bum; this.rh = rh; this.source = prospect.getSource(); - this.pretentionSalariale = prospect.getPretentionSalariale(); + this.pretentionSalarial = prospect.getPretentionSalarial(); this.niveauEtude = prospect.getNiveauEtude(); + this.frenchNationality = prospect.getFrenchNationality(); + this.nationality = prospect.getNationality(); + this.experience = prospect.getExperience(); + this.englishLevel = prospect.getEnglishLevel(); + this.avis = prospect.getAvis(); + this.disponibilite = prospect.getDisponibilite(); + this.mobiliteGeo = prospect.getMobiliteGeo(); this.disponibilite = prospect.getDisponibilite(); this.mobiliteGeo = prospect.getMobiliteGeo(); - this.goNogo = prospect.getGoNogo(); this.cv = cv; this.grille = grille; this.pr = prospect.getPr(); + this.prValidated = prospect.getPrValidated(); this.dc = dc; this.pushQualif = prospect.getPushQualif(); this.createdDate = prospect.getCreatedDate(); } -} +} \ No newline at end of file diff --git a/backend/src/main/java/com/epsyl/eps/dtos/SignupRequest.java b/backend/src/main/java/com/epsyl/eps/dtos/SignupRequest.java index ae9dc7f..a34e6fc 100644 --- a/backend/src/main/java/com/epsyl/eps/dtos/SignupRequest.java +++ b/backend/src/main/java/com/epsyl/eps/dtos/SignupRequest.java @@ -53,6 +53,4 @@ public String getPassword() { public void setPassword(String password) { this.password = password; } - - -} +} \ No newline at end of file diff --git a/backend/src/main/java/com/epsyl/eps/emailings/MailBumAdded.java b/backend/src/main/java/com/epsyl/eps/emailings/MailBumAdded.java new file mode 100644 index 0000000..c0ada29 --- /dev/null +++ b/backend/src/main/java/com/epsyl/eps/emailings/MailBumAdded.java @@ -0,0 +1,68 @@ +package com.epsyl.eps.emailings; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.epsyl.eps.entities.Prospect; +import com.epsyl.eps.entities.User; +import com.epsyl.eps.repositories.UserRepository; +import com.epsyl.eps.services.email.EmailService; + +@Component +public class MailBumAdded { + + @Autowired + private EmailService emailService; + + @Autowired + private UserRepository userRepository; + + String[] recipients = { + "bum-bdx@epsyl-alcen.com", + "rhbordeaux@epsyl-alcen.com", + "rhidf@epsyl-alcen.com", + "service-rh@epsyl-alcen.com", + }; + + String[] recipientsTest = { + "rlassalle@epsyl-alcen.com", + "mjpereira@epsyl-alcen.com", + "bmortier@epsyl-alcen.com" + }; + + public void notifyBumAdded(Prospect prospect) { + System.out.println("--------------------------------"); + System.out.println("MailBumAdded=> " + prospect); + System.out.println("--------------------------------"); + + User bum = userRepository.findBy_id(prospect.bum); + String fullname = bum.getFirstName().substring(0,1) + "." + bum.getLastName(); + + String subject = "GO pour " + prospect.getFirstName() + "_" + prospect.getLastName().toUpperCase(); + String text = + "" + + "" + + "

Bonjour,

" + + "
" + + "" + bum.getFirstName() + " " + bum.getLastName() + " propose " + prospect.pr + "K, pour " + + prospect.getLastName().toUpperCase() + " " + prospect.getFirstName().toUpperCase() + + "
" + + "

Cordialement,

" + + "

" + fullname + "

" + + "" + + ""; + + // TODO Décommenter pour la prod + // for (String recipient : recipients) { + // sendEmail(recipient, subject, text); + // } + + for (String rTest : recipientsTest) { + try { + emailService.sendEmail(rTest, subject, text); + } catch (Exception exception) { + System.err.println("Erreur lors de l'envoi de l'email : " + exception.getMessage()); + } + } + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/epsyl/eps/emailings/MailGrilleAdded.java b/backend/src/main/java/com/epsyl/eps/emailings/MailGrilleAdded.java new file mode 100644 index 0000000..3ecb9fe --- /dev/null +++ b/backend/src/main/java/com/epsyl/eps/emailings/MailGrilleAdded.java @@ -0,0 +1,97 @@ +package com.epsyl.eps.emailings; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.epsyl.eps.entities.FileStorage; +import com.epsyl.eps.entities.Prospect; +import com.epsyl.eps.entities.User; +import com.epsyl.eps.repositories.UserRepository; +import com.epsyl.eps.services.FileStorageService; +import com.epsyl.eps.services.email.EmailService; + +@Component +public class MailGrilleAdded { + + @Autowired + private EmailService emailService; + + @Autowired + private UserRepository userRepository; + + @Autowired + private FileStorageService fileStorageService; + + String[] recipients = { + "bum-bdx@epsyl-alcen.com", + "rhbordeaux@epsyl-alcen.com", + "rhidf@epsyl-alcen.com", + "service-rh@epsyl-alcen.com", + }; + + String[] recipientsTest = { + "rlassalle@epsyl-alcen.com", + "mjpereira@epsyl-alcen.com", + "bmortier@epsyl-alcen.com" + }; + + public void notifyGrilleAdded(Prospect prospect) throws Exception { + User rh = userRepository.findBy_id(prospect.rh); + String fullname = rh.getFirstName().substring(0,1) + "." + rh.getLastName(); + String nationality = prospect.getFrenchNationality() ? "Française" : prospect.getNationality(); + String mobility = String.join(", ", prospect.getMobiliteGeo()); + + String subject = "CV + Grille_" + prospect.getFirstName() + " " + (prospect.getLastName()).toUpperCase(); + String text = + "" + + "" + + "

Bonjour,

" + + "
    " + + "
  1. " + + "Nom : " + prospect.getFirstName() + " " + prospect.getLastName() + "" + + "
  2. " + + "
  3. " + + "Diplôme + compétences : " + prospect.getNiveauEtude() + "" + + "
  4. " + + "
  5. " + + "Nationalité : " + nationality + "" + + "
  6. " + + "
  7. " + + "Année d'expérience : " + prospect.getExperience() + "" + + "
  8. " + + "
  9. " + + "Prétention salariale : " + prospect.getPretentionSalarial() + "K" + + "
  10. " + + "
  11. " + + "Mobilité géographique : " + mobility + "" + + "
  12. " + + "
  13. " + + "Anglais : " + prospect.getEnglishLevel() + "" + + "
  14. " + + "
  15. " + + "Disponibilité : " + prospect.getDisponibilite() + "" + + "
  16. " + + "
" + + "Avis : " + + "

" + prospect.getAvis() + "

" + + "
" + + "

Cordialement,

" + + "

" + fullname + "

" + + "" + + ""; + + FileStorage cvFile = fileStorageService.getFile(prospect.getCv()); + FileStorage grilleFile = fileStorageService.getFile(prospect.getGrille()); + + FileStorage[] files = {cvFile, grilleFile}; + + // TODO Décommenter pour la prod + // for (String recipient : recipients) { + // sendEmail(recipient, subject, text); + // } + + for (String rTest : recipientsTest) { + emailService.sendEmailWithAttachments(rTest, subject, text, files); + } + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/epsyl/eps/entities/ArchiveProspect.java b/backend/src/main/java/com/epsyl/eps/entities/ArchiveProspect.java new file mode 100644 index 0000000..0df15fc --- /dev/null +++ b/backend/src/main/java/com/epsyl/eps/entities/ArchiveProspect.java @@ -0,0 +1,48 @@ +package com.epsyl.eps.entities; + +import java.time.LocalDateTime; + +import org.bson.types.ObjectId; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.mongodb.core.mapping.Document; + +import com.epsyl.eps.serialization.ObjectIdDeserrializer; +import com.epsyl.eps.serialization.ObjectIdSerializer; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +@AllArgsConstructor +@Document(collection = "archive_prospect") +public class ArchiveProspect { + + @JsonSerialize(using = ObjectIdSerializer.class) + @JsonDeserialize(using = ObjectIdDeserrializer.class) + public ObjectId _id; + + public String firstName; + + public String lastName; + + public String trigramme; + + public String email; + + public String phone; + + public String profil; + + public String niveauEtude; + + public String avis; + + public String cv; // ObjectId + + @CreatedDate + public LocalDateTime createdDate; +} diff --git a/backend/src/main/java/com/epsyl/eps/entities/FileStorage.java b/backend/src/main/java/com/epsyl/eps/entities/FileStorage.java index 1874661..eb7ce2f 100644 --- a/backend/src/main/java/com/epsyl/eps/entities/FileStorage.java +++ b/backend/src/main/java/com/epsyl/eps/entities/FileStorage.java @@ -1,5 +1,6 @@ package com.epsyl.eps.entities; +import org.bson.types.ObjectId; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; @@ -12,12 +13,11 @@ @Builder @AllArgsConstructor @NoArgsConstructor -@Document(collection = "fileStorages") +@Document(collection = "file_storages") public class FileStorage { @Id - public String _id; + public ObjectId _id; public String filename; public String contentType; public byte[] data; - -} +} \ No newline at end of file diff --git a/backend/src/main/java/com/epsyl/eps/entities/Prospect.java b/backend/src/main/java/com/epsyl/eps/entities/Prospect.java index 37e2dee..2dae08e 100644 --- a/backend/src/main/java/com/epsyl/eps/entities/Prospect.java +++ b/backend/src/main/java/com/epsyl/eps/entities/Prospect.java @@ -3,13 +3,15 @@ import java.time.LocalDateTime; import java.util.Date; +import org.bson.types.ObjectId; import org.springframework.data.annotation.CreatedDate; -import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; -import com.epsyl.eps.configuration_global.ObjectIdDeserrializer; +import com.epsyl.eps.serialization.ObjectIdDeserrializer; +import com.epsyl.eps.serialization.ObjectIdSerializer; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import lombok.AllArgsConstructor; import lombok.Builder; @@ -23,9 +25,9 @@ @Document(collection = "prospects") public class Prospect { - @Id + @JsonSerialize(using = ObjectIdSerializer.class) @JsonDeserialize(using = ObjectIdDeserrializer.class) - public String _id; + public ObjectId _id; public String firstName; @@ -39,38 +41,55 @@ public class Prospect { public String profil; - public Date dateContact; + public Date contactDate; - public Date dateEntretien; + public Date meetingDate; - public String statutProspect; - - public String bum; // ObjectId + @JsonSerialize(using = ObjectIdSerializer.class) + @JsonDeserialize(using = ObjectIdDeserrializer.class) + public ObjectId bum; // ObjectId - public String rh; // ObjectId + @JsonSerialize(using = ObjectIdSerializer.class) + @JsonDeserialize(using = ObjectIdDeserrializer.class) + public ObjectId rh; // ObjectId public String source; - public Double pretentionSalariale; + public String pretentionSalarial; public String niveauEtude; - public String disponibilite; + public Boolean frenchNationality; + public String nationality; + + public String experience; + + public String englishLevel; - public String mobiliteGeo; + public String avis; - public Boolean goNogo; + public String disponibilite; + + public String[] mobiliteGeo; - public String cv; // ObjectId + @JsonSerialize(using = ObjectIdSerializer.class) + @JsonDeserialize(using = ObjectIdDeserrializer.class) + public ObjectId cv; // ObjectId - public String grille; // ObjectId + @JsonSerialize(using = ObjectIdSerializer.class) + @JsonDeserialize(using = ObjectIdDeserrializer.class) + public ObjectId grille; // ObjectId public Integer pr; - public String dc; // ObjectId + public Boolean prValidated; + + @JsonSerialize(using = ObjectIdSerializer.class) + @JsonDeserialize(using = ObjectIdDeserrializer.class) + public ObjectId dc; // ObjectId @JsonProperty - public PushQualif pushQualif; + public PushQualif[] pushQualif; @CreatedDate public LocalDateTime createdDate; diff --git a/backend/src/main/java/com/epsyl/eps/entities/User.java b/backend/src/main/java/com/epsyl/eps/entities/User.java index 3c68103..3fda3db 100644 --- a/backend/src/main/java/com/epsyl/eps/entities/User.java +++ b/backend/src/main/java/com/epsyl/eps/entities/User.java @@ -12,6 +12,7 @@ import java.util.Collection; import java.util.List; +import org.bson.types.ObjectId; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.DBRef; import org.springframework.data.mongodb.core.mapping.Document; @@ -19,15 +20,21 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; +import com.epsyl.eps.serialization.GrantedAuthorityDeserializer; +import com.epsyl.eps.serialization.GrantedAuthoritySerializer; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; -@Document(collection = "users") @Data @Builder @AllArgsConstructor @NoArgsConstructor +@Document(collection = "users") +@JsonIgnoreProperties(ignoreUnknown = true) public class User implements UserDetails { @Id - private String _id; + private ObjectId _id; @NotBlank @Size(max = 20) @@ -49,6 +56,8 @@ public class User implements UserDetails { @DBRef private Collection roles; + @JsonSerialize(contentUsing = GrantedAuthoritySerializer.class) + @JsonDeserialize(contentUsing = GrantedAuthorityDeserializer.class) @Override public Collection getAuthorities() { List authorities = new ArrayList<>(); @@ -85,5 +94,4 @@ public boolean isCredentialsNonExpired() { public boolean isEnabled() { return true; } - -} +} \ No newline at end of file diff --git a/backend/src/main/java/com/epsyl/eps/enums/ERole.java b/backend/src/main/java/com/epsyl/eps/enums/ERole.java index 2bd5ba3..78cee66 100644 --- a/backend/src/main/java/com/epsyl/eps/enums/ERole.java +++ b/backend/src/main/java/com/epsyl/eps/enums/ERole.java @@ -3,5 +3,9 @@ public enum ERole { ADMIN, RH, - BUM + BUM; + + public String getRoleName() { + return this.name().toUpperCase(); // Convertit l'enum en String majuscule + } } diff --git a/backend/src/main/java/com/epsyl/eps/exception/ResourceNotFoundException.java b/backend/src/main/java/com/epsyl/eps/exception/ResourceNotFoundException.java new file mode 100644 index 0000000..d446258 --- /dev/null +++ b/backend/src/main/java/com/epsyl/eps/exception/ResourceNotFoundException.java @@ -0,0 +1,8 @@ +package com.epsyl.eps.exception; + +public class ResourceNotFoundException extends RuntimeException { + + public ResourceNotFoundException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/epsyl/eps/repositories/ArchiveProspectRepository.java b/backend/src/main/java/com/epsyl/eps/repositories/ArchiveProspectRepository.java new file mode 100644 index 0000000..b0305d7 --- /dev/null +++ b/backend/src/main/java/com/epsyl/eps/repositories/ArchiveProspectRepository.java @@ -0,0 +1,11 @@ +package com.epsyl.eps.repositories; + +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.stereotype.Repository; + +import com.epsyl.eps.entities.ArchiveProspect; + +@Repository +public interface ArchiveProspectRepository extends MongoRepository { + +} diff --git a/backend/src/main/java/com/epsyl/eps/repositories/FileStorageRepository.java b/backend/src/main/java/com/epsyl/eps/repositories/FileStorageRepository.java index 7841ca2..620aeb3 100644 --- a/backend/src/main/java/com/epsyl/eps/repositories/FileStorageRepository.java +++ b/backend/src/main/java/com/epsyl/eps/repositories/FileStorageRepository.java @@ -1,9 +1,10 @@ package com.epsyl.eps.repositories; +import org.bson.types.ObjectId; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.stereotype.Repository; import com.epsyl.eps.entities.FileStorage; @Repository -public interface FileStorageRepository extends MongoRepository { } +public interface FileStorageRepository extends MongoRepository { } diff --git a/backend/src/main/java/com/epsyl/eps/repositories/ProspectRepository.java b/backend/src/main/java/com/epsyl/eps/repositories/ProspectRepository.java index 92b56c5..3766c80 100644 --- a/backend/src/main/java/com/epsyl/eps/repositories/ProspectRepository.java +++ b/backend/src/main/java/com/epsyl/eps/repositories/ProspectRepository.java @@ -1,12 +1,13 @@ package com.epsyl.eps.repositories; +import org.bson.types.ObjectId; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.stereotype.Repository; import com.epsyl.eps.entities.Prospect; @Repository -public interface ProspectRepository extends MongoRepository { +public interface ProspectRepository extends MongoRepository { /* * Vérifier si le trigramme existe diff --git a/backend/src/main/java/com/epsyl/eps/repositories/UserRepository.java b/backend/src/main/java/com/epsyl/eps/repositories/UserRepository.java index 9ae9f42..c2f8d99 100644 --- a/backend/src/main/java/com/epsyl/eps/repositories/UserRepository.java +++ b/backend/src/main/java/com/epsyl/eps/repositories/UserRepository.java @@ -1,5 +1,6 @@ package com.epsyl.eps.repositories; +import org.bson.types.ObjectId; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.stereotype.Repository; @@ -8,11 +9,11 @@ @Repository -public interface UserRepository extends MongoRepository { +public interface UserRepository extends MongoRepository { Optional findByEmail(String email); boolean existsByEmail(String email); - User findBy_id(String _id); + User findBy_id(ObjectId _id); } \ No newline at end of file diff --git a/backend/src/main/java/com/epsyl/eps/serialization/FileStorageDeserializer.java b/backend/src/main/java/com/epsyl/eps/serialization/FileStorageDeserializer.java new file mode 100644 index 0000000..b822c44 --- /dev/null +++ b/backend/src/main/java/com/epsyl/eps/serialization/FileStorageDeserializer.java @@ -0,0 +1,29 @@ +package com.epsyl.eps.serialization; + +import java.io.IOException; + +import org.bson.types.ObjectId; + +import com.epsyl.eps.entities.FileStorage; +import com.fasterxml.jackson.core.JacksonException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +public class FileStorageDeserializer extends JsonDeserializer { + @Override + public FileStorage deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException { + ObjectMapper mapper = (ObjectMapper) p.getCodec(); + ObjectNode node = mapper.readTree(p); + + FileStorage fileStorage = new FileStorage(); + fileStorage.set_id(new ObjectId(node.get("_id").asText())); + fileStorage.setFilename(node.get("filename").asText()); + fileStorage.setContentType(node.get("contentType").asText()); + fileStorage.setData(node.get("data").binaryValue()); + + return fileStorage; + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/epsyl/eps/serialization/GrantedAuthorityDeserializer.java b/backend/src/main/java/com/epsyl/eps/serialization/GrantedAuthorityDeserializer.java new file mode 100644 index 0000000..c14c06d --- /dev/null +++ b/backend/src/main/java/com/epsyl/eps/serialization/GrantedAuthorityDeserializer.java @@ -0,0 +1,22 @@ +package com.epsyl.eps.serialization; + +import java.io.IOException; + +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; + +public class GrantedAuthorityDeserializer extends StdDeserializer { + public GrantedAuthorityDeserializer() { + super(GrantedAuthority.class); + } + + @Override + public GrantedAuthority deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { + return new SimpleGrantedAuthority(p.getValueAsString()); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/epsyl/eps/serialization/GrantedAuthoritySerializer.java b/backend/src/main/java/com/epsyl/eps/serialization/GrantedAuthoritySerializer.java new file mode 100644 index 0000000..f025909 --- /dev/null +++ b/backend/src/main/java/com/epsyl/eps/serialization/GrantedAuthoritySerializer.java @@ -0,0 +1,20 @@ +package com.epsyl.eps.serialization; + +import java.io.IOException; + +import org.springframework.security.core.GrantedAuthority; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +public class GrantedAuthoritySerializer extends StdSerializer { + public GrantedAuthoritySerializer() { + super(GrantedAuthority.class); + } + + @Override + public void serialize(GrantedAuthority value, JsonGenerator gen, SerializerProvider provider) throws IOException { + gen.writeString(value.getAuthority()); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/epsyl/eps/serialization/ObjectIdDeserrializer.java b/backend/src/main/java/com/epsyl/eps/serialization/ObjectIdDeserrializer.java new file mode 100644 index 0000000..68e131a --- /dev/null +++ b/backend/src/main/java/com/epsyl/eps/serialization/ObjectIdDeserrializer.java @@ -0,0 +1,39 @@ +package com.epsyl.eps.serialization; + +import java.io.IOException; + +import org.bson.types.ObjectId; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; + +public class ObjectIdDeserrializer extends StdDeserializer { + + public ObjectIdDeserrializer() { + super(ObjectId.class); + } + + @Override + public ObjectId deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { + try { + String text = jsonParser.getValueAsString(); + System.out.println("Deserializing JSON: " + text); + + if(text == null || text.isEmpty()) { + return null; + } + + + if(!text.matches("^[0-9a-fA-F]{24}$")) { + throw new IllegalArgumentException("Input is not a valid ObjectId" + text); + } + + return new ObjectId(text); + } catch (IllegalArgumentException e) { + System.out.println("ObjectIdDeserrializer error: " + jsonParser.getText()); + throw new JsonParseException(jsonParser, "Invalid ObjectId: " + jsonParser.getText(), e); + } + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/epsyl/eps/serialization/ObjectIdSerializer.java b/backend/src/main/java/com/epsyl/eps/serialization/ObjectIdSerializer.java new file mode 100644 index 0000000..fac122c --- /dev/null +++ b/backend/src/main/java/com/epsyl/eps/serialization/ObjectIdSerializer.java @@ -0,0 +1,21 @@ +package com.epsyl.eps.serialization; + +import java.io.IOException; + +import org.bson.types.ObjectId; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +public class ObjectIdSerializer extends StdSerializer { + + public ObjectIdSerializer() { + super(ObjectId.class); + } + + @Override + public void serialize(ObjectId objectId, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + jsonGenerator.writeString(objectId.toString()); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/epsyl/eps/serialization/UserDeserializer.java b/backend/src/main/java/com/epsyl/eps/serialization/UserDeserializer.java new file mode 100644 index 0000000..6dfa68f --- /dev/null +++ b/backend/src/main/java/com/epsyl/eps/serialization/UserDeserializer.java @@ -0,0 +1,42 @@ +package com.epsyl.eps.serialization; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.bson.types.ObjectId; + +import com.epsyl.eps.entities.Role; +import com.epsyl.eps.entities.User; +import com.epsyl.eps.enums.ERole; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +public class UserDeserializer extends JsonDeserializer { + @Override + public User deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { + ObjectMapper mapper = (ObjectMapper) p.getCodec(); + ObjectNode node = mapper.readTree(p); + + User user = new User(); + user.set_id(new ObjectId(node.get("_id").asText())); + user.setFirstName(node.get("firstName").asText()); + user.setLastName(node.get("lastName").asText()); + user.setEmail(node.get("email").asText()); + user.setPassword(node.get("password").asText()); + + List roles = new ArrayList<>(); + node.get("roles").forEach(roleNode -> { + Role role = new Role(); + role.setName(ERole.valueOf(roleNode.get("name").asText().toUpperCase())); + roles.add(role); + }); + user.setRoles(roles); + + return user; + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/epsyl/eps/services/ArchiveProspectService.java b/backend/src/main/java/com/epsyl/eps/services/ArchiveProspectService.java new file mode 100644 index 0000000..fd6ee62 --- /dev/null +++ b/backend/src/main/java/com/epsyl/eps/services/ArchiveProspectService.java @@ -0,0 +1,12 @@ +package com.epsyl.eps.services; + +import java.util.Optional; + +import com.epsyl.eps.entities.ArchiveProspect; + +public interface ArchiveProspectService { + Iterable listAll(); + Optional getArchiveProspectByID(String id); + ArchiveProspect save(ArchiveProspect user); + Optional deleteArchive(String _id); +} diff --git a/backend/src/main/java/com/epsyl/eps/services/ArchiveProspectServiceImpl.java b/backend/src/main/java/com/epsyl/eps/services/ArchiveProspectServiceImpl.java new file mode 100644 index 0000000..2b76858 --- /dev/null +++ b/backend/src/main/java/com/epsyl/eps/services/ArchiveProspectServiceImpl.java @@ -0,0 +1,39 @@ +package com.epsyl.eps.services; + +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.epsyl.eps.entities.ArchiveProspect; +import com.epsyl.eps.repositories.ArchiveProspectRepository; + +@Service +public class ArchiveProspectServiceImpl implements ArchiveProspectService { + + @Autowired + private ArchiveProspectRepository archiveProspectRepository; + + @Override + public Iterable listAll() { + return this.archiveProspectRepository.findAll(); + } + + @Override + + public Optional getArchiveProspectByID(String id) { + return this.archiveProspectRepository.findById(id); + } + + public ArchiveProspect save(ArchiveProspect prospect) { + return this.archiveProspectRepository.save(prospect); + } + + public Optional deleteArchive(String _id) { + return this.archiveProspectRepository.findById(_id).flatMap(prospect -> { + archiveProspectRepository.deleteById(prospect.get_id().toString()); + return Optional.of(prospect); + }); + } + +} diff --git a/backend/src/main/java/com/epsyl/eps/services/FileStorageService.java b/backend/src/main/java/com/epsyl/eps/services/FileStorageService.java index 3f0a61b..b283bb0 100644 --- a/backend/src/main/java/com/epsyl/eps/services/FileStorageService.java +++ b/backend/src/main/java/com/epsyl/eps/services/FileStorageService.java @@ -3,6 +3,7 @@ import com.epsyl.eps.entities.FileStorage; import com.epsyl.eps.repositories.FileStorageRepository; +import org.bson.types.ObjectId; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; @@ -23,10 +24,10 @@ public String storeFile(MultipartFile file) throws IOException { fileStorage = fileStorageRepository.save(fileStorage); - return fileStorage._id; + return fileStorage._id.toHexString(); } - public FileStorage getFile(String id) { + public FileStorage getFile(ObjectId id) { return fileStorageRepository.findById(id).orElse(null); } } diff --git a/backend/src/main/java/com/epsyl/eps/services/ProspectService.java b/backend/src/main/java/com/epsyl/eps/services/ProspectService.java index 3ef36e9..8541dd6 100644 --- a/backend/src/main/java/com/epsyl/eps/services/ProspectService.java +++ b/backend/src/main/java/com/epsyl/eps/services/ProspectService.java @@ -3,88 +3,15 @@ import java.util.List; import java.util.Optional; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.data.mongodb.core.aggregation.Aggregation; -import org.springframework.data.mongodb.core.aggregation.AggregationResults; -import org.springframework.data.mongodb.core.query.Criteria; -import org.springframework.stereotype.Service; +import org.bson.types.ObjectId; import com.epsyl.eps.entities.Prospect; -import com.epsyl.eps.repositories.ProspectRepository; -@Service -public class ProspectService { - - @Autowired - private ProspectRepository prospectRepository; - - @Autowired - private MongoTemplate mongoTemplate; - - public Prospect getProspectWithUserDetail(String prospectId) { - Aggregation aggregation = Aggregation.newAggregation( - Aggregation.match(Criteria.where("_id").is(prospectId)), - Aggregation.lookup("users", "bum", "_id", "bumDetails"), - Aggregation.lookup("users", "rh", "_id", "rhDetails") - ); - AggregationResults results = mongoTemplate.aggregate(aggregation, "prospects", Prospect.class); - return results.getUniqueMappedResult(); - } - - // All prospects - public List allProspects() { - return prospectRepository.findAll(); - } - - // One prospect - public Optional getProspectByID(String _id) { - return prospectRepository.findById(_id); - } - - public Prospect save(Prospect prospect) { - return prospectRepository.save(prospect); - } - - public Prospect updateProspect(String id, Prospect updatedProspect) { - // Récupérer le prospect existant depuis la base de données - Prospect existingProspect = prospectRepository.findById(id).orElseThrow(() -> new RuntimeException("Prospect not found")); - - existingProspect.setFirstName(updatedProspect.getFirstName()); - existingProspect.setLastName(updatedProspect.getLastName()); - existingProspect.setTrigramme(updatedProspect.getTrigramme()); - existingProspect.setEmail(updatedProspect.getEmail()); - existingProspect.setPhone(updatedProspect.getPhone()); - existingProspect.setProfil(updatedProspect.getProfil()); - existingProspect.setDateContact(updatedProspect.getDateContact()); - existingProspect.setDateEntretien(updatedProspect.getDateEntretien()); - existingProspect.setStatutProspect(updatedProspect.getStatutProspect()); - existingProspect.setBum(updatedProspect.getBum()); - existingProspect.setRh(updatedProspect.getRh()); - existingProspect.setSource(updatedProspect.getSource()); - existingProspect.setPretentionSalariale(updatedProspect.getPretentionSalariale()); - existingProspect.setNiveauEtude(updatedProspect.getNiveauEtude()); - existingProspect.setDisponibilite(updatedProspect.getDisponibilite()); - existingProspect.setMobiliteGeo(updatedProspect.getMobiliteGeo()); - existingProspect.setGoNogo(updatedProspect.getGoNogo()); - existingProspect.setCv(updatedProspect.getCv()); - existingProspect.setGrille(updatedProspect.getGrille()); - existingProspect.setPr(updatedProspect.getPr()); - existingProspect.setDc(updatedProspect.getDc()); - existingProspect.setPushQualif(updatedProspect.getPushQualif()); - existingProspect.setCreatedDate(updatedProspect.getCreatedDate()); - - return existingProspect; - } - - public Optional deleteProspectById(String _id) { - return prospectRepository.findById(_id).flatMap(prospect -> { - prospectRepository.deleteById(prospect.get_id()); - return Optional.of(prospect); - }); - } - - public boolean trigramExist(String trigramme) { - return prospectRepository.existsByTrigramme(trigramme); - } +public interface ProspectService { + List allProspects(); + Optional getProspectByID(ObjectId _id); + Prospect createProspect(Prospect prospect); + Prospect updateProspect(ObjectId id, Prospect updatedProspect); + Optional deleteProspectById(ObjectId _id); + boolean trigramExist(String trigramme); } diff --git a/backend/src/main/java/com/epsyl/eps/services/ProspectServiceImpl.java b/backend/src/main/java/com/epsyl/eps/services/ProspectServiceImpl.java new file mode 100644 index 0000000..a34d185 --- /dev/null +++ b/backend/src/main/java/com/epsyl/eps/services/ProspectServiceImpl.java @@ -0,0 +1,88 @@ +package com.epsyl.eps.services; + +import java.util.List; +import java.util.Optional; + +import org.bson.types.ObjectId; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.epsyl.eps.emailings.MailBumAdded; +import com.epsyl.eps.emailings.MailGrilleAdded; +import com.epsyl.eps.entities.Prospect; +import com.epsyl.eps.exception.ResourceNotFoundException; +import com.epsyl.eps.repositories.ProspectRepository; + +import lombok.RequiredArgsConstructor; + +@Service +@Transactional +@RequiredArgsConstructor +public class ProspectServiceImpl implements ProspectService { + + @Autowired + private ProspectRepository prospectRepository; + + @Autowired + private MailBumAdded mailBumAdded; + + @Autowired + private MailGrilleAdded mailGrilleAdded; + + // All prospects + public List allProspects() { + return prospectRepository.findAll(); + } + + // One prospect + public Optional getProspectByID(ObjectId _id) { + return prospectRepository.findById(_id); + } + + // Create prospect + public Prospect createProspect(Prospect prospect) { + return prospectRepository.save(prospect); + } + + // Update prospect + public Prospect updateProspect(ObjectId id, Prospect updatedProspect) { + Prospect existingProspect = prospectRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException("Prospect not found")); + + updatedProspect.set_id(existingProspect.get_id()); + + Prospect savedProspect = prospectRepository.save(updatedProspect); + + if (savedProspect.getGrille() != null) { + try { + mailGrilleAdded.notifyGrilleAdded(savedProspect); + } catch (Exception e) { + System.err.println("Erreur lors de l'envoi du mail Grille : " + e.getMessage()); + throw new RuntimeException("Erreur lors de l'envoi du mail Grille : " + e); + } + } + + if (savedProspect.getBum() != null) { + try { + mailBumAdded.notifyBumAdded(savedProspect); + } catch (Exception e) { + System.err.println("Erreur lors de l'envoi du mail Bum : " + e.getMessage()); + // Log exception without throwing to continue with the update + } + } + + return savedProspect; + } + + public Optional deleteProspectById(ObjectId _id) { + return prospectRepository.findById(_id).flatMap(prospect -> { + prospectRepository.deleteById(prospect.get_id()); + return Optional.of(prospect); + }); + } + + public boolean trigramExist(String trigramme) { + return prospectRepository.existsByTrigramme(trigramme); + } +} diff --git a/backend/src/main/java/com/epsyl/eps/services/RoleService.java b/backend/src/main/java/com/epsyl/eps/services/RoleService.java new file mode 100644 index 0000000..d945dd4 --- /dev/null +++ b/backend/src/main/java/com/epsyl/eps/services/RoleService.java @@ -0,0 +1,7 @@ +package com.epsyl.eps.services; + +import com.epsyl.eps.entities.Role; + +public interface RoleService { + Iterable getAllRoles(); +} diff --git a/backend/src/main/java/com/epsyl/eps/services/RoleServiceImpl.java b/backend/src/main/java/com/epsyl/eps/services/RoleServiceImpl.java new file mode 100644 index 0000000..51293ae --- /dev/null +++ b/backend/src/main/java/com/epsyl/eps/services/RoleServiceImpl.java @@ -0,0 +1,20 @@ +package com.epsyl.eps.services; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.epsyl.eps.entities.Role; +import com.epsyl.eps.repositories.RoleRepository; + +@Service +public class RoleServiceImpl implements RoleService { + + @Autowired + private RoleRepository roleRepository; + + @Override + public Iterable getAllRoles() { + return this.roleRepository.findAll(); + } + +} diff --git a/backend/src/main/java/com/epsyl/eps/services/UserService.java b/backend/src/main/java/com/epsyl/eps/services/UserService.java index 3c01f7f..3568dae 100644 --- a/backend/src/main/java/com/epsyl/eps/services/UserService.java +++ b/backend/src/main/java/com/epsyl/eps/services/UserService.java @@ -3,6 +3,8 @@ import java.util.List; import java.util.Optional; +import org.bson.types.ObjectId; + import com.epsyl.eps.entities.Role; import com.epsyl.eps.entities.User; @@ -13,7 +15,7 @@ public interface UserService { // CRUD operations Iterable listAll(); - Optional getUserByID(String id); + Optional getUserByID(ObjectId id); User saveUser(User user); - Optional deleteUser(String _id); + Optional deleteUser(ObjectId _id); } \ No newline at end of file diff --git a/backend/src/main/java/com/epsyl/eps/services/UserServiceImpl.java b/backend/src/main/java/com/epsyl/eps/services/UserServiceImpl.java index 4faf352..54aa8d9 100644 --- a/backend/src/main/java/com/epsyl/eps/services/UserServiceImpl.java +++ b/backend/src/main/java/com/epsyl/eps/services/UserServiceImpl.java @@ -3,6 +3,7 @@ import java.util.List; import java.util.Optional; +import org.bson.types.ObjectId; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; @@ -37,15 +38,21 @@ public Role addNewRole(Role role) { @Override public void addRoleToUser(User user, List roles) { - // User userFromDB = userRepository.findByEmail(user.getEmail()).orElse(null); + User userFromDB = userRepository.findByEmail(user.getEmail()).orElse(null); - // roles.stream() - // .map(Role::getName) - // .map(roleRepository::findByName) - // .forEach(userFromDB.getRoles()::add); + if(userFromDB != null) { + roles.forEach(role -> { + Role roleFromDB = roleRepository.findByName(role.getName().toString()).orElse(null); + + if(roleFromDB != null && !userFromDB.getRoles().contains(roleFromDB)) { + userFromDB.getRoles().add(roleFromDB); + } + }); + userRepository.save(userFromDB); + } } - public Optional getUserByID(String userId) { + public Optional getUserByID(ObjectId userId) { return this.userRepository.findById(userId); } @@ -53,7 +60,7 @@ public Iterable listAll() { return this.userRepository.findAll(); } - public Optional deleteUser(String _id) { + public Optional deleteUser(ObjectId _id) { return this.userRepository.findById(_id).flatMap(user -> { userRepository.deleteById(user.get_id()); return Optional.of(user); diff --git a/backend/src/main/java/com/epsyl/eps/services/authentification/AuthService.java b/backend/src/main/java/com/epsyl/eps/services/authentification/AuthService.java index aeb7722..728c108 100644 --- a/backend/src/main/java/com/epsyl/eps/services/authentification/AuthService.java +++ b/backend/src/main/java/com/epsyl/eps/services/authentification/AuthService.java @@ -70,14 +70,24 @@ public ResponseEntity register(RegisterRequestDto newUser) { public ResponseEntity login(LoginRequestDto request) { - var user = userRepository.findByEmail(request.getEmail()).orElseThrow(() -> { - return new RuntimeException("Utilisateur non trouvé"); - }); + var user = userRepository.findByEmail(request.getEmail()).orElseThrow(null); + if (user == null) { + return ResponseEntity.badRequest() + .body(UserResponseDto.builder() + .message("Email incorrect") + .build()); + } + try { Authentication authentication = authenticationManager .authenticate(new UsernamePasswordAuthenticationToken(request.getEmail(), request.getPassword())); - SecurityContextHolder.getContext().setAuthentication(authentication); + } catch (Exception e) { + return ResponseEntity.badRequest() + .body(UserResponseDto.builder() + .message("Mot de passe incorrect") + .build()); + } var jwtToken = jwtService.generateToken(user); @@ -88,7 +98,7 @@ public ResponseEntity login(LoginRequestDto request) { return ResponseEntity.ok() .headers(responseHeaders) .body(UserResponseDto.builder() - ._id(user.get_id()) + ._id(user.get_id().toString()) .firstName(user.getFirstName()) .lastName(user.getLastName()) .email(user.getEmail()) diff --git a/backend/src/main/java/com/epsyl/eps/services/email/EmailService.java b/backend/src/main/java/com/epsyl/eps/services/email/EmailService.java new file mode 100644 index 0000000..da08eec --- /dev/null +++ b/backend/src/main/java/com/epsyl/eps/services/email/EmailService.java @@ -0,0 +1,51 @@ +package com.epsyl.eps.services.email; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.ByteArrayResource; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.MimeMessageHelper; +import org.springframework.stereotype.Service; + +import com.epsyl.eps.entities.FileStorage; + +import jakarta.mail.MessagingException; +import jakarta.mail.internet.MimeMessage; + +@Service +public class EmailService { + @Autowired + private JavaMailSender mailSender; + + public void sendEmail(String to, String subject, String htmlContent) throws Exception { + MimeMessage mimeMessage = mailSender.createMimeMessage(); + + try { + MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true); + helper.setTo(to); + helper.setSubject(subject); + helper.setText(htmlContent, true); + + mailSender.send(mimeMessage); + } catch (MessagingException me) { + me.printStackTrace(); + } + } + + public void sendEmailWithAttachments(String to, String subject, String htmlContent, FileStorage[] attachments) throws Exception { + MimeMessage mimeMessage = mailSender.createMimeMessage(); + try { + MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true); + helper.setTo(to); + helper.setSubject(subject); + helper.setText(htmlContent, true); + // Ajout de piece jointe + for(FileStorage file : attachments) { + helper.addAttachment(file.filename, new ByteArrayResource(file.data)); + } + + mailSender.send(mimeMessage); + } catch (MessagingException me) { + me.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties index ebcb55f..32b41bc 100644 --- a/backend/src/main/resources/application.properties +++ b/backend/src/main/resources/application.properties @@ -14,9 +14,18 @@ spring.servlet.multipart.max-request-size=10MB spring.servlet.multipart.file-size-threshold=10MB # Spring Security -# spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:4200/auth -# spring.security.oauth2.resourceserver.jwt.jwk-set-uri=http -# App properties +# Token authentication spring.security.oauth2.resourceserver.jwt.public-key-location=JeSuisLaPuteDEpsylAlcenPourFaireToutEtNImporteQuoi +# mail +spring.mail.host=smtp.gmail.com +spring.mail.port=587 +spring.mail.username=automate@epsilon-alcen.com +spring.mail.password=x43#LEm@ +spring.mail.properties.mail.smtp.auth=true +spring.mail.properties.mail.smtp.starttls.enable=true +spring.mail.properties.mail.smtp.starttls.required=true +spring.mail.properties.mail.smtp.connectiontimeout=5000 +spring.mail.properties.mail.smtp.timeout=5000 +spring.mail.properties.mail.smtp.writetimeout=5000 \ No newline at end of file diff --git a/backend/src/test/java/com/epsyl/eps/entities/ProspectTest.java b/backend/src/test/java/com/epsyl/eps/entities/ProspectTest.java new file mode 100644 index 0000000..ce30fd2 --- /dev/null +++ b/backend/src/test/java/com/epsyl/eps/entities/ProspectTest.java @@ -0,0 +1,82 @@ +package com.epsyl.eps.entities; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Date; + +import org.bson.types.ObjectId; +import org.junit.jupiter.api.Test; + +public class ProspectTest { + @Test + public void testProspectBuilder() { + // Test de la méthode builder() de la classe Prospect. + ObjectId bumId = new ObjectId("667bc2ab8113383a0670eaef"); + ObjectId rhId = new ObjectId("667bc2ab8113383a0670eaf0"); + ObjectId cvId = new ObjectId("667bc2ab8113383a0670eaf1"); + ObjectId grilleId = new ObjectId("667bc2ab8113383a0670eaf2"); + ObjectId dcId = new ObjectId("667bc2ab8113383a0670eaf3"); + + Prospect prospect1 = Prospect.builder() + .firstName("John") + .lastName("Doe") + .email("john.doe@example.com") + .trigramme("JDO") + .bum(bumId) // Exemple de création d'un ObjectId + .rh(rhId) // Exemple de création d'un ObjectId + .phone("0011223344") + .profil("profil") + .contactDate(new Date()) + .meetingDate(new Date()) + .source("linkdin") + .pretentionSalarial("50-75") + .niveauEtude("bb") + .frenchNationality(true) + .nationality(null) + .experience("BB") + .englishLevel("novice") + .avis("TU") + .disponibilite("asap") + .mobiliteGeo(null) + .cv(cvId) + .grille(grilleId) + .pr(50) + .prValidated(true) + .dc(dcId) + .pushQualif(null) + .createdDate(null) + .build(); + + Prospect prospect2 = Prospect.builder() + .firstName("John") + .lastName("Doe") + .email("john.doe@example.com") + .trigramme("JDO") + .bum(bumId) // Exemple de création d'un ObjectId + .rh(rhId) // Exemple de création d'un ObjectId + .phone("0011223344") + .profil("profil") + .contactDate(new Date()) + .meetingDate(new Date()) + .source("linkdin") + .pretentionSalarial("50-75") + .niveauEtude("bb") + .frenchNationality(true) + .nationality(null) + .experience("BB") + .englishLevel("novice") + .avis("TU") + .disponibilite("asap") + .mobiliteGeo(null) + .cv(cvId) + .grille(grilleId) + .pr(50) + .prValidated(true) + .dc(dcId) + .pushQualif(null) + .createdDate(null) + .build(); + + assertThat(prospect1).isEqualTo(prospect2); + } +} diff --git a/backend/src/test/java/com/epsyl/eps/services/ProspectServiceTest.java b/backend/src/test/java/com/epsyl/eps/services/ProspectServiceTest.java new file mode 100644 index 0000000..ac1a6f9 --- /dev/null +++ b/backend/src/test/java/com/epsyl/eps/services/ProspectServiceTest.java @@ -0,0 +1,146 @@ +package com.epsyl.eps.services; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Optional; + +import org.bson.types.ObjectId; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.junit.jupiter.MockitoExtension; + +import com.epsyl.eps.emailings.MailGrilleAdded; +import com.epsyl.eps.entities.Prospect; +import com.epsyl.eps.repositories.ProspectRepository; + +@ExtendWith(MockitoExtension.class) +public class ProspectServiceTest { + @Mock + private ProspectRepository prospectRepository; + + @Mock + private MailGrilleAdded mailGrilleAdded; + + @InjectMocks + private ProspectService prospectService; + + private Prospect prospect; + + @BeforeEach + public void setUp() { + prospect = new Prospect(); + prospect.set_id(new ObjectId()); + prospect.setFirstName("John"); + prospect.setLastName("Doe"); + prospect.setEmail("john.doe@example.com"); + prospect.setTrigramme("JDO"); + prospect.setBum(new ObjectId()); // Exemple de création d'un ObjectId + prospect.setRh(new ObjectId()); // Exemple de création d'un ObjectId + prospect.setPhone("0011223344"); + prospect.setProfil("profil"); + prospect.setContactDate(new Date()); + prospect.setMeetingDate(new Date()); + prospect.setSource("linkdin"); + prospect.setPretentionSalarial("50-75"); + prospect.setNiveauEtude("bb"); + prospect.setFrenchNationality(true); + prospect.setNationality(null); + prospect.setExperience("BB"); + prospect.setEnglishLevel("novice"); + prospect.setAvis("TU"); + prospect.setDisponibilite("asap"); + prospect.setMobiliteGeo(null); + prospect.setCv(new ObjectId()); + prospect.setGrille(new ObjectId()); + prospect.setPr(50); + prospect.setPrValidated(true); + prospect.setDc(new ObjectId()); + prospect.setPushQualif(null); + prospect.setCreatedDate(null); + MockitoAnnotations.openMocks(this); + } + + @Test + public void testAllProspects() { + when(prospectRepository.findAll()).thenReturn(Arrays.asList(prospect)); + + List prospects = prospectService.allProspects(); + + assertThat(prospects).isNotNull(); + assertThat(prospects.size()).isEqualTo(1); + assertThat(prospects.get(0)).isEqualTo(prospect); + } + + @Test + public void testGetProspectByID() { + when(prospectRepository.findById(prospect.get_id())).thenReturn(Optional.of(prospect)); + + Optional foundProspect = prospectService.getProspectByID(prospect.get_id()); + + assertThat(foundProspect).isPresent(); + assertThat(foundProspect.get()).isEqualTo(prospect); + } + + @Test + public void testSave() { + when(prospectRepository.save(any(Prospect.class))).thenReturn(prospect); + + Prospect savedProspect = prospectService.createProspect(prospect); + + assertThat(savedProspect).isNotNull(); + assertThat(savedProspect).isEqualTo(prospect); + } + + @Test + public void testUpdateProspect() { + // Mock data + ObjectId prospectId = new ObjectId("667ae5ad6aa2bc3166214017"); + ObjectId prospectGrille = new ObjectId("667ae5ad6aa2bc3166215018"); + Prospect existingProspect = new Prospect(); + existingProspect.set_id(prospectId); + + Prospect updatedProspect = new Prospect(); + updatedProspect.set_id(prospectId); + updatedProspect.setFirstName("Updated John"); + updatedProspect.setGrille(prospectGrille); + + when((prospectRepository.findById(prospectId))).thenReturn(Optional.of(existingProspect)); + when(prospectRepository.save(any(Prospect.class))).thenReturn(updatedProspect); + + // Prospect result = prospectService.updateProspect(prospectId, updatedProspect); + + // verify(mailGrilleAdded, times(1)).notifyGrilleAdded(result); + } + + @Test + public void testDeleteProspectById() { + // Mock data + ObjectId prospectId = new ObjectId("667ae5ad6aa2bc3166214017"); + Prospect prospectToDelete = new Prospect(); + prospectToDelete.set_id(prospectId); + + when(prospectRepository.findById(prospectId)).thenReturn(Optional.of(prospectToDelete)); + + prospectService.deleteProspectById(prospectId); + + verify(prospectRepository, times(1)).deleteById(prospectId); + } + + @Test + public void testTrigramExist() { + when(prospectRepository.existsByTrigramme("JDO")).thenReturn(true); + + boolean result = prospectService.trigramExist("JDO"); + + assertThat(result).isTrue(); + } +} diff --git a/backend/src/test/java/com/epsyl/eps/services/UserServiceImplTest.java b/backend/src/test/java/com/epsyl/eps/services/UserServiceImplTest.java new file mode 100644 index 0000000..7e0f4fd --- /dev/null +++ b/backend/src/test/java/com/epsyl/eps/services/UserServiceImplTest.java @@ -0,0 +1,117 @@ +package com.epsyl.eps.services; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import org.bson.types.ObjectId; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import com.epsyl.eps.entities.Role; +import com.epsyl.eps.entities.User; +import com.epsyl.eps.enums.ERole; +import com.epsyl.eps.repositories.RoleRepository; +import com.epsyl.eps.repositories.UserRepository; + +@ExtendWith(MockitoExtension.class) +public class UserServiceImplTest { + + @Mock + private UserRepository userRepository; + + @Mock + private RoleRepository roleRepository; + + @InjectMocks + private UserServiceImpl userService; + + private User user; + private Role role; + + @BeforeEach + public void setUp() { + role = new Role("ROLE_USER", ERole.RH); // Assuming ERole is an enum or String + user = User.builder() + ._id(new ObjectId("667ae5ad6aa2bc3166214022")) + .firstName("John") + .lastName("Doe") + .email("user@example.com") + .password("password") + .roles(Arrays.asList(role)) + .build(); + } + + @Test + public void testAddNewRole() { + when(roleRepository.save(any(Role.class))).thenReturn(role); + + Role savedRole = userService.addNewRole(role); + + assertThat(savedRole).isEqualTo(role); + verify(roleRepository).save(role); + } + + @Test + public void testAddRoleToUser() { + when(userRepository.findByEmail(any(String.class))).thenReturn(Optional.of(user)); + when(roleRepository.findByName(any(String.class))).thenReturn(Optional.of(role)); + + userService.addRoleToUser(user, Arrays.asList(role)); + + verify(userRepository).findByEmail(user.getEmail()); + verify(roleRepository).findByName(role.getName().getRoleName()); + } + + @Test + public void testGetUserByID() { + ObjectId userId = new ObjectId("667ae5ad6aa2bc3166214022"); + when(userRepository.findById(userId)).thenReturn(Optional.of(user)); + + Optional foundUser = userService.getUserByID(userId); + + assertThat(foundUser).isPresent(); + assertThat(foundUser.get()).isEqualTo(user); + } + + @Test + public void testListAll() { + List users = Arrays.asList(user); + when(userRepository.findAll()).thenReturn(users); + + Iterable allUsers = userService.listAll(); + + assertThat(allUsers).containsExactlyElementsOf(users); + } + + @Test + public void testDeleteUser() { + ObjectId userId = new ObjectId("667ae5ad6aa2bc3166214017"); + when(userRepository.findById(userId)).thenReturn(Optional.of(user)); + + Optional deletedUser = userService.deleteUser(userId); + + assertThat(deletedUser).isPresent(); + assertThat(deletedUser.get()).isEqualTo(user); + verify(userRepository).deleteById(userId); + } + + @Test + public void testSaveUser() { + when(userRepository.save(any(User.class))).thenReturn(user); + + User savedUser = userService.saveUser(user); + + assertThat(savedUser).isEqualTo(user); + verify(userRepository).save(user); + } +}