From 6aae6cc0a419c981a44eb18d3fb8e6dd49b08c07 Mon Sep 17 00:00:00 2001 From: jboinembalome Date: Tue, 9 Feb 2021 17:58:15 +0100 Subject: [PATCH 1/8] MAJ de la description d'AttenteEntretien --- EPAServeur/Enum/StatutEp.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EPAServeur/Enum/StatutEp.cs b/EPAServeur/Enum/StatutEp.cs index 6f95570..4c93d06 100644 --- a/EPAServeur/Enum/StatutEp.cs +++ b/EPAServeur/Enum/StatutEp.cs @@ -39,7 +39,7 @@ namespace IO.Swagger.Enum [EnumMember(Value = "DatesProposees")] DatesProposees = 3, /// - /// Indique qu’il s’agit d’un EPS + /// Le collaborateur a choisi une date, il ne reste plus qu'à attendre l'entretien /// [EnumMember(Value = "AttenteEntretien")] AttenteEntretien = 4, From bcc0ddb5d9117463eb25c12ff57b9198c44a6ac2 Mon Sep 17 00:00:00 2001 From: jboinembalome Date: Thu, 11 Feb 2021 15:49:22 +0100 Subject: [PATCH 2/8] =?UTF-8?q?Mise=20=C3=A0=20jour=20du=20jeu=20de=20donn?= =?UTF-8?q?=C3=A9es=20fictif=20pour=20la=20partie=20Engagement?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- EPAServeur/Context/DataSeeder.cs | 202 +++++++++++++++++++++++++------ 1 file changed, 164 insertions(+), 38 deletions(-) diff --git a/EPAServeur/Context/DataSeeder.cs b/EPAServeur/Context/DataSeeder.cs index a478ee0..92be406 100644 --- a/EPAServeur/Context/DataSeeder.cs +++ b/EPAServeur/Context/DataSeeder.cs @@ -256,63 +256,70 @@ namespace EPAServeur.Context ep9 = new Ep { - IdCollaborateur = Guid.Parse("59a8becb-bc0a-4d3d-adb1-8a8bd13c48c9"), - IdReferent = Guid.Parse("e5d36da4-df16-4d19-8a11-1ba2f6efc80c"), - IdBu = 2, - Fonction = "Dev", + IdEP = 9, + IdCollaborateur = Guid.Parse("842650db-a548-4472-a3af-4c5fff3c1ab8"), + IdReferent = Guid.Parse("aa36f34c-9041-42f5-9db3-6536fe7f1696"), + IdBu = 1, + Fonction = "Ingénieur en Etudes et Développement", TypeEP = TypeEp.EPA, NumeroEp = 1, - DateCreation = new DateTime(2017, 7, 7), - DatePrevisionnelle = new DateTime(2018, 7, 8), + DateCreation = new DateTime(2020, 7, 7), + DatePrevisionnelle = new DateTime(2020, 7, 8), Obligatoire = false, Statut = StatutEp.Signe, CV = "CV.pdf", - DateSaisie = new DateTime(2018, 6, 20) + DateSaisie = new DateTime(2020, 7, 20) }; epContext.Ep.Add(ep9); ep10 = new Ep { - IdCollaborateur = Guid.Parse("a00eb610-d735-4a83-ac5a-7b89cbd4b42d"), - IdReferent = Guid.Parse("d3f69a83-8a29-4971-8d3c-2d0cf320dad2"), - IdBu = 2, - Fonction = "Dev", - TypeEP = TypeEp.EPA, + IdEP = 10, + IdCollaborateur = Guid.Parse("301ba7f3-095e-4912-8998-a7c942dc5f23"), + IdReferent = Guid.Parse("ea027734-ff0f-4308-8879-133a09fb3c46"), + IdBu = 3, + Fonction = "Ingénieur en Etudes et Développement", + TypeEP = TypeEp.EPS, NumeroEp = 1, - DateCreation = new DateTime(2017, 7, 7), - DatePrevisionnelle = new DateTime(2018, 7, 8), + DateCreation = new DateTime(2020, 6, 1), + DatePrevisionnelle = new DateTime(2020, 9, 25), Obligatoire = false, Statut = StatutEp.Signe, CV = "CV.pdf", - DateSaisie = new DateTime(2018, 6, 20) + DateSaisie = new DateTime(2020, 10, 5) }; epContext.Ep.Add(ep10); ep11 = new Ep { - IdCollaborateur = Guid.Parse("a00eb610-d735-4a83-ac5a-7b89cbd4b42d"), - IdReferent = Guid.Parse("d3f69a83-8a29-4971-8d3c-2d0cf320dad2"), + IdEP = 11, + IdCollaborateur = Guid.Parse("a0f40e2a-cc03-4032-a627-5389e1281c64"), + IdReferent = Guid.Parse("c199024f-5960-4c11-8e34-f9947d589284"), IdBu = 2, - Fonction = "Dev", + Fonction = "Ingénieur en Etudes et Développement", TypeEP = TypeEp.EPA, NumeroEp = 1, - DateCreation = new DateTime(2018, 1, 7), - DatePrevisionnelle = new DateTime(2018, 1, 6), + DateCreation = new DateTime(2020, 10, 15), + DatePrevisionnelle = new DateTime(2020, 12, 4), Obligatoire = false, - Statut = StatutEp.Signe, + Statut = StatutEp.SignatureReferent, CV = "CV.pdf", - DateSaisie = new DateTime(2018, 6, 20) + DateSaisie = new DateTime(2020, 12, 10) }; epContext.Ep.Add(ep11); - Engagement engagement1, engagement2, engagement3; + Engagement engagement1, engagement2, engagement3; // EnAttente + Engagement engagement4, engagement5, engagement6; // Respecte + Engagement engagement7, engagement8, engagement9; // NonRealisable + Engagement engagement10, engagement11, engagement12; // DateLimitePassee engagement1 = new Engagement { - Action = "Je m'engage à...", - Dispositif = "interne", - Modalite = "Modalite", - DateLimite = new DateTime(2017, 7, 7), + IdEngagement = 1, + Action = "Je m'engage à trouver une formation sur l'Asp.Net Core.", + Dispositif = "Demande de formation RH.", + Modalite = "Sur temps de travail", + DateLimite = new DateTime(2020, 9, 1), EtatEngagement = EtatEngagement.EnAttente, RaisonNonRealisable = null, Ep = ep9 @@ -321,28 +328,147 @@ namespace EPAServeur.Context engagement2 = new Engagement { - Action = "Je m'engage à faire...", - Dispositif = "externe", - Modalite = "Modalite 2", - DateLimite = new DateTime(2017, 7, 8), + IdEngagement = 2, + Action = "Je m'engage à attribuer une progression salariale.", + Dispositif = "Demande d'augmentation RH.", + Modalite = "Hors temps", + DateLimite = new DateTime(2020, 9, 1), EtatEngagement = EtatEngagement.EnAttente, RaisonNonRealisable = null, - Ep = ep10 + Ep = ep9 }; epContext.Engagement.Add(engagement2); engagement3 = new Engagement { - Action = "Je m'engage à faire...", - Dispositif = "externe", - Modalite = "Modalite 3", - DateLimite = new DateTime(2017, 7, 8), + IdEngagement = 3, + Action = "Je m'engage à réaliser des points hebdomadaires avec l'équipe pour renforcer le lien social.", + Dispositif = "Planifier un point hebdomadaire sur Teams.", + Modalite = "Sur temps de travail", + DateLimite = new DateTime(2020, 9, 1), EtatEngagement = EtatEngagement.EnAttente, - RaisonNonRealisable = "Aucune formation disponible", - Ep = ep11 + RaisonNonRealisable = null, + Ep = ep9 }; epContext.Engagement.Add(engagement3); + engagement4 = new Engagement + { + IdEngagement = 4, + Action = "Je m'engage à fournir une connexion internet afin que le collaborateur puisse travailler dans de bonnes condition lorsque ce dernier est en télétravail.", + Dispositif = "Fournir un téléphone portable avec une connexion internet.", + Modalite = "Hors temps", + DateLimite = new DateTime(2020, 9, 1), + EtatEngagement = EtatEngagement.Respecte, + RaisonNonRealisable = null, + Ep = ep9 + }; + epContext.Engagement.Add(engagement4); + + engagement5 = new Engagement + { + IdEngagement = 5, + Action = "Je m'engage à trouver une formation sur la méthode SCRUM.", + Dispositif = "Demande de formation RH.", + Modalite = "Sur temps de travail", + DateLimite = new DateTime(2020, 12, 1), + EtatEngagement = EtatEngagement.Respecte, + RaisonNonRealisable = null, + Ep = ep10 + }; + epContext.Engagement.Add(engagement5); + + engagement6 = new Engagement + { + IdEngagement = 6, + Action = "Je m'engage à réaliser un point avec le client pour améliorer l'intégration du collaborateur dans l'équipe.", + Dispositif = "Contacter le client pour planifier un rendez-vous.", + Modalite = "Sur temps de travail", + DateLimite = new DateTime(2020, 10, 25), + EtatEngagement = EtatEngagement.Respecte, + RaisonNonRealisable = null, + Ep = ep10 + }; + epContext.Engagement.Add(engagement6); + + engagement7 = new Engagement + { + IdEngagement = 7, + Action = "Je m'engage à attribuer 5 jours de télétravail pour le collbaorateur en dehors de la période Covid.", + Dispositif = "Demande RH.", + Modalite = "Sur temps de travail", + DateLimite = new DateTime(2020, 12, 1), + EtatEngagement = EtatEngagement.NonRealisable, + RaisonNonRealisable = "L'accord du télétravail ne permet pas d'avoir 5 jours de travail pour le Groupe 1.", + Ep = ep10 + }; + epContext.Engagement.Add(engagement7); + + engagement8 = new Engagement + { + IdEngagement = 8, + Action = "Je m'engage à attribuer 5 jours de congés supplémentaire.", + Dispositif = "Demande RH.", + Modalite = "Sur temps de travail", + DateLimite = new DateTime(2020, 12, 1), + EtatEngagement = EtatEngagement.NonRealisable, + RaisonNonRealisable = "On ne peut pas donner plus de jours de congés que le nombre de droits que le salarié a cotisé.", + Ep = ep10 + }; + epContext.Engagement.Add(engagement8); + + engagement9 = new Engagement + { + IdEngagement = 9, + Action = "Je m'engage à augmenter le salaire mensuel du collaborateur de 1000 euros.", + Dispositif = "Demande RH.", + Modalite = "Hors temps", + DateLimite = new DateTime(2021, 1, 31), + EtatEngagement = EtatEngagement.NonRealisable, + RaisonNonRealisable = "La demande d'augmentation dépasse le crédit budgétaire.", + Ep = ep11 + }; + epContext.Engagement.Add(engagement9); + + engagement10 = new Engagement + { + IdEngagement = 10, + Action = "Je m'engage à interdire le client de conctacter le collaborateur en dehors du temps de travail.", + Dispositif = "Contacter le client pour planifier un rendez-vous.", + Modalite = "Hors temps", + DateLimite = new DateTime(2021, 1, 31), + EtatEngagement = EtatEngagement.DateLimitePassee, + RaisonNonRealisable = "La date limite pour respecter l'engagement est passée.", + Ep = ep11 + }; + epContext.Engagement.Add(engagement10); + + engagement11 = new Engagement + { + IdEngagement = 11, + Action = "Je m'engage à trouver une formation sur le Cobol.", + Dispositif = "Demande de formation auprès des RH.", + Modalite = "Sur temps de travail", + DateLimite = new DateTime(2021, 1, 31), + EtatEngagement = EtatEngagement.DateLimitePassee, + RaisonNonRealisable = "La date limite pour respecter l'engagement est passée.", + Ep = ep11 + }; + epContext.Engagement.Add(engagement11); + + engagement12 = new Engagement + { + IdEngagement = 12, + Action = "Je m'engage à fournir une disque dur externe au collaborateur.", + Dispositif = "Demande de matériel auprès des RH.", + Modalite = "Sur temps de travail", + DateLimite = new DateTime(2021, 1, 31), + EtatEngagement = EtatEngagement.DateLimitePassee, + RaisonNonRealisable = "La date limite pour respecter l'engagement est passée.", + Ep = ep11 + }; + epContext.Engagement.Add(engagement12); + epContext.SaveChanges(); } From 0fdb651fddf52abb4b17153ffd8a59a205693c7c Mon Sep 17 00:00:00 2001 From: jboinembalome Date: Thu, 11 Feb 2021 15:51:23 +0100 Subject: [PATCH 3/8] Configuration du package Microsoft.AspNetCore.Mvc.NewtonsoftJson --- EPAServeur/EPAServeur.csproj | 2 +- EPAServeur/Startup.cs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/EPAServeur/EPAServeur.csproj b/EPAServeur/EPAServeur.csproj index 6f38212..a72dab4 100644 --- a/EPAServeur/EPAServeur.csproj +++ b/EPAServeur/EPAServeur.csproj @@ -7,10 +7,10 @@ + - diff --git a/EPAServeur/Startup.cs b/EPAServeur/Startup.cs index 887dfc8..cacfb6b 100644 --- a/EPAServeur/Startup.cs +++ b/EPAServeur/Startup.cs @@ -42,7 +42,8 @@ namespace EPAServeur }); }); - services.AddControllers(); + services.AddControllers().AddNewtonsoftJson(); + services.AddAuthentication(options => { From 92a68a26ccddea12187caf7890506acadf249385 Mon Sep 17 00:00:00 2001 From: jboinembalome Date: Thu, 11 Feb 2021 15:55:44 +0100 Subject: [PATCH 4/8] =?UTF-8?q?Mise=20=C3=A0=20jour=20des=20signatures=20d?= =?UTF-8?q?e=20l'interface?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- EPAServeur/IServices/IEngagementService.cs | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/EPAServeur/IServices/IEngagementService.cs b/EPAServeur/IServices/IEngagementService.cs index bc94629..3d22f92 100644 --- a/EPAServeur/IServices/IEngagementService.cs +++ b/EPAServeur/IServices/IEngagementService.cs @@ -1,5 +1,6 @@ using EPAServeur.Context; using IO.Swagger.DTO; +using IO.Swagger.Enum; using IO.Swagger.ModelCollaborateur; using System; using System.Collections.Generic; @@ -10,16 +11,8 @@ namespace EPAServeur.IServices { public interface IEngagementService { - - IEnumerable GetEngagements(bool? asc, int? numPage, int? parPAge, string texte, string tri); - Task> GetEngagementsAsync(bool? asc, int? numPage, int? parPAge, string texte, string tri); - IEnumerable GetEngagementsEnAttente(bool? asc, int? numPage, int? parPAge, string texte, string tri); - Task> GetEngagementsEnAttenteAsync(bool? asc, int? numPage, int? parPAge, string texte, string tri); - IEnumerable GetEngagementsRepondus(bool? asc, int? numPage, int? parPAge, string texte, string tri); - Task> GetEngagementsRepondusAsync(bool? asc, int? numPage, int? parPAge, string texte, string tri); - - EngagementDTO RepondreEngagement(EngagementDTO engagement, long? idEngagement); - Task RepondreEngagementAsync(EngagementDTO engagement, long? idEngagement); - + Task> GetEngagementsAsync(List idBUs, List etatsEngagement, bool? asc, int? numPage, int? parPage, string texte, string tri); + Task GetEngagementsCountAsync(List idBUs, List etatsEngagement, bool? asc, int? numPage, int? parPage, string texte, string tri); + Task RepondreEngagementAsync(EngagementDTO engagement, long idEngagement); } } From 170b806e40a892976be1aa55e6a919f8f8d1eac0 Mon Sep 17 00:00:00 2001 From: jboinembalome Date: Thu, 11 Feb 2021 15:57:12 +0100 Subject: [PATCH 5/8] =?UTF-8?q?Mise=20=C3=A0=20jour=20des=20endpoints=20+?= =?UTF-8?q?=20Ajout=20des=20droits?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- EPAServeur/Controllers/EngagementsApi.cs | 208 +++++++++++++++++------ 1 file changed, 154 insertions(+), 54 deletions(-) diff --git a/EPAServeur/Controllers/EngagementsApi.cs b/EPAServeur/Controllers/EngagementsApi.cs index 95ba16a..0408661 100644 --- a/EPAServeur/Controllers/EngagementsApi.cs +++ b/EPAServeur/Controllers/EngagementsApi.cs @@ -19,6 +19,16 @@ using IO.Swagger.Security; using Microsoft.AspNetCore.Authorization; using IO.Swagger.DTO; using IO.Swagger.Enum; +using EPAServeur.Attributes; +using EPAServeur.IServices; +using Microsoft.Extensions.Logging; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; +using Microsoft.AspNetCore.Http; +using System.Threading.Tasks; +using EPAServeur.Exceptions; +using Microsoft.EntityFrameworkCore; +using Microsoft.AspNetCore.Authentication.JwtBearer; namespace IO.Swagger.Controllers { @@ -28,12 +38,23 @@ namespace IO.Swagger.Controllers [ApiController] public class EngagementsApiController : ControllerBase { + private readonly IEngagementService engagementService; + private readonly ILogger logger; + private readonly IWebHostEnvironment env; + + public EngagementsApiController(IEngagementService _engagementService, ILogger _logger, IWebHostEnvironment _env) + { + engagementService = _engagementService; + logger = _logger; + env = _env; + } + /// /// /// /// Récupérer la liste des engagements. - /// Etats de l'engagement /// liste des ids des BU auxquelles les données sont rattachées + /// Etats de l'engagement /// Indique si les données sont récupérées dans l'ordre croissant ou non /// Numéro de la page du tableau à afficher /// Nombre d’élément maximum à afficher dans le tableau @@ -45,41 +66,49 @@ namespace IO.Swagger.Controllers /// Une erreur est survenue sur le serveur [HttpGet] [Route("/api/engagements")] - [Authorize(AuthenticationSchemes = BearerAuthenticationHandler.SchemeName)] + [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme, Roles = "RH")] [ValidateModelState] [SwaggerOperation("GetEngagements")] [SwaggerResponse(statusCode: 200, type: typeof(List), description: "OK")] [SwaggerResponse(statusCode: 401, type: typeof(ErreurDTO), description: "L'utilisateur souhaitant accéder à la ressource n'est pas authentifié")] [SwaggerResponse(statusCode: 403, type: typeof(ErreurDTO), description: "L’utilisateur souhaitant accéder à la ressource n’a pas les droits d’accès suffisants")] [SwaggerResponse(statusCode: 500, type: typeof(ErreurDTO), description: "Une erreur est survenue sur le serveur")] - public virtual IActionResult GetEngagements([FromQuery]List etatsEngagement, [FromQuery]List idBUs, [FromQuery]bool? asc, [FromQuery]int? numPage, [FromQuery][Range(5, 100)]int? parPAge, [FromQuery]string texte, [FromQuery]string tri) + public virtual async Task GetEngagements([FromQuery][CannotBeEmpty] List idBUs, [FromQuery]List etatsEngagement, [FromQuery]bool? asc, [FromQuery]int? numPage, [FromQuery][Range(5, 100)]int? parPAge, [FromQuery]string texte, [FromQuery]string tri) { - //TODO: Uncomment the next line to return response 200 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(200, default(List)); + if (env.IsDevelopment()) + logger.LogInformation("Récupération de la liste des engagements."); - //TODO: Uncomment the next line to return response 401 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(401, default(ErreurDTO)); + IEnumerable engagements; - //TODO: Uncomment the next line to return response 403 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(403, default(ErreurDTO)); + try + { + engagements = await engagementService.GetEngagementsAsync(idBUs, etatsEngagement, asc, numPage, parPAge, texte, tri); + } + catch (Exception e) + { + logger.LogError(e.Message); - //TODO: Uncomment the next line to return response 500 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(500, default(ErreurDTO)); - string exampleJson = null; - exampleJson = "[ {\n \"action\" : \"action\",\n \"id\" : 4,\n \"dispositif\" : \"dispositif\",\n \"modalite\" : \"modalite\",\n \"dateLimite\" : \"2000-01-23T04:56:07.000+00:00\",\n \"etatEngagement\" : \"EnAttente\",\n \"raisonNonRealisable\" : \"raisonNonRealisable\"\n}, {\n \"action\" : \"action\",\n \"id\" : 4,\n \"dispositif\" : \"dispositif\",\n \"modalite\" : \"modalite\",\n \"dateLimite\" : \"2000-01-23T04:56:07.000+00:00\",\n \"etatEngagement\" : \"EnAttente\",\n \"raisonNonRealisable\" : \"raisonNonRealisable\"\n} ]"; + ErreurDTO erreur = new ErreurDTO() + { + Code = StatusCodes.Status500InternalServerError, + Message = "Une erreur inconnue est survenue sur le serveur." + }; - var example = exampleJson != null - ? JsonConvert.DeserializeObject>(exampleJson) - : default(List); //TODO: Change the data returned - return new ObjectResult(example); + return StatusCode(erreur.Code.Value, erreur); + } + + if (env.IsDevelopment()) + logger.LogInformation("Liste des engagements récupérée."); + + return Ok(engagements); } /// /// /// /// Récupérer le nombre total d’engagements. - /// Etats de l'engagement /// liste des ids des BU auxquelles les données sont rattachées + /// Etats de l'engagement /// Indique si les données sont récupérées dans l'ordre croissant ou non /// Numéro de la page du tableau à afficher /// Nombre d’élément maximum à afficher dans le tableau @@ -91,33 +120,41 @@ namespace IO.Swagger.Controllers /// Une erreur est survenue sur le serveur [HttpGet] [Route("/api/engagements/count")] - [Authorize(AuthenticationSchemes = BearerAuthenticationHandler.SchemeName)] + [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme, Roles = "RH")] [ValidateModelState] [SwaggerOperation("GetEngagementsCount")] [SwaggerResponse(statusCode: 200, type: typeof(long?), description: "OK")] [SwaggerResponse(statusCode: 401, type: typeof(ErreurDTO), description: "L'utilisateur souhaitant accéder à la ressource n'est pas authentifié")] [SwaggerResponse(statusCode: 403, type: typeof(ErreurDTO), description: "L’utilisateur souhaitant accéder à la ressource n’a pas les droits d’accès suffisants")] [SwaggerResponse(statusCode: 500, type: typeof(ErreurDTO), description: "Une erreur est survenue sur le serveur")] - public virtual IActionResult GetEngagementsCount([FromQuery]List etatsEngagement, [FromQuery]List idBUs, [FromQuery]bool? asc, [FromQuery]int? numPage, [FromQuery][Range(5, 100)]int? parPAge, [FromQuery]string texte, [FromQuery]string tri) + public virtual async Task GetEngagementsCount([FromQuery][CannotBeEmpty]List idBUs, [FromQuery]List etatsEngagement, [FromQuery]bool? asc, [FromQuery]int? numPage, [FromQuery][Range(5, 100)]int? parPAge, [FromQuery]string texte, [FromQuery]string tri) { - //TODO: Uncomment the next line to return response 200 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(200, default(long?)); + if (env.IsDevelopment()) + logger.LogInformation("Récupération du nombre total d'engagements."); + + long count; - //TODO: Uncomment the next line to return response 401 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(401, default(ErreurDTO)); + try + { + count = await engagementService.GetEngagementsCountAsync(idBUs, etatsEngagement, asc, numPage, parPAge, texte, tri); + } + catch (Exception e) + { + logger.LogError(e.Message); - //TODO: Uncomment the next line to return response 403 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(403, default(ErreurDTO)); + ErreurDTO erreur = new ErreurDTO() + { + Code = StatusCodes.Status500InternalServerError, + Message = "Une erreur inconnue est survenue sur le serveur." + }; - //TODO: Uncomment the next line to return response 500 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(500, default(ErreurDTO)); - string exampleJson = null; - exampleJson = "0"; + return StatusCode(erreur.Code.Value, erreur); + } - var example = exampleJson != null - ? JsonConvert.DeserializeObject(exampleJson) - : default(long?); //TODO: Change the data returned - return new ObjectResult(example); + if (env.IsDevelopment()) + logger.LogInformation("Nombre total d'engagement récupéré."); + + return Ok(count); } /// @@ -134,7 +171,7 @@ namespace IO.Swagger.Controllers /// Une erreur est survenue sur le serveur [HttpPut] [Route("/api/engagements/{idEngagement}")] - [Authorize(AuthenticationSchemes = BearerAuthenticationHandler.SchemeName)] + [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme, Roles = "RH")] [ValidateModelState] [SwaggerOperation("UpdateEngagement")] [SwaggerResponse(statusCode: 200, type: typeof(EngagementDTO), description: "Engagement modifié avec succès")] @@ -143,32 +180,95 @@ namespace IO.Swagger.Controllers [SwaggerResponse(statusCode: 404, type: typeof(ErreurDTO), description: "La ressource n'a pas été trouvée")] [SwaggerResponse(statusCode: 415, type: typeof(ErreurDTO), description: "L’opération ne peut pas être effectuée car certaines données sont manquantes")] [SwaggerResponse(statusCode: 500, type: typeof(ErreurDTO), description: "Une erreur est survenue sur le serveur")] - public virtual IActionResult UpdateEngagement([FromBody]EngagementDTO body, [FromRoute][Required]long? idEngagement) + public virtual async Task UpdateEngagement([FromBody]EngagementDTO body, [FromRoute][Required]long idEngagement) { - //TODO: Uncomment the next line to return response 200 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(200, default(EngagementDTO)); + if (env.IsDevelopment()) + logger.LogInformation("Mise à jour de l'engagement d'id {idEngagement}.", idEngagement); + + try + { + body = await engagementService.RepondreEngagementAsync(body, idEngagement); + } + catch (EngagementInvalidException e) + { + if (env.IsDevelopment()) + logger.LogInformation(e.Message); + + ErreurDTO erreur = new ErreurDTO() + { + Code = StatusCodes.Status415UnsupportedMediaType, + Message = e.Message, + }; + + return StatusCode(erreur.Code.Value, erreur.Message); + } + catch (EngagementIncompatibleIdException e) + { + if (env.IsDevelopment()) + logger.LogInformation(e.Message); + + ErreurDTO erreur = new ErreurDTO() + { + Code = StatusCodes.Status415UnsupportedMediaType, + Message = e.Message, + }; + + return StatusCode(erreur.Code.Value, erreur.Message); + } + catch (EngagementNotFoundException e) + { + if (env.IsDevelopment()) + logger.LogInformation(e.Message); + + ErreurDTO erreur = new ErreurDTO() + { + Code = StatusCodes.Status404NotFound, + Message = e.Message + }; + + return NotFound(erreur); + } + catch (DbUpdateConcurrencyException e) + { + logger.LogError(e.Message); + + ErreurDTO erreur = new ErreurDTO() + { + Code = StatusCodes.Status500InternalServerError, + Message = string.Format("L'engagement {0} n'a pas pu être supprimé car il est pris par une autre ressource.", idEngagement) + }; + + return StatusCode(erreur.Code.Value, erreur); + } + catch (DbUpdateException e) + { + logger.LogError(e.Message); - //TODO: Uncomment the next line to return response 401 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(401, default(ErreurDTO)); + ErreurDTO erreur = new ErreurDTO() + { + Code = StatusCodes.Status500InternalServerError, + Message = "Une erreur est survenue sur le serveur lors de la suppression de l'engagement." + }; - //TODO: Uncomment the next line to return response 403 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(403, default(ErreurDTO)); + return StatusCode(erreur.Code.Value, erreur); + } + catch (Exception e) + { + logger.LogError(e.Message); - //TODO: Uncomment the next line to return response 404 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(404, default(ErreurDTO)); + ErreurDTO erreur = new ErreurDTO() + { + Code = StatusCodes.Status500InternalServerError, + Message = "Une erreur inconnue est survenue sur le serveur." + }; - //TODO: Uncomment the next line to return response 415 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(415, default(ErreurDTO)); + return StatusCode(erreur.Code.Value, erreur); + } - //TODO: Uncomment the next line to return response 500 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(500, default(ErreurDTO)); - string exampleJson = null; - exampleJson = "{\n \"action\" : \"action\",\n \"id\" : 4,\n \"dispositif\" : \"dispositif\",\n \"modalite\" : \"modalite\",\n \"dateLimite\" : \"2000-01-23T04:56:07.000+00:00\",\n \"etatEngagement\" : \"EnAttente\",\n \"raisonNonRealisable\" : \"raisonNonRealisable\"\n}"; + if (env.IsDevelopment()) + logger.LogInformation("Update effectué avec succès."); - var example = exampleJson != null - ? JsonConvert.DeserializeObject(exampleJson) - : default(EngagementDTO); //TODO: Change the data returned - return new ObjectResult(example); + return Ok(body); } } } From a1ca68302785057b39e371b08ce7e693ca290d9f Mon Sep 17 00:00:00 2001 From: jboinembalome Date: Thu, 11 Feb 2021 15:58:04 +0100 Subject: [PATCH 6/8] =?UTF-8?q?Mise=20=C3=A0=20jour=20des=20m=C3=A9thodes?= =?UTF-8?q?=20du=20service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- EPAServeur/Services/EngagementService.cs | 514 ++++++++++++----------- 1 file changed, 260 insertions(+), 254 deletions(-) diff --git a/EPAServeur/Services/EngagementService.cs b/EPAServeur/Services/EngagementService.cs index b5f6a69..ad750a5 100644 --- a/EPAServeur/Services/EngagementService.cs +++ b/EPAServeur/Services/EngagementService.cs @@ -2,15 +2,11 @@ using EPAServeur.Exceptions; using EPAServeur.IServices; using EPAServeur.Models.EP; -using EPAServeur.Models.Formation; -using EPAServeur.Models.SaisieChamp; using IO.Swagger.DTO; using IO.Swagger.Enum; -using IO.Swagger.ModelCollaborateur; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using System.Threading.Tasks; @@ -20,9 +16,42 @@ namespace EPAServeur.Services { #region Variables + + /// + /// Accès et gestion de la base de données + /// private readonly EpContext epContext; + + /// + /// Accès et service collaborateur + /// private readonly ICollaborateurService collaborateurService; - private readonly IReferentEPService referentService; + + /// + /// Nombre d'éléments min à afficher par page + /// + private readonly int minParPage = 5; + + /// + /// Nom d'éléments max à affichar par page + /// + private readonly int maxParPage = 100; + + /// + /// Nombre d'éléments à afficher par défaut par page + /// + private readonly int defaultParPage = 15; + + /// + /// Numéro de page min à afficher par défaut + /// + private readonly int defaultNumPage = 1; + + /// + /// Ordonnancement par défaut + /// + private readonly bool defaultAsc = true; + #endregion #region Contructeurs @@ -31,260 +60,270 @@ namespace EPAServeur.Services /// Constructeur de la classe EngagementService /// /// - public EngagementService(EpContext _epContext, ICollaborateurService _collaborateurService, IReferentEPService _referentService) + public EngagementService(EpContext _epContext, ICollaborateurService _collaborateurService) { epContext = _epContext; collaborateurService = _collaborateurService; - referentService = _referentService; } #endregion #region Méthodes Service - public IEnumerable GetEngagements(bool? asc, int? numPage, int? parPAge, string texte, string tri) + /// + /// Récupérer la liste des engagements de manière asynchrone + /// + /// + /// + /// + /// + /// + /// + /// + /// + public async Task> GetEngagementsAsync(List idBUs, List etatsEngagement, bool? asc, int? numPage, int? parPage, string texte, string tri) { + IQueryable query; IEnumerable engagements; + IEnumerable engagementDTOs; + IEnumerable collaborateurDTOs; - if (texte == null) - texte = ""; - else - texte = texte.ToLower(); - - int skip = (numPage.Value - 1) * parPAge.Value; - int take = parPAge.Value; + query = epContext.Engagement.Include(engagement => engagement.Ep); + query = IdBUsFilter(query, idBUs); + query = EtatsEngagementFilter(query, etatsEngagement); + query = ActionFilter(query, texte); + query = OrderByColumn(query, asc, tri); + query = SkipAndTake(query, parPage, numPage); - engagements = epContext.Engagement.Include(engagement => engagement.Ep).Skip(skip).Take(take); + engagements = await query.ToListAsync(); - if (engagements == null || engagements.Count() == 0) - return new List(); + collaborateurDTOs = await GetCollaborateurDTOs(engagements); - var engagementDTOs = engagements.Where(engagement => engagement.Modalite.ToLower().Contains(texte)).Select(engagement => GetEngagementDTO(engagement)); + engagementDTOs = engagements.Select(engagement => GetEngagementDTO(engagement, collaborateurDTOs)); return engagementDTOs; } - public async Task> GetEngagementsAsync(bool? asc, int? numPage, int? parPAge, string texte, string tri) + public async Task GetEngagementsCountAsync(List idBUs, List etatsEngagement, bool? asc, int? numPage, int? parPage, string texte, string tri) { - IEnumerable engagements; - - if (texte == null) - texte = ""; - else - texte = texte.ToLower(); - - int skip = (numPage.Value - 1) * parPAge.Value; - int take = parPAge.Value; - - engagements = await epContext.Engagement.Include(engagement => engagement.Ep).Skip(skip).Take(take).ToListAsync(); + IQueryable query; + long count; - if (engagements == null || engagements.Count() == 0) - return new List(); + query = epContext.Engagement.Include(engagement => engagement.Ep); + query = IdBUsFilter(query, idBUs); + query = EtatsEngagementFilter(query, etatsEngagement); + query = ActionFilter(query, texte); + query = OrderByColumn(query, asc, tri); + query = SkipAndTake(query, parPage, numPage); - var engagementDTOs = engagements.Where(engagement => engagement.Modalite.ToLower().Contains(texte)).Select(engagement => GetEngagementDTOAsync(engagement)); - var results = await Task.WhenAll(engagementDTOs); + count = await query.CountAsync(); - return results; + return count; } - public IEnumerable GetEngagementsEnAttente(bool? asc, int? numPage, int? parPAge, string texte, string tri) + /// + /// Donner une réponse à un engagement de manière asynchrone + /// + /// + /// + /// + public async Task RepondreEngagementAsync(EngagementDTO engagementDTO, long idEngagement) { - IEnumerable engagements; - - if (texte == null) - texte = ""; - else - texte = texte.ToLower(); - - int skip = (numPage.Value - 1) * parPAge.Value; - int take = parPAge.Value; + IEnumerable collaborateurDTOs; + Engagement engagement; - engagements = epContext.Engagement.Include(engagement => engagement.Ep).Where(engagement => engagement.EtatEngagement == EtatEngagement.EnAttente).Skip(skip).Take(take).ToList(); + IsEngagementValide(engagementDTO); - if (engagements == null || engagements.Count() == 0) - return new List(); + if (!engagementDTO.Id.HasValue || engagementDTO.Id.Value != idEngagement) + throw new EngagementIncompatibleIdException("L'id de l'engagement à mettre à jour et l'engagement à mettre à jour sont incompatible."); - var engagementDTOs = engagements.Where(engagement => engagement.Modalite.ToLower().Contains(texte)).Select(engagement => GetEngagementDTO(engagement)); - - return engagementDTOs; - } + engagement = await epContext.Engagement.Include(engagement => engagement.Ep).FirstOrDefaultAsync(engagement => engagement.IdEngagement == idEngagement); - public async Task> GetEngagementsEnAttenteAsync(bool? asc, int? numPage, int? parPAge, string texte, string tri) - { - IEnumerable engagements; - - if (texte == null) - texte = ""; - else - texte = texte.ToLower(); - - int skip = (numPage.Value - 1) * parPAge.Value; - int take = parPAge.Value; + if (engagement == null) + throw new EngagementNotFoundException(); - engagements = await epContext.Engagement.Include(engagement => engagement.Ep).Where(engagement => engagement.EtatEngagement == EtatEngagement.EnAttente).Skip(skip).Take(take).ToListAsync(); + collaborateurDTOs = await GetCollaborateurDTOs(engagement); - if (engagements == null || engagements.Count() == 0) - return new List(); + engagement = SetReponseEngagement(engagement, engagementDTO); - var engagementDTOs = engagements.Where(engagement => engagement.Modalite.ToLower().Contains(texte)).Select(engagement => GetEngagementDTOAsync(engagement)); - var results = await Task.WhenAll(engagementDTOs); + await epContext.SaveChangesAsync(); - return results; + return GetEngagementDTO(engagement, collaborateurDTOs); } - public IEnumerable GetEngagementsRepondus(bool? asc, int? numPage, int? parPAge, string texte, string tri) - { - IEnumerable engagements; - if (texte == null) - texte = ""; - else - texte = texte.ToLower(); + #endregion - int skip = (numPage.Value - 1) * parPAge.Value; - int take = parPAge.Value; + #region Méthodes Privée + /// + /// Vérifier si un objet EngagementDTO est valide pour ajout ou mise à jour + /// + /// Un objet EngagementDTO est valide si l'action, le dispositif, la modalité et la date limite n'est pas null, si l'EP est signé, et si l'EP est présent dans la base de données. + /// + /// + private void IsEngagementValide(EngagementDTO engagementDTO) + { + // Vérifier que l'engagement n'est pas null + if (engagementDTO == null) + throw new EngagementInvalidException("Aucun engagement n'a été reçu."); - engagements = epContext.Engagement.Include(engagement => engagement.Ep).Where(engagement => engagement.EtatEngagement == EtatEngagement.Respecte && engagement.Modalite.ToLower().Contains(texte)).Skip(skip).Take(take); + // Vérfier que l'engagement a bien un EP + if (engagementDTO.Ep == null || !engagementDTO.Ep.Id.HasValue) + throw new EngagementInvalidException("Impossible de répondre à un engagement sans EP."); - if (engagements == null || engagements.Count() == 0) - return new List(); + // Vérfier que l'ep a bien été signé par le collaborateur + if (engagementDTO.Ep.Statut != StatutEp.Signe) + throw new EngagementInvalidException("Impossible de répondre à un engagement d'un EP qui n'est pas en cours et qui n'a pas été signé par le collaborateur."); - var engagementDTOs = engagements.Where(engagement => engagement.Modalite.ToLower().Contains(texte)).Select(engagement => GetEngagementDTO(engagement)); + // Vérifier que l'engagement a bien une action + if (string.IsNullOrWhiteSpace(engagementDTO.Action)) + throw new EngagementInvalidException("L'action de l'engagement doit contenir au moins 1 caractère."); - return engagementDTOs; - } + // Vérifier que l'engagement a bien un dispositif + if (string.IsNullOrWhiteSpace(engagementDTO.Dispositif)) + throw new EngagementInvalidException("Le dispostif de l'engagement doit contenir au moins 1 caractère."); - public async Task> GetEngagementsRepondusAsync(bool? asc, int? numPage, int? parPAge, string texte, string tri) - { - IEnumerable engagements; - - if (texte == null) - texte = ""; - else - texte = texte.ToLower(); - - int skip = (numPage.Value - 1) * parPAge.Value; - int take = parPAge.Value; + // Vérifier que l'engagement a bien une modalité + if (string.IsNullOrWhiteSpace(engagementDTO.Modalite)) + throw new EngagementInvalidException("La modalité de l'engagement doit contenir au moins 1 caractère."); - engagements = await epContext.Engagement.Include(engagement => engagement.Ep).Where(engagement => engagement.EtatEngagement == EtatEngagement.Respecte && engagement.Modalite.ToLower().Contains(texte)).Skip(skip).Take(take).ToListAsync(); + // Vérifier que l'engagement a bien une date limite + if (!engagementDTO.DateLimite.HasValue) + throw new EngagementInvalidException("Impossible de répondre à l'engagement sans date limite."); - if (engagements == null || engagements.Count() == 0) - return new List(); - - var engagementDTOs = engagements.Where(engagement => engagement.Modalite.ToLower().Contains(texte)).Select(engagement => GetEngagementDTOAsync(engagement)); - var results = await Task.WhenAll(engagementDTOs); + // Vérifier que l'engagement a bien raison expliquant pourquoi l'engagement n'est pas réalisable lorsque l'état de l'engagement n'est pas réalisable + if (engagementDTO.EtatEngagement == EtatEngagement.NonRealisable && string.IsNullOrWhiteSpace(engagementDTO.RaisonNonRealisable)) + throw new EngagementInvalidException("Impossible de répondre à l'engagement, une raison doit être rensignée lorsqu'un engagement n'est pas réalisé."); - return results; + // Vérfier que l'EP lié à l'engagement est présent dans la BDD + if (!epContext.Ep.Any(ep => ep.IdEP == engagementDTO.Ep.Id.Value)) + throw new EngagementInvalidException("L'EP n'existe pas."); } /// - /// Donner une réponse à un engagement + /// Ajouter un ordonnancement croissant ou décroissant sur colonne /// - /// - /// + /// + /// /// - public EngagementDTO RepondreEngagement(EngagementDTO engagementDTO, long? idEngagement) + private IQueryable OrderByColumn(IQueryable query, bool? asc, string columnName) { + if (!asc.HasValue) + asc = defaultAsc; - if (!IsEngagementValide(engagementDTO)) - throw new EngagementInvalidException("Impossible de répondre à l'engagement, des données sont manquants."); - - if (engagementDTO.EtatEngagement == EtatEngagement.NonRealisable && string.IsNullOrWhiteSpace(engagementDTO.RaisonNonRealisable)) - throw new EngagementInvalidException("Impossible de répondre à l'engagement, une raison doit être rensignée lorsqu'un engagement n'est pas réalisé."); - - if (engagementDTO == null && !engagementDTO.Id.HasValue && engagementDTO.Id.Value != idEngagement) - throw new EngagementIncompatibleIdException(); - - - Engagement engagement = epContext.Engagement.Include(engagement => engagement.Ep).FirstOrDefault(engagement => engagement.IdEngagement == idEngagement); - - if (engagement == null) - throw new EngagementNotFoundException(); + if (string.IsNullOrWhiteSpace(columnName)) + { + if (asc.Value) + return query.OrderBy(p => p.Action); - engagement.EtatEngagement = engagementDTO.EtatEngagement; + return query.OrderByDescending(p => p.Action); + } - switch (engagement.EtatEngagement) + switch (columnName.ToLower()) { - case EtatEngagement.Respecte: - engagement.EtatEngagement = engagementDTO.EtatEngagement; - engagement.RaisonNonRealisable = null; - break; - case EtatEngagement.NonRealisable: - engagement.EtatEngagement = engagementDTO.EtatEngagement; - engagement.RaisonNonRealisable = engagementDTO.RaisonNonRealisable; - break; + case "action": + if (asc.Value) + return query.OrderBy(p => p.Action); + + return query.OrderByDescending(p => p.Action); + case "dispositif": + if (asc.Value) + return query.OrderBy(p => p.Dispositif); + + return query.OrderByDescending(p => p.Dispositif); + case "modalite": + if (asc.Value) + return query.OrderBy(p => p.Modalite); + + return query.OrderByDescending(p => p.Modalite); + case "date": + if (asc.Value) + return query.OrderBy(p => p.DateLimite); + + return query.OrderByDescending(p => p.DateLimite); default: - engagement.EtatEngagement = engagementDTO.EtatEngagement; - engagement.RaisonNonRealisable = null; - break; + if (asc.Value) + return query.OrderBy(p => p.Action); + + return query.OrderByDescending(p => p.Action); } + } - epContext.SaveChanges(); + /// + /// Ajouter un filtre pour récupérer les engagements en fonction de plusieurs identifiants de Business Unit + /// + /// + /// + /// + /// + private IQueryable IdBUsFilter(IQueryable query, List idBUs) + { + if (idBUs == null || idBUs.Count == 0) + throw new EngagementInvalidException("Aucune Business Unit n'a été reçu."); - return GetEngagementDTO(engagement); + return query.Where(engagement => idBUs.Contains(engagement.Ep.IdBu)); } - /// - /// Donner une réponse à un engagement de manière asynchrone + /// Ajouter un filtre pour récupérer les engagements en fonction de plusieurs états d'engagement /// - /// - /// + /// + /// /// - public async Task RepondreEngagementAsync(EngagementDTO engagementDTO, long? idEngagement) + private IQueryable EtatsEngagementFilter(IQueryable query, List etatsEngagement) { + if (etatsEngagement == null || etatsEngagement.Count <= 0) + return query; - if (!IsEngagementValide(engagementDTO)) - throw new EngagementInvalidException("Impossible de répondre à l'engagement, des données sont manquants."); + return query.Where(engagement => etatsEngagement.Contains(engagement.EtatEngagement)); + } - if (engagementDTO.EtatEngagement == EtatEngagement.NonRealisable && string.IsNullOrWhiteSpace(engagementDTO.RaisonNonRealisable)) - throw new EngagementInvalidException("Impossible de répondre à l'engagement, une raison doit être rensignée lorsqu'un engagement n'est pas réalisé."); + /// + /// Ajouter un filtre pour récupérer les engagements en fonction d'une action + /// + /// + /// + /// + private IQueryable ActionFilter(IQueryable query, string action) + { + if (string.IsNullOrWhiteSpace(action)) + return query; + return query.Where(engagement => engagement.Action.ToLower().Contains(action.ToLower())); + } - Engagement engagement = await epContext.Engagement.Include(engagement => engagement.Ep).FirstOrDefaultAsync(engagement => engagement.IdEngagement == idEngagement); + /// + /// Ajouter une pagination + /// + /// + /// + /// + /// + private IQueryable SkipAndTake(IQueryable query, int? parPage, int? numPage) + { + int skip, take; - if (engagement == null) - throw new EngagementNotFoundException(); + if (!parPage.HasValue || parPage.Value < minParPage || parPage.Value > maxParPage) + parPage = defaultParPage; - engagement.EtatEngagement = engagementDTO.EtatEngagement; + if (!numPage.HasValue || numPage.Value <= 0) + numPage = defaultNumPage; - switch (engagement.EtatEngagement) - { - case EtatEngagement.Respecte: - engagement.EtatEngagement = engagementDTO.EtatEngagement; - engagement.RaisonNonRealisable = null; - break; - case EtatEngagement.NonRealisable: - engagement.EtatEngagement = engagementDTO.EtatEngagement; - engagement.RaisonNonRealisable = engagementDTO.RaisonNonRealisable; - break; - default: - engagement.EtatEngagement = engagementDTO.EtatEngagement; - engagement.RaisonNonRealisable = null; - break; - } - await epContext.SaveChangesAsync(); + skip = (numPage.Value - 1) * parPage.Value; + take = parPage.Value; - return await GetEngagementDTOAsync(engagement); + return query.Skip(skip).Take(take); } - #endregion - - #region Méthodes Privée - private bool IsEngagementValide(EngagementDTO engagementDTO) - { - return !(engagementDTO == null || engagementDTO.Id == null || engagementDTO.Action == null || engagementDTO.DateLimite == null || engagementDTO.Dispositif == null || engagementDTO.Modalite == null); - } - #region Object to DTO /// - /// Récupère un objet EngagementDTO en fonction d'un objet Engagement + /// Récupère un objet EngagementDTO en fonction d'un objet Engagement et d'une liste de CollaborateurDTO /// /// /// - private EngagementDTO GetEngagementDTO(Engagement engagement) + private EngagementDTO GetEngagementDTO(Engagement engagement, IEnumerable collaborateurDTOs) { EngagementDTO engagementDTO = new EngagementDTO() { @@ -295,80 +334,67 @@ namespace EPAServeur.Services Modalite = engagement.Modalite, RaisonNonRealisable = engagement.RaisonNonRealisable, EtatEngagement = engagement.EtatEngagement, - Ep = GetEpInformationDTO(engagement.Ep) + Ep = GetEpInformationDTO(engagement.Ep, collaborateurDTOs) }; return engagementDTO; } + /// - /// Récupère un objet EngagementDTO en fonction d'un objet Engagement + /// Récuperer une liste de CollaborateurDTO contenant les collaborateurs et les référents. Retourne null si l'engagement est null. /// - /// + /// /// - private async Task GetEngagementDTOAsync(Engagement engagement) + private async Task> GetCollaborateurDTOs(Engagement engagement) { - EngagementDTO engagementDTO = new EngagementDTO() - { - Id = engagement.IdEngagement, - Action = engagement.Action, - DateLimite = engagement.DateLimite, - Dispositif = engagement.Dispositif, - Modalite = engagement.Modalite, - RaisonNonRealisable = engagement.RaisonNonRealisable, - EtatEngagement = engagement.EtatEngagement, - Ep = await GetEpInformationDTOAsync(engagement.Ep) - }; + List guids = new List(); - return engagementDTO; + guids.Add((Guid?)engagement.Ep.IdCollaborateur); + guids.Add(engagement.Ep.IdReferent); + + return await collaborateurService.GetCollaborateurDTOsAsync(guids); ; } /// - /// Récupère un objet EpInformationDTO en fonction d'un objet Ep + /// Récuperer une liste de CollaborateurDTO contenant les collaborateurs et les référents. Retourne null s'il n'y a aucun engagement. /// - /// + /// /// - private EpInformationDTO GetEpInformationDTO(Ep ep) + private async Task> GetCollaborateurDTOs(IEnumerable engagements) { - EpInformationDTO epInformationDTO = new EpInformationDTO() - { - Id = ep.IdEP, - Type = ep.TypeEP, - Statut = ep.Statut, - DatePrevisionnelle = ep.DatePrevisionnelle, - Obligatoire = ep.Obligatoire, - //Collaborateur = collaborateurService.GetCollaborateurById(ep.IdCollaborateur), - //Referent = referentService.GetReferentById(ep.IdReferent) - //Ajouter la date de disponibilité - }; + if (!engagements.Any()) + return null; - return epInformationDTO; + List guids = engagements.SelectMany(engagement => new[] { (Guid?)engagement.Ep.IdCollaborateur, engagement.Ep.IdReferent }).ToList(); + + return await collaborateurService.GetCollaborateurDTOsAsync(guids); } /// - /// Récupère un objet EpInformationDTO en fonction d'un objet Ep + /// Récupère un objet EpInformationDTO en fonction d'un objet Ep et d'une liste de CollaborateurDTO /// /// /// - private async Task GetEpInformationDTOAsync(Ep ep) + private EpInformationDTO GetEpInformationDTO(Ep ep, IEnumerable collaborateurDTOs) { + CollaborateurDTO collaborateur; + CollaborateurDTO referent; + + collaborateur = collaborateurDTOs.FirstOrDefault(collaborateurDTO => collaborateurDTO.Id == ep.IdCollaborateur); + referent = collaborateurDTOs.FirstOrDefault(collaborateurDTO => collaborateurDTO.Id == ep.IdReferent); + EpInformationDTO epInformationDTO = new EpInformationDTO() { Id = ep.IdEP, Type = ep.TypeEP, Statut = ep.Statut, + DateDisponibilite = ep.DateDisponibilite, DatePrevisionnelle = ep.DatePrevisionnelle, - Obligatoire = ep.Obligatoire - //Ajouter la date de disponibilité + Obligatoire = ep.Obligatoire, + Collaborateur = collaborateur, + Referent = referent, }; - var collaborateur = collaborateurService.GetCollaborateurByIdAsync(ep.IdCollaborateur); - var referent = collaborateurService.GetCollaborateurByIdAsync(ep.IdReferent); - - await Task.WhenAll(collaborateur, referent); - - epInformationDTO.Collaborateur = collaborateur.Result; - epInformationDTO.Referent = referent.Result; - return epInformationDTO; } @@ -378,51 +404,31 @@ namespace EPAServeur.Services #region DTO to Object /// - /// Modifie un objet Engagement en fonction d'un objet FormationDTO + /// Modifie la réponse d'un objet Engagement en fonction d'un objet EngagementDTO /// /// /// /// - private Engagement SetEngagement(Engagement engagement, EngagementDTO engagementDTO) + private Engagement SetReponseEngagement(Engagement engagement, EngagementDTO engagementDTO) { - engagement.Action = engagementDTO.Action; - engagement.DateLimite = engagementDTO.DateLimite.Value; - engagement.Dispositif = engagementDTO.Dispositif; - engagement.Modalite = engagementDTO.Modalite; - engagement.RaisonNonRealisable = engagementDTO.RaisonNonRealisable; engagement.EtatEngagement = engagementDTO.EtatEngagement; - engagement.Ep = GetEp(engagementDTO.Ep); - - return engagement; - } - - /// - /// Récupère un objet Ep en fonction d'un objet EpDTO - /// - /// - /// - private Ep GetEp(EpInformationDTO epInformationDTO) - { - if (epInformationDTO == null) - return null; - - Ep ep = new Ep() + switch (engagement.EtatEngagement) { - IdEP = epInformationDTO.Id.Value, - TypeEP = epInformationDTO.Type, - Statut = epInformationDTO.Statut, - DatePrevisionnelle = epInformationDTO.DatePrevisionnelle.Value, - Obligatoire = epInformationDTO.Obligatoire.Value, - IdReferent = epInformationDTO.Referent.Id.Value, - IdCollaborateur = epInformationDTO.Collaborateur.Id.Value, - // Ajouter la date de disponibilité - }; - - return ep; + case EtatEngagement.NonRealisable: + engagement.RaisonNonRealisable = engagementDTO.RaisonNonRealisable; + break; + case EtatEngagement.DateLimitePassee: + engagement.RaisonNonRealisable = "La date limite pour respecter l'engagement est passée."; + break; + default: + engagement.RaisonNonRealisable = null; + break; + } + + return engagement; } - #endregion #endregion From 74ca7f067ba0a6af37c06acc563864877977b7a9 Mon Sep 17 00:00:00 2001 From: jboinembalome Date: Thu, 11 Feb 2021 15:59:18 +0100 Subject: [PATCH 7/8] =?UTF-8?q?Cr=C3=A9ation=20des=20tests=20unitaires=20p?= =?UTF-8?q?our=20la=20partie=20Engagement?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/EngagementsApiTests.cs | 340 ++++++++++ .../Services/EngagementServiceTests.cs | 637 ++++++++++++++++++ 2 files changed, 977 insertions(+) create mode 100644 EPAServeur.Tests/Controllers/EngagementsApiTests.cs create mode 100644 EPAServeur.Tests/Services/EngagementServiceTests.cs diff --git a/EPAServeur.Tests/Controllers/EngagementsApiTests.cs b/EPAServeur.Tests/Controllers/EngagementsApiTests.cs new file mode 100644 index 0000000..c2de69f --- /dev/null +++ b/EPAServeur.Tests/Controllers/EngagementsApiTests.cs @@ -0,0 +1,340 @@ +using EPAServeur.Context; +using EPAServeur.Exceptions; +using EPAServeur.Models.Formation; +using EPAServeur.Services; +using IO.Swagger.Controllers; +using IO.Swagger.DTO; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.DependencyInjection; +using EPAServeur.IServices; +using Moq; +using IO.Swagger.ApiCollaborateur; +using IO.Swagger.Enum; + +namespace EPAServeur.Tests.Controllers +{ + [TestFixture] + public class EngagementsApiTests + { + #region Variables + + private IEngagementService engagementService; + private Mock mockEnvironment; + private EpContext epContext; + #endregion + + #region Setup + + [SetUp] + public void Setup() + { + // Création d'une collection de services pour l'injection de dépendance + var services = new ServiceCollection(); + + // Utilisation d'une base de données en mémoire + var optionBuider = new DbContextOptionsBuilder() + .UseInMemoryDatabase("server_ep_test") + .Options; + + services.AddDbContext(b => b.UseInMemoryDatabase("server_ep_test")); + + epContext = new EpContext(optionBuider); + + epContext.Database.EnsureDeleted(); + epContext.Database.EnsureCreated(); + epContext.SaveChanges(); + + // Ajout du jeu de données pour les tests + DataSeeder.AddEngagements(epContext); + + // Détache les entités du context car la base de données InMemory créé des conflits + // entre les clés primaires lors d'un Update ou d'un Insert + foreach (var entity in epContext.ChangeTracker.Entries()) + { + entity.State = EntityState.Detached; + } + + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + + // Récupère le service qui sera utilsé pour tester le contrôleur + var serviceProvider = services.BuildServiceProvider(); + engagementService = serviceProvider.GetService(); + + // Simule l'interface IWebHostEnvironment avec Moq + mockEnvironment = new Mock(); + + mockEnvironment + .Setup(m => m.EnvironmentName) + .Returns("Development"); + + } + + #endregion + + + #region Tests GetEngagements + + [Test] + public void GetEngagements_PasseDesParamsPresentsDansLaBDD_RetourneUnObjetOkResult() + { + // Arrange + EngagementsApiController engagementsApiController = new EngagementsApiController(engagementService, new NullLogger(), mockEnvironment.Object); + List idBUs = new List { 1, 2 }; + + // Act + var okResult = engagementsApiController.GetEngagements(idBUs, null, true, 1, 5, null, null); + + // Assert + Assert.IsInstanceOf(okResult.Result); + } + + [Test] + public void GetEngagements_PasseDesParamsPresentsDansLaBDD_RetourneLesCinqPremiersEngagements() + { + // Arrange + EngagementsApiController engagementsApiController = new EngagementsApiController(engagementService, new NullLogger(), mockEnvironment.Object); + List idBUs = new List { 1, 2 }; + int nbEngagement = 5; + int idFirstEngagement = 2; + int idLastEngagement = 10; + + // Act + var okResult = engagementsApiController.GetEngagements(idBUs, null, true, 1, 5, null, null).Result as OkObjectResult; + + // Assert + Assert.IsInstanceOf>(okResult.Value); + Assert.AreEqual(nbEngagement, (okResult.Value as IEnumerable).Count()); + Assert.AreEqual(idFirstEngagement, (okResult.Value as IEnumerable).First().Id); + Assert.AreEqual(idLastEngagement, (okResult.Value as IEnumerable).Last().Id); + } + + #endregion + + #region Tests GetEngagementsCount + + [Test] + public void GetEngagementsCount_PasseDesParamsPresentsDansLaBDD_RetourneUnObjetOkResult() + { + // Arrange + EngagementsApiController engagementsApiController = new EngagementsApiController(engagementService, new NullLogger(), mockEnvironment.Object); + List idBUs = new List { 1, 2 }; + + // Act + var okResult = engagementsApiController.GetEngagementsCount(idBUs, null, true, 1, 5, null, null); + + // Assert + Assert.IsInstanceOf(okResult.Result); + } + + [Test] + public void GetEngagementsCount_PasseDesParamsPresentsDansLaBDD_RetourneLeBonNombreDEngagement() + { + // Arrange + EngagementsApiController engagementsApiController = new EngagementsApiController(engagementService, new NullLogger(), mockEnvironment.Object); + List idBUs = new List { 1, 2 }; + int nbEngagement = 5; + + // Act + var okResult = engagementsApiController.GetEngagementsCount(idBUs, null, true, 1, 5, null, null).Result as OkObjectResult; + + // Assert + Assert.IsInstanceOf(okResult.Value); + Assert.AreEqual(nbEngagement, (long)okResult.Value); + } + + #endregion + + #region Tests UpdateEngagement + + [Test] + public void UpdateEngagement_ModifieUnEngagementAvecUnEPInvalide_RetourneUnObjetObjectResultDansCatchEngagementInvalidException() + { + // Arrange + long idEngagement = 1; + EtatEngagement reponse = EtatEngagement.Respecte; + EngagementsApiController engagementsApiController = new EngagementsApiController(engagementService, new NullLogger(), mockEnvironment.Object); + EpInformationDTO epInformationDTO = null; + + EngagementDTO engagementDTO = new EngagementDTO + { + Id = idEngagement, + Action = "Je m'engage à trouver une formation sur l'Asp.Net Core.", + Dispositif = "Demande de formation RH.", + Modalite = "Sur temps de travail", + DateLimite = new DateTime(2020, 9, 1), + EtatEngagement = reponse, + Ep = epInformationDTO + }; + + // Act + var objectResult = engagementsApiController.UpdateEngagement(engagementDTO, idEngagement); + + // Assert + Assert.IsInstanceOf(objectResult.Result); + } + + [Test] + public void UpdateEngagement_ModifieUnEngagementAvecUnIdEngagementInvalide_RetourneUnObjetObjectResultDansCatchEngagementIncompatibleIdException() + { + // Arrange + long idEngagement = 1; + long idEngagementIncorrecte = 2; + long idEp = 9; + EtatEngagement reponse = EtatEngagement.Respecte; + EngagementsApiController engagementsApiController = new EngagementsApiController(engagementService, new NullLogger(), mockEnvironment.Object); + EpInformationDTO epInformationDTO = epContext.Ep.Where(ep => ep.IdEP == idEp) + .Select(ep => new EpInformationDTO + { + Id = ep.IdEP, + Type = ep.TypeEP, + Statut = ep.Statut, + DateDisponibilite = ep.DateDisponibilite, + DatePrevisionnelle = ep.DatePrevisionnelle, + Obligatoire = ep.Obligatoire + }).FirstOrDefault(); + + EngagementDTO engagementDTO = new EngagementDTO + { + Id = idEngagementIncorrecte, + Action = "Je m'engage à trouver une formation sur l'Asp.Net Core.", + Dispositif = "Demande de formation RH.", + Modalite = "Sur temps de travail", + DateLimite = new DateTime(2020, 9, 1), + EtatEngagement = reponse, + Ep = epInformationDTO + }; + + // Act + var objectResult = engagementsApiController.UpdateEngagement(engagementDTO, idEngagement); + + // Assert + Assert.IsInstanceOf(objectResult.Result); + } + + [Test] + public void UpdateEngagement_ModifieUnEngagementInexistant_RetourneUnObjetObjectResultDansCatchEngagementNotFoundExceptionn() + { + // Arrange + long idEngagementInexistant = 999; + long idEp = 9; + EtatEngagement reponse = EtatEngagement.Respecte; + EngagementsApiController engagementsApiController = new EngagementsApiController(engagementService, new NullLogger(), mockEnvironment.Object); + EpInformationDTO epInformationDTO = epContext.Ep.Where(ep => ep.IdEP == idEp) + .Select(ep => new EpInformationDTO + { + Id = ep.IdEP, + Type = ep.TypeEP, + Statut = ep.Statut, + DateDisponibilite = ep.DateDisponibilite, + DatePrevisionnelle = ep.DatePrevisionnelle, + Obligatoire = ep.Obligatoire + }).FirstOrDefault(); + EngagementDTO engagementDTO = new EngagementDTO + { + Id = idEngagementInexistant, + Action = "Toto.", + Dispositif = "Tata.", + Modalite = "Titi", + DateLimite = new DateTime(2020, 9, 1), + EtatEngagement = reponse, + Ep = epInformationDTO + }; + + // Act + var objectResult = engagementsApiController.UpdateEngagement(engagementDTO, idEngagementInexistant); + + // Assert + Assert.IsInstanceOf(objectResult.Result); + } + + [Test] + public void UpdateEngagement_ModifieUnEngagementValide_RetourneUnObjetOkObjectResult() + { + // Arrange + long idEngagement = 1; + long idEp = 9; + EtatEngagement reponse = EtatEngagement.Respecte; + EngagementsApiController engagementsApiController = new EngagementsApiController(engagementService, new NullLogger(), mockEnvironment.Object); + EpInformationDTO epInformationDTO = epContext.Ep.Where(ep => ep.IdEP == idEp) + .Select(ep => new EpInformationDTO + { + Id = ep.IdEP, + Type = ep.TypeEP, + Statut = ep.Statut, + DateDisponibilite = ep.DateDisponibilite, + DatePrevisionnelle = ep.DatePrevisionnelle, + Obligatoire = ep.Obligatoire + }).FirstOrDefault(); + + EngagementDTO engagementDTO = new EngagementDTO + { + Id = idEngagement, + Action = "Je m'engage à trouver une formation sur l'Asp.Net Core.", + Dispositif = "Demande de formation RH.", + Modalite = "Sur temps de travail", + DateLimite = new DateTime(2020, 9, 1), + EtatEngagement = reponse, + Ep = epInformationDTO + }; + + // Act + var okObjectResult = engagementsApiController.UpdateEngagement(engagementDTO, idEngagement); + + // Assert + Assert.IsInstanceOf(okObjectResult.Result); + } + + [Test] + public void UpdateEngagement_ModifieUnEngagementValide_RetourneLEngagementModifie() + { + // Arrange + long idEngagement = 1; + long idEp = 9; + EtatEngagement reponse = EtatEngagement.Respecte; + EngagementsApiController engagementsApiController = new EngagementsApiController(engagementService, new NullLogger(), mockEnvironment.Object); + EpInformationDTO epInformationDTO = epContext.Ep.Where(ep => ep.IdEP == idEp) + .Select(ep => new EpInformationDTO + { + Id = ep.IdEP, + Type = ep.TypeEP, + Statut = ep.Statut, + DateDisponibilite = ep.DateDisponibilite, + DatePrevisionnelle = ep.DatePrevisionnelle, + Obligatoire = ep.Obligatoire + }).FirstOrDefault(); + + EngagementDTO engagementDTO = new EngagementDTO + { + Id = idEngagement, + Action = "Je m'engage à trouver une formation sur l'Asp.Net Core.", + Dispositif = "Demande de formation RH.", + Modalite = "Sur temps de travail", + DateLimite = new DateTime(2020, 9, 1), + EtatEngagement = reponse, + Ep = epInformationDTO + }; + + // Act + var okObjectResult = engagementsApiController.UpdateEngagement(engagementDTO, idEngagement).Result as OkObjectResult; + + // Assert + Assert.IsInstanceOf(okObjectResult.Value); + Assert.AreEqual(reponse, (okObjectResult.Value as EngagementDTO).EtatEngagement); + } + + #endregion + + } +} \ No newline at end of file diff --git a/EPAServeur.Tests/Services/EngagementServiceTests.cs b/EPAServeur.Tests/Services/EngagementServiceTests.cs new file mode 100644 index 0000000..8c25bc7 --- /dev/null +++ b/EPAServeur.Tests/Services/EngagementServiceTests.cs @@ -0,0 +1,637 @@ +using EPAServeur.Context; +using EPAServeur.Exceptions; +using EPAServeur.IServices; +using EPAServeur.Models.Formation; +using EPAServeur.Services; +using IO.Swagger.ApiCollaborateur; +using IO.Swagger.DTO; +using IO.Swagger.Enum; +using Microsoft.EntityFrameworkCore; +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace EPAServeur.Tests.Services +{ + [TestFixture] + public class EngagementServiceTests + { + #region Variables + + private EpContext epContext; + private ICollaborateurApi collaborateurApi; + private ICollaborateurService collaborateurService; + #endregion + + #region Setup + + [SetUp] + public void Setup() + { + // Utilisation d'une base de données en mémoire + var optionBuider = new DbContextOptionsBuilder() + .UseInMemoryDatabase("server_ep_test") + .Options; + + epContext = new EpContext(optionBuider); + collaborateurApi = new CollaborateurApi(); + collaborateurService = new CollaborateurService(collaborateurApi, epContext); + epContext.Database.EnsureDeleted(); + epContext.Database.EnsureCreated(); + epContext.SaveChanges(); + + // Ajout du jeu de données pour les tests + DataSeeder.AddEngagements(epContext); + + // Détache les entités du context car la base de données InMemory créé des conflits + // entre les clés primaires lors d'un Update ou d'un Insert + foreach (var entity in epContext.ChangeTracker.Entries()) + { + entity.State = EntityState.Detached; + } + } + + #endregion + + #region Tests GetEngagementsAsync + + [TestCase(new long[] { 1, 2 })] + [TestCase(new long[] { 3 })] + public async Task GetEngagementsAsync_PasseDesParamsDesIdBUValides_RetourneDesEngagements(long[] arrIdBUs) + { + // Arrange + EngagementService engagementService = new EngagementService(epContext, collaborateurService); + List idBUs = arrIdBUs.Select(x => x).ToList(); + + // Act + IEnumerable engagementDTOs = await engagementService.GetEngagementsAsync(idBUs, null, null, null, null, null, null); + + // Assert + Assert.Less(0, engagementDTOs.Count()); + } + + [TestCase(new EtatEngagement[] { EtatEngagement.EnAttente, EtatEngagement.Respecte })] + [TestCase(new EtatEngagement[] { EtatEngagement.DateLimitePassee })] + public async Task GetEngagementsAsync_PasseDesParamsDesEtatsDEngagementsValides_RetourneDesEngagements(EtatEngagement[] arrEtatsEngagement) + { + // Arrange + EngagementService engagementService = new EngagementService(epContext, collaborateurService); + List idBUs = new List() { 1, 2, 3 }; + List etatEngagements = arrEtatsEngagement.Select(x => x).ToList(); + + // Act + IEnumerable engagementDTOs = await engagementService.GetEngagementsAsync(idBUs, etatEngagements, null, null, null, null, null); + + // Assert + Assert.Less(0, engagementDTOs.Count()); + } + + [TestCase(1, 5)] + [TestCase(1, 10)] + public async Task GetEngagementsAsync_PasseEnParamNumPageEtParPage_RetourneLaPremierePageDesEngagements(int? numPage, int? parPage) + { + // Arrange + EngagementService engagementService = new EngagementService(epContext, collaborateurService); + List idBUs = new List() { 1, 2, 3 }; + + // Act + IEnumerable engagementDTOs = await engagementService.GetEngagementsAsync(idBUs, null, null, numPage, parPage, null, null); + + // Assert + Assert.AreEqual(parPage, engagementDTOs.Count()); + } + + [TestCase(2, 5)] + [TestCase(2, 6)] + [TestCase(2, 10)] + [TestCase(2, 15)] + public async Task GetEngagementsAsync_PasseEnParamNumPageEtParPage_RetourneLaDeuxiemePageDesFormations(int? numPage, int? parPage) + { + // Arrange + EngagementService engagementService = new EngagementService(epContext, collaborateurService); + List idBUs = new List() { 1, 2, 3 }; + int? nbEngagementDeuxiemePage; + + switch (parPage) + { + case 5: + nbEngagementDeuxiemePage = 5; + break; + case 6: + nbEngagementDeuxiemePage = 6; + break; + case 10: + nbEngagementDeuxiemePage = 2; + break; + default: + nbEngagementDeuxiemePage = 0; + break; + } + + // Act + IEnumerable engagementDTOs = await engagementService.GetEngagementsAsync(idBUs, null, null, numPage, parPage, null, null); + + // Assert + Assert.AreEqual(nbEngagementDeuxiemePage, engagementDTOs.Count()); + } + + [TestCase(true, "action")] + [TestCase(true, null)] + [TestCase(true, "toto")] + public async Task GetEngagementsAsync_PasseEnParamAscEtTri_RetourneDesEngagementsOrdonnancesParActionCroissant(bool? asc, string tri) + { + // Arrange + EngagementService engagementService = new EngagementService(epContext, collaborateurService); + List idBUs = new List() { 1, 2, 3 }; + + // Act + IEnumerable engagementDTOs = await engagementService.GetEngagementsAsync(idBUs, null, asc, null, null, null, tri); + + // Assert + Assert.AreEqual("Je m'engage à attribuer 5 jours de congés supplémentaire.", engagementDTOs.First().Action); + Assert.AreEqual("Je m'engage à trouver une formation sur le Cobol.", engagementDTOs.Last().Action); + } + + [TestCase(false, "action")] + [TestCase(false, null)] + [TestCase(false, "toto")] + public async Task GetEngagementsAsync_PasseEnParamAscEtTri_RetourneDesEngagementsOrdonnancesParActionDecroissant(bool? asc, string tri) + { + // Arrange + EngagementService engagementService = new EngagementService(epContext, collaborateurService); + List idBUs = new List() { 1, 2, 3 }; + + // Act + IEnumerable engagementDTOs = await engagementService.GetEngagementsAsync(idBUs, null, asc, null, null, null, tri); + + // Assert + Assert.AreEqual("Je m'engage à trouver une formation sur le Cobol.", engagementDTOs.First().Action); + Assert.AreEqual("Je m'engage à attribuer 5 jours de congés supplémentaire.", engagementDTOs.Last().Action); + } + + [Test] + public async Task GetEngagementsAsync_PasseEnParamAscEtTri_RetourneDesEngagementsOrdonnancesParDispositifCroissant() + { + // Arrange + EngagementService engagementService = new EngagementService(epContext, collaborateurService); + List idBUs = new List() { 1, 2, 3 }; + bool? asc = true; + string tri = "dispositif"; + + // Act + IEnumerable engagementDTOs = await engagementService.GetEngagementsAsync(idBUs, null, asc, null, null, null, tri); + + // Assert + Assert.AreEqual("Contacter le client pour planifier un rendez-vous.", engagementDTOs.First().Dispositif); + Assert.AreEqual("Planifier un point hebdomadaire sur Teams.", engagementDTOs.Last().Dispositif); + } + + [Test] + public async Task GetEngagementsAsync_PasseEnParamAscEtTri_RetourneDesEngagementsOrdonnancesParDispositifDecroissant() + { + // Arrange + EngagementService engagementService = new EngagementService(epContext, collaborateurService); + List idBUs = new List() { 1, 2, 3 }; + bool? asc = false; + string tri = "dispositif"; + + // Act + IEnumerable engagementDTOs = await engagementService.GetEngagementsAsync(idBUs, null, asc, null, null, null, tri); + + // Assert + Assert.AreEqual("Planifier un point hebdomadaire sur Teams.", engagementDTOs.First().Dispositif); + Assert.AreEqual("Contacter le client pour planifier un rendez-vous.", engagementDTOs.Last().Dispositif); + } + + [Test] + public async Task GetEngagementsAsync_PasseEnParamAscEtTri_RetourneDesEngagementsOrdonnancesParModaliteCroissante() + { + // Arrange + EngagementService engagementService = new EngagementService(epContext, collaborateurService); + List idBUs = new List() { 1, 2, 3 }; + bool? asc = true; + string tri = "modalite"; + + // Act + IEnumerable engagementDTOs = await engagementService.GetEngagementsAsync(idBUs, null, asc, null, null, null, tri); + + // Assert + Assert.AreEqual("Hors temps", engagementDTOs.First().Modalite); + Assert.AreEqual("Sur temps de travail", engagementDTOs.Last().Modalite); + } + + [Test] + public async Task GetEngagementsAsync_PasseEnParamAscEtTri_RetourneDesEngagementsOrdonnancesParModaliteDecroissante() + { + // Arrange + EngagementService engagementService = new EngagementService(epContext, collaborateurService); + List idBUs = new List() { 1, 2, 3 }; + bool? asc = false; + string tri = "modalite"; + + // Act + IEnumerable engagementDTOs = await engagementService.GetEngagementsAsync(idBUs, null, asc, null, null, null, tri); + + // Assert + Assert.AreEqual("Sur temps de travail", engagementDTOs.First().Modalite); + Assert.AreEqual("Hors temps", engagementDTOs.Last().Modalite); + } + + [Test] + public async Task GetEngagementsAsync_PasseEnParamAscEtTri_RetourneDesEngagementsOrdonnancesParDateCroissante() + { + // Arrange + EngagementService engagementService = new EngagementService(epContext, collaborateurService); + List idBUs = new List() { 1, 2, 3 }; + bool? asc = true; + string tri = "date"; + + // Act + IEnumerable engagementDTOs = await engagementService.GetEngagementsAsync(idBUs, null, asc, null, null, null, tri); + + // Assert + Assert.AreEqual(new DateTime(2020, 9, 1), engagementDTOs.First().DateLimite); + Assert.AreEqual(new DateTime(2021, 1, 31), engagementDTOs.Last().DateLimite); + } + + [Test] + public async Task GetEngagementsAsync_PasseEnParamAscEtTri_RetourneDesEngagementsOrdonnancesParDateDecroissante() + { + // Arrange + EngagementService engagementService = new EngagementService(epContext, collaborateurService); + List idBUs = new List() { 1, 2, 3 }; + bool? asc = false; + string tri = "date"; + + // Act + IEnumerable engagementDTOs = await engagementService.GetEngagementsAsync(idBUs, null, asc, null, null, null, tri); + + // Assert + Assert.AreEqual(new DateTime(2021, 1, 31), engagementDTOs.First().DateLimite); + Assert.AreEqual(new DateTime(2020, 9, 1), engagementDTOs.Last().DateLimite); + } + + [TestCase(new long[] { 0 }, null )] + [TestCase(new long[] { 4 }, null)] + [TestCase(new long[] { 1, 2 }, "azerty")] + + public async Task GetEngagementsAsync_PasseDesParamsInvalides_RetourneZeroEngagement(long[] arrIdBUs, string texte) + { + // Arrange + EngagementService engagementService = new EngagementService(epContext, collaborateurService); + List idBUs; + + if (arrIdBUs != null) + idBUs = arrIdBUs.Select(x => x).ToList(); + else + idBUs = new List(); + + // Act + IEnumerable engagementDTOs = await engagementService.GetEngagementsAsync(idBUs, null, null, null, null, texte, null); + + // Assert + Assert.AreEqual(0, engagementDTOs.Count()); + } + + [Test] + public void GetEngagementsAsync_PasseDesParamsUneListeDIdsBUVide_LeveUneEngagementInvalidException() + { + // Arrange + EngagementService engagementService = new EngagementService(epContext, collaborateurService); + List idBUs = new List(); + + // Act + AsyncTestDelegate throwException = () => engagementService.GetEngagementsAsync(idBUs, null, null, null, null, null, null); + + // Assert + Assert.ThrowsAsync(typeof(EngagementInvalidException), throwException); + } + + [Test] + public void GetEngagementsAsync_PasseDesParamsUneListeDIdsBUNull_LeveUneEngagementInvalidException() + { + // Arrange + EngagementService engagementService = new EngagementService(epContext, collaborateurService); + List idBUs = null; + + // Act + AsyncTestDelegate throwException = () => engagementService.GetEngagementsAsync(idBUs, null, null, null, null, null, null); + + // Assert + Assert.ThrowsAsync(typeof(EngagementInvalidException), throwException); + } + + + #endregion + + #region Tests GetEngagementsCountAsync + + [TestCase(new long[] { 1, 2, 3 }, "formation")] + [TestCase(new long[] { 1 }, null)] + public async Task GetEngagementsCountAsync_PasseDesParamsValides_RetourneLeNombreTotalDEngagements(long[] arrIdBUs, string texte) + { + // Arrange + EngagementService engagementService = new EngagementService(epContext, collaborateurService); + List idBUs; + + if (arrIdBUs != null) + idBUs = arrIdBUs.Select(x => x).ToList(); + else + idBUs = new List(); + + // Act + long count = await engagementService.GetEngagementsCountAsync(idBUs, null, null, null, null, texte, null); + + // Assert + Assert.Less(0, count); + } + + [TestCase(new long[] { 0 }, null)] + [TestCase(new long[] { 4 }, null)] + [TestCase(new long[] { 1, 2 }, "azerty")] + public async Task GetEngagementsCountAsync_PasseDesParamsInvalides_RetourneZero(long[] arrIdBUs, string texte) + { + // Arrange + EngagementService engagementService = new EngagementService(epContext, collaborateurService); + List idBUs; + + if (arrIdBUs != null) + idBUs = arrIdBUs.Select(x => x).ToList(); + else + idBUs = new List(); + + // Act + long count = await engagementService.GetEngagementsCountAsync(idBUs, null, null, null, null, texte, null); + + // Assert + Assert.AreEqual(0, count); + } + + #endregion + + #region Tests RepondreEngagementAsync + + [TestCase(1, 9, EtatEngagement.Respecte, null)] + [TestCase(1, 9, EtatEngagement.EnAttente, null)] + [TestCase(2, 9, EtatEngagement.NonRealisable, "Impossible de respecter cet engagement car hors budget.")] + public async Task RepondreEngagementAsync_ModifieUnEngagementValide_EngagementModifieAvecSucces(long idEngagement, long idEp, EtatEngagement etatEngagement, string raisonNonRealisable) + { + // Arrange + EngagementService engagementService = new EngagementService(epContext, collaborateurService); + + EpInformationDTO epInformationDTO = epContext.Ep.Where(ep => ep.IdEP == idEp) + .Select(ep => new EpInformationDTO + { + Id = ep.IdEP, + Type = ep.TypeEP, + Statut = ep.Statut, + DateDisponibilite = ep.DateDisponibilite, + DatePrevisionnelle = ep.DatePrevisionnelle, + Obligatoire = ep.Obligatoire + }).FirstOrDefault(); + + EngagementDTO engagementDTO =new EngagementDTO + { + Id = idEngagement, + Action = "Je m'engage à trouver une formation sur l'Asp.Net Core.", + Dispositif = "Demande de formation RH.", + Modalite = "Sur temps de travail", + DateLimite = new DateTime(2020, 9, 1), + EtatEngagement = etatEngagement, + RaisonNonRealisable = raisonNonRealisable, + Ep = epInformationDTO + }; + + // Act + EngagementDTO engagementModifie = await engagementService.RepondreEngagementAsync(engagementDTO, idEngagement); + + // Assert + Assert.IsNotNull(engagementModifie); + Assert.AreEqual(idEngagement, engagementModifie.Id); + Assert.AreEqual(engagementDTO.Id, engagementModifie.Id); + Assert.AreEqual(engagementDTO.EtatEngagement, engagementModifie.EtatEngagement); + Assert.AreEqual(engagementDTO.RaisonNonRealisable, engagementModifie.RaisonNonRealisable); + } + + [Test] + public async Task RepondreEngagementAsync_ModifieUnEngagementAvecUneDateLimitePasseeValide_EngagementModifieAvecSucces() + { + long idEngagement = 3; + long idEp = 9; + EtatEngagement etatEngagement = EtatEngagement.DateLimitePassee; + string raisonNonRealisableAvantUpdate = null; + string raisonNonRealisableApresUpdate = "La date limite pour respecter l'engagement est passée."; + // Arrange + EngagementService engagementService = new EngagementService(epContext, collaborateurService); + + EpInformationDTO epInformationDTO = epContext.Ep.Where(ep => ep.IdEP == idEp) + .Select(ep => new EpInformationDTO + { + Id = ep.IdEP, + Type = ep.TypeEP, + Statut = ep.Statut, + DateDisponibilite = ep.DateDisponibilite, + DatePrevisionnelle = ep.DatePrevisionnelle, + Obligatoire = ep.Obligatoire + }).FirstOrDefault(); + + EngagementDTO engagementDTO = new EngagementDTO + { + Id = idEngagement, + Action = "Je m'engage à trouver une formation sur l'Asp.Net Core.", + Dispositif = "Demande de formation RH.", + Modalite = "Sur temps de travail", + DateLimite = new DateTime(2020, 9, 1), + EtatEngagement = etatEngagement, + RaisonNonRealisable = raisonNonRealisableAvantUpdate, + Ep = epInformationDTO + }; + + // Act + EngagementDTO engagementModifie = await engagementService.RepondreEngagementAsync(engagementDTO, idEngagement); + + // Assert + Assert.IsNotNull(engagementModifie); + Assert.AreEqual(idEngagement, engagementModifie.Id); + Assert.AreEqual(engagementDTO.Id, engagementModifie.Id); + Assert.AreEqual(engagementDTO.EtatEngagement, engagementModifie.EtatEngagement); + Assert.AreEqual(raisonNonRealisableApresUpdate, engagementModifie.RaisonNonRealisable); + } + + [TestCase(1, 0, "Je m'engage à trouver une formation sur l'Asp.Net Core.", "Demande de formation RH.", "Sur temps de travail", "2020-9-11", EtatEngagement.Respecte, null)] + [TestCase(1, 11, "Je m'engage à trouver une formation sur l'Asp.Net Core.", "Demande de formation RH.", "Sur temps de travail", "2020-9-11", EtatEngagement.Respecte, null)] + [TestCase(1, 9, "", "Demande de formation RH.", "Sur temps de travail", "2020-9-11", EtatEngagement.Respecte, null)] + [TestCase(1, 9, "Je m'engage à trouver une formation sur l'Asp.Net Core.", "", "Sur temps de travail", "2020-9-11", EtatEngagement.Respecte, null)] + [TestCase(1, 9, "Je m'engage à trouver une formation sur l'Asp.Net Core.", "Demande de formation RH.", "", "2020-9-11", EtatEngagement.Respecte, null)] + [TestCase(1, 9, "Je m'engage à trouver une formation sur l'Asp.Net Core.", "Demande de formation RH.", "Sur temps de travail", null, EtatEngagement.Respecte, null)] + [TestCase(1, 9, "Je m'engage à trouver une formation sur l'Asp.Net Core.", "Demande de formation RH.", "Sur temps de travail", "2020-9-11", EtatEngagement.NonRealisable, null)] + public void RepondreEngagementAsync_ModifieUnEngagementAvecDesProprietesInvalide_LeveUneEngagementInvalidException(long idEngagement, long idEp, string action, string dispositif, string modalite, DateTime? dateLimite, EtatEngagement etatEngagement, string raisonNonRealisable) + { + // Arrange + EngagementService engagementService = new EngagementService(epContext, collaborateurService); + + EpInformationDTO epInformationDTO = epContext.Ep.Where(ep => ep.IdEP == idEp) + .Select(ep => new EpInformationDTO + { + Id = ep.IdEP, + Type = ep.TypeEP, + Statut = ep.Statut, + DateDisponibilite = ep.DateDisponibilite, + DatePrevisionnelle = ep.DatePrevisionnelle, + Obligatoire = ep.Obligatoire + }).FirstOrDefault(); + + EngagementDTO engagementDTO = new EngagementDTO + { + Id = idEngagement, + Action = action, + Dispositif = dispositif, + Modalite = modalite, + DateLimite = dateLimite, + EtatEngagement = etatEngagement, + RaisonNonRealisable = raisonNonRealisable, + Ep = epInformationDTO + }; + + // Act + AsyncTestDelegate throwException = () => engagementService.RepondreEngagementAsync(engagementDTO, idEngagement); + + // Assert + Assert.ThrowsAsync(typeof(EngagementInvalidException), throwException); + } + + [Test] + public void RepondreEngagementAsync_ModifieUnEngagementNull_LeveUneEngagementInvalidException() + { + // Arrange + EngagementService engagementService = new EngagementService(epContext, collaborateurService); + EngagementDTO engagementDTO = null; + long idEngagement = 1; + + // Act + AsyncTestDelegate throwException = () => engagementService.RepondreEngagementAsync(engagementDTO, idEngagement); + + // Assert + Assert.ThrowsAsync(typeof(EngagementInvalidException), throwException); + } + + [Test] + public void RepondreEngagementAsync_ModifieUnEngagementAvecUnEPInexistantDansLaBDD_LeveUneEngagementInvalidException() + { + // Arrange + EngagementService engagementService = new EngagementService(epContext, collaborateurService); + long idEngagement = 1; + EpInformationDTO epInformationDTO = new EpInformationDTO + { + Id = 999, + Type = TypeEp.EPA, + Statut = StatutEp.Signe, + DateDisponibilite = DateTime.Now, + DatePrevisionnelle = DateTime.Now, + Obligatoire = false + }; + + EngagementDTO engagementDTO = new EngagementDTO + { + Id = idEngagement, + Action = "Je m'engage à trouver une formation sur l'Asp.Net Core.", + Dispositif = "Demande de formation RH.", + Modalite = "Sur temps de travail", + DateLimite = new DateTime(2020, 9, 1), + EtatEngagement = EtatEngagement.Respecte, + RaisonNonRealisable = null, + Ep = epInformationDTO + }; + + // Act + AsyncTestDelegate throwException = () => engagementService.RepondreEngagementAsync(engagementDTO, idEngagement); + + // Assert + Assert.ThrowsAsync(typeof(EngagementInvalidException), throwException); + } + + + + [TestCase(1)] + [TestCase(null)] + public void RepondreEngagementAsync_ModifieUnEngagementAvecUnIdIncorrecte_LeveUneEngagementnIncompatibleIdException(long? idEngagement) + { + // Arrange + long idEngagementIncorrecte = 2; + long idEp = 9; + + EngagementService engagementService = new EngagementService(epContext, collaborateurService); + + EpInformationDTO epInformationDTO = epContext.Ep.Where(ep => ep.IdEP == idEp) + .Select(ep => new EpInformationDTO + { + Id = ep.IdEP, + Type = ep.TypeEP, + Statut = ep.Statut, + DateDisponibilite = ep.DateDisponibilite, + DatePrevisionnelle = ep.DatePrevisionnelle, + Obligatoire = ep.Obligatoire + }).FirstOrDefault(); + + EngagementDTO engagementDTO = new EngagementDTO + { + Id = idEngagement, + Action = "Je m'engage à trouver une formation sur l'Asp.Net Core.", + Dispositif = "Demande de formation RH.", + Modalite = "Sur temps de travail", + DateLimite = new DateTime(2020, 9, 1), + EtatEngagement = EtatEngagement.Respecte, + RaisonNonRealisable = null, + Ep = epInformationDTO + }; + + // Act + AsyncTestDelegate throwException = () => engagementService.RepondreEngagementAsync(engagementDTO, idEngagementIncorrecte); + + // Assert + Assert.ThrowsAsync(typeof(EngagementIncompatibleIdException), throwException); + } + + [Test] + public void RepondreEngagementAsync_ModifieUnEngagementAvecUnIdInexistant_LeveUneEngagementNotFoundException() + { + // Arrange + long idEngagement = 0; + long idEp = 9; + + EngagementService engagementService = new EngagementService(epContext, collaborateurService); + + EpInformationDTO epInformationDTO = epContext.Ep.Where(ep => ep.IdEP == idEp) + .Select(ep => new EpInformationDTO + { + Id = ep.IdEP, + Type = ep.TypeEP, + Statut = ep.Statut, + DateDisponibilite = ep.DateDisponibilite, + DatePrevisionnelle = ep.DatePrevisionnelle, + Obligatoire = ep.Obligatoire + }).FirstOrDefault(); + + EngagementDTO engagementDTO = new EngagementDTO + { + Id = idEngagement, + Action = "Je m'engage à trouver une formation sur l'Asp.Net Core.", + Dispositif = "Demande de formation RH.", + Modalite = "Sur temps de travail", + DateLimite = new DateTime(2020, 9, 1), + EtatEngagement = EtatEngagement.Respecte, + RaisonNonRealisable = null, + Ep = epInformationDTO + }; + + // Act + AsyncTestDelegate throwException = () => engagementService.RepondreEngagementAsync(engagementDTO, idEngagement); + + // Assert + Assert.ThrowsAsync(typeof(EngagementNotFoundException), throwException); + } + #endregion + } +} \ No newline at end of file From 70808c29664dcb66acf6101d533007480b2d2293 Mon Sep 17 00:00:00 2001 From: jboinembalome Date: Thu, 11 Feb 2021 16:00:24 +0100 Subject: [PATCH 8/8] =?UTF-8?q?Cr=C3=A9ation=20d'un=20attribut=20pour=20va?= =?UTF-8?q?lider=20une=20collection=20qui=20est=20pass=C3=A9e=20en=20param?= =?UTF-8?q?=C3=A8tre=20d'un=20endpoint?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit L'attribut CannotBeEmpty vérifie que la liste n'est pas nulle et que la liste contient au moins 1 élément. L'api renvoie une erreur 400 (BadRequest) dans le cas contraire. --- .../Attributes/CannotBeEmptyAttribute.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 EPAServeur/Attributes/CannotBeEmptyAttribute.cs diff --git a/EPAServeur/Attributes/CannotBeEmptyAttribute.cs b/EPAServeur/Attributes/CannotBeEmptyAttribute.cs new file mode 100644 index 0000000..b785ba1 --- /dev/null +++ b/EPAServeur/Attributes/CannotBeEmptyAttribute.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections; +using System.ComponentModel.DataAnnotations; + +namespace EPAServeur.Attributes +{ + /// + /// Specifies that a collection of a specified type must have at least one element. + /// + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)] + public sealed class CannotBeEmptyAttribute : RequiredAttribute + { + public override bool IsValid(object value) + { + var list = value as IEnumerable; + return list != null && list.GetEnumerator().MoveNext(); + } + } +}