diff --git a/README.md b/README.md index e7c4526..2db5c57 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,11 @@ +
+ ---   ![C#](https://img.shields.io/badge/C%23-000?style=for-the-badge&logo=c-sharp&logoColor=white&color=purple)   ![Entity Framework](https://img.shields.io/badge/Entity_Framework-000?style=for-the-badge&logo=.net&logoColor=white&color=blue) @@ -29,7 +31,7 @@
# Table des matières -[Présentation](#présentation) | [Répartition du Git](#répartition-du-git) | [Documentation](#documentation) | [Prérequis](#prerequisites) | [Pour commencer](#getting-started) | [Ce que nous avons fait](#ce-que-nous-avons-fait) | [Fabriqué avec](#fabriqué-avec) | [Contributeurs](#contributeurs) | [Comment contribuer](#comment-contribuer) | [License](#license) | [Remerciements](#remerciements) +[Présentation](#présentation) | [Répartition du Git](#répartition-du-git) | [Documentation](#documentation) | [Prerequisites](#prerequisites) | [Getting Started](#getting-started) | [Features](#features) | [Ce que nous avons fait](#ce-que-nous-avons-fait) | [Fabriqué avec](#fabriqué-avec) | [Contributeurs](#contributeurs) | [Comment contribuer](#comment-contribuer) | [License](#license) | [Remerciements](#remerciements) @@ -48,10 +50,12 @@ Le projet HeartTrack, avec son application HeartTrack, vise à offrir une soluti ## Répartition du Git -[**Sources**](src/) : **Code de l'application** +[**Sources**](Sources/) : **Code de l'application** [**Documents**](docs/Diagramme/README_DIAGRAMMES.md) : **Documentation de l'application et diagrammes** +[**Wiki**](https://codefirst.iut.uca.fr/git/HeartDev/Web/wiki/PHP) : **Wiki de notre projet (attendus PHP)** + --- Le projet HeartTrack utilise un modèle de flux de travail Git (Gitflow) pour organiser le développement. Voici une brève explication des principales branches : @@ -76,56 +80,54 @@ Documentation et informations à propos de `HearthTrack` disponible [ici](https: * [![Git](https://img.shields.io/badge/Versioning-Git-000?style=for-the-badge&logo=git&logoColor=white&color=red)](https://git-scm.com/) ## Getting Started -Lancer le projet via le projet HeartTrackAPI afin de démarrer la base de donnée pour swagger en http. -Les méthodes PUT sont en cours de production. Les autres routes sont finalisés et en cours de tests. ## Ce que nous avons fait ### Entity Framework réalisé | niveau | description | coeff | jalon --- | --- | --- | --- | --- -✅ | ☢️ | Le dépôt doit être accessible par l'enseignant | ☢️ | J1 -✅ | ☢️ | un .gitignore doit exister au premier push | ☢️ | J1 -✅ | 🎬 | les *projets* et les tests compilent | 1 | J1 & J2 -✅ | 🎬 | le projet et le tests s'exécutent sans bug (concernant la partie persistance) | 3 | J1 & J2 -✅ | 🟢 | Transcription du modèle : Modèle vers entités (et inversement) | 2 | J1 -✅ | 🟢 | Requêtes CRUD simples (sur une table) | 1 | J1 -✅ | 🟢 | Utilisation de LINQ to Entities | 2 | J1 -✅ | 🟡 | Injection / indépendance du fournisseur | 1 | J1 -✅ | 🟡 | Requêtes CRUD sur des données complexes (images par exemple) | 2 | J1 -✅ | 🟢 | Tests - Appli Console | 1 | J1 -✅ | 🟢 | Tests - Tests unitaires (avec SQLite in memory) | 2 | J1 -✅ | 🟢 | Tests - Données stubbées et/ou Moq | 1 | J1 -✅ | 🟡 | CI : build, tests, Sonar (doc?) | 1 | J1 -✅ | 🟡 | Utilisation de relations (One-to-One, One-to-Many, Many-to-Many) (+ mapping, TU, Requêtes) | 4 | J1 -✅ | 🟢 | Liens avec le web service | 2 | J1 -✅ | 🟡 | Utilisation d'un *Logger* | 1 | J1 -❌ | 🟡 | Déploiement | 4 | J2 -❌ | 🔴 | Unit of Work / Repository + extras (héritage, accès concurrents...) | 8 | J2 -❌ | 🟢 | Utilisation dans le projet | 2 | J2 -✅ | 🟢 | mon dépôt possède un readme qui apporte quelque chose... | 2 | J2 +[ ] | ☢️ | Le dépôt doit être accessible par l'enseignant | ☢️ | J1 +[ ] | ☢️ | un .gitignore doit exister au premier push | ☢️ | J1 +[ ] | 🎬 | les *projets* et les tests compilent | 1 | J1 & J2 +[ ] | 🎬 | le projet et le tests s'exécutent sans bug (concernant la partie persistance) | 3 | J1 & J2 +[ ] | 🟢 | Transcription du modèle : Modèle vers entités (et inversement) | 2 | J1 +[ ] | 🟢 | Requêtes CRUD simples (sur une table) | 1 | J1 +[ ] | 🟢 | Utilisation de LINQ to Entities | 2 | J1 +[ ] | 🟡 | Injection / indépendance du fournisseur | 1 | J1 +[ ] | 🟡 | Requêtes CRUD sur des données complexes (images par exemple) | 2 | J1 +[ ] | 🟢 | Tests - Appli Console | 1 | J1 +[ ] | 🟢 | Tests - Tests unitaires (avec SQLite in memory) | 2 | J1 +[ ] | 🟢 | Tests - Données stubbées et/ou Moq | 1 | J1 +[ ] | 🟡 | CI : build, tests, Sonar (doc?) | 1 | J1 +[ ] | 🟡 | Utilisation de relations (One-to-One, One-to-Many, Many-to-Many) (+ mapping, TU, Requêtes) | 4 | J1 +[ ] | 🟢 | Liens avec le web service | 2 | J1 +[ ] | 🟡 | Utilisation d'un *Logger* | 1 | J1 +[ ] | 🟡 | Déploiement | 4 | J2 +[ ] | 🔴 | Unit of Work / Repository + extras (héritage, accès concurrents...) | 8 | J2 +[ ] | 🟢 | Utilisation dans le projet | 2 | J2 +[ ] | 🟢 | mon dépôt possède un readme qui apporte quelque chose... | 2 | J2 ### API réalisé | niveau | description | coeff | jalon --- | --- | --- | --- | --- -✅ | ☢️ | Le dépôt doit être accessible par l'enseignant | ☢️ | J1 -✅ | ☢️ | un .gitignore doit exister au premier push | ☢️ | J1 -✅ | 🎬 | les *projets* et les tests compilent | 1 | J1 & J2 -✅ | 🎬 | le projet et le tests s'exécutent sans bug (concernant la partie persistance) | 4 | J1 & J2 -✅ | 🟢 | Modèle <-> DTO | 1 | J1 -✅ | 🟢 | Entities <-> DTO | 1 | J1 -✅ | 🟡 | Authentification | 4 | J1 -✅ | 🟢 | Requêtes GET, PUT, POST, DELETE sur des données simples (1 seul type d'objet en retour, propriétés de types natifs) | 2 | J1 -✅ | 🟡 | Pagination & filtrage | 2 | J1 -✅ | 🟢 | Injection de service | 2 | J1 -✅ | 🟡 | Requêtes GET, PUT, POST, DELETE sur des données complexes (plusieurs données complexes en retour) | 4 | J1 -✅ | 🟢 | Tests - Appli Console (consommation des requêtes) | 4 | J1 -✅ | 🟢 | Tests - Tests unitaires (avec Stub et/ou Moq) | 2 | J1 -✅ | 🟡 | CI : build, tests, Sonar, Documentation (en particulier Swagger avec exemples...) | 1 | J1 -✅ | 🟢 | Liens avec la persistance en base de données | 4 | J1 -✅ | 🟡 | Utilisation d'un *Logger* | 1 | J1 -❌ | 🟡 | Déploiement | 4 | J2 +[ ] | ☢️ | Le dépôt doit être accessible par l'enseignant | ☢️ | J1 +[ ] | ☢️ | un .gitignore doit exister au premier push | ☢️ | J1 +[ ] | 🎬 | les *projets* et les tests compilent | 1 | J1 & J2 +[ ] | 🎬 | le projet et le tests s'exécutent sans bug (concernant la partie persistance) | 4 | J1 & J2 +[ ] | 🟢 | Modèle <-> DTO | 1 | J1 +[ ] | 🟢 | Entities <-> DTO | 1 | J1 +[ ] | 🟡 | Authentification | 4 | J1 +[ ] | 🟢 | Requêtes GET, PUT, POST, DELETE sur des données simples (1 seul type d'objet en retour, propriétés de types natifs) | 2 | J1 +[ ] | 🟡 | Pagination & filtrage | 2 | J1 +[ ] | 🟢 | Injection de service | 2 | J1 +[ ] | 🟡 | Requêtes GET, PUT, POST, DELETE sur des données complexes (plusieurs données complexes en retour) | 4 | J1 +[ ] | 🟢 | Tests - Appli Console (consommation des requêtes) | 4 | J1 +[ ] | 🟢 | Tests - Tests unitaires (avec Stub et/ou Moq) | 2 | J1 +[ ] | 🟡 | CI : build, tests, Sonar, Documentation (en particulier Swagger avec exemples...) | 1 | J1 +[ ] | 🟢 | Liens avec la persistance en base de données | 4 | J1 +[ ] | 🟡 | Utilisation d'un *Logger* | 1 | J1 +[ ] | 🟡 | Déploiement | 4 | J2 ❌ | 🟡 | Utilisation dans le projet | 4 | J2 -✅ | 🎬 | mon dépôt possède un readme qui apporte quelque chose... | 1 | J2 +✅ | 🎬 | mon dépôt possède un readme qui apporte quelque chose... | 1 | J2 ## Fabriqué avec ![.NET](https://img.shields.io/badge/Langage-.NET-000?style=for-the-badge&logo=.net&logoColor=white&color=blue) diff --git a/src/HeartTrack.sln b/src/HeartTrack.sln index a20b9ff..f9c60dd 100644 --- a/src/HeartTrack.sln +++ b/src/HeartTrack.sln @@ -45,6 +45,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTestsModel", "Tests\Uni EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Entities2Dto", "Entities2Dto\Entities2Dto.csproj", "{1B15D383-1DFA-47E8-86EC-AC631B15FBEB}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RepositoriesUnitTest", "Tests\RepositoriesUnitTest\RepositoriesUnitTest.csproj", "{707B1AC4-F896-4270-BC2F-1A589F48979D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebAPIConsoleTests", "Tests\WebAPIConsoleTests\WebAPIConsoleTests.csproj", "{D0EE112F-3151-4C28-A6EC-B1CEC7883FAE}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -123,10 +127,6 @@ Global {508D380F-145C-437E-A7DF-7A17C526B2F3}.Debug|Any CPU.Build.0 = Debug|Any CPU {508D380F-145C-437E-A7DF-7A17C526B2F3}.Release|Any CPU.ActiveCfg = Release|Any CPU {508D380F-145C-437E-A7DF-7A17C526B2F3}.Release|Any CPU.Build.0 = Release|Any CPU - {1B15D383-1DFA-47E8-86EC-AC631B15FBEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1B15D383-1DFA-47E8-86EC-AC631B15FBEB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1B15D383-1DFA-47E8-86EC-AC631B15FBEB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1B15D383-1DFA-47E8-86EC-AC631B15FBEB}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Model/EnumMappeur.cs b/src/Model/EnumMappeur.cs index b939ee9..38ca1a3 100644 --- a/src/Model/EnumMappeur.cs +++ b/src/Model/EnumMappeur.cs @@ -9,6 +9,7 @@ public static class EnumMappeur return value switch { "None" => Shared.AthleteOrderCriteria.None, + "ById" => Shared.AthleteOrderCriteria.ById, "ByUsername" => Shared.AthleteOrderCriteria.ByUsername, "ByFirstName" => Shared.AthleteOrderCriteria.ByFirstName, "ByLastName" => Shared.AthleteOrderCriteria.ByLastName, @@ -17,7 +18,7 @@ public static class EnumMappeur "ByWeight" => Shared.AthleteOrderCriteria.ByWeight, "ByDateOfBirth" => Shared.AthleteOrderCriteria.ByDateOfBirth, "ByEmail" => Shared.AthleteOrderCriteria.ByEmail, - "ByIsCoach" => Shared.AthleteOrderCriteria.ByIsCoach, + "ByRole" => Shared.AthleteOrderCriteria.ByRole, _ => Shared.AthleteOrderCriteria.None }; } diff --git a/src/Shared/AthleteOrderCriteria.cs b/src/Shared/AthleteOrderCriteria.cs index aad08e4..3faa935 100644 --- a/src/Shared/AthleteOrderCriteria.cs +++ b/src/Shared/AthleteOrderCriteria.cs @@ -3,15 +3,16 @@ public enum AthleteOrderCriteria { None, + ById, ByUsername, ByFirstName, ByLastName, + ByEmail, BySexe, ByLenght, ByWeight, ByDateOfBirth, - ByEmail, - ByIsCoach + ByRole } } diff --git a/src/Tests/ConsoleTestEFMapper/Program.cs b/src/Tests/ConsoleTestEFMapper/Program.cs index e5acca0..5079527 100644 --- a/src/Tests/ConsoleTestEFMapper/Program.cs +++ b/src/Tests/ConsoleTestEFMapper/Program.cs @@ -49,7 +49,7 @@ namespace ConsoleTestEFMapper; } Console.WriteLine(); - // // Test de la méthode AddActivity + // Test de la méthode AddActivity Console.WriteLine("Testing AddActivity method..."); var user = new User { diff --git a/src/Tests/RepositoriesUnitTest/ActivityRepository.cs b/src/Tests/RepositoriesUnitTest/ActivityRepository.cs new file mode 100644 index 0000000..a366bfb --- /dev/null +++ b/src/Tests/RepositoriesUnitTest/ActivityRepository.cs @@ -0,0 +1,114 @@ +using Xunit; +using Model2Entities; +using Microsoft.EntityFrameworkCore; +using DbContextLib; +using StubbedContextLib; +using System.Linq; +using Microsoft.Data.Sqlite; +using System; +using EFMappers; +using Shared; +using Model; +using Moq; +using Microsoft.Extensions.Logging; +using Entities; +/* +namespace UnitTestsEntities +{ + public class ActivityRepositoryTests : IClassFixture + { + private readonly DatabaseFixture _fixture; + + public ActivityRepositoryTests(DatabaseFixture fixture) + { + _fixture = fixture; + } + + [Fact] + public async Task GetActivities_ReturnsActivities() + { + var options = new DbContextOptionsBuilder() + .UseSqlite(_fixture._connection) + .Options; + + using (var context = new HeartTrackContext(options)) + { + context.Database.EnsureCreated(); + } + + using (var context = new HeartTrackContext(options)) + { + var repository = new DbDataManager.ActivityRepository(new DbDataManager(context), null); + var activities = await repository.GetActivities(0, 10, ActivityOrderCriteria.None); + + Assert.NotNull(activities); + Assert.Equal(10, activities.Count()); + } + } + [Fact] + public async Task GetActivityByIdAsync_ReturnsCorrectActivity_WhenIdExists() + { + // Arrange + var activityId = 1; + var expectedActivity = new Activity { Id = activityId, Type = "Running" }; + + var mockDataManager = new Mock(); + mockDataManager.Setup(dm => dm.DbContext.ActivitiesSet.SingleOrDefaultAsync(a => a.IdActivity == activityId)) + .ReturnsAsync(expectedActivity.ToEntity()); + + var loggerMock = new Mock>(); + var activityRepository = new DbDataManager.ActivityRepository(mockDataManager.Object, loggerMock.Object); + + // Act + var result = await activityRepository.GetActivityByIdAsync(activityId); + + // Assert + Assert.NotNull(result); + Assert.Equal(expectedActivity.Id, result.Id); + Assert.Equal(expectedActivity.Type, result.Type); + } + + [Fact] + public async Task GetActivityByIdAsync_ReturnsNull_WhenIdDoesNotExist() + { + // Arrange + var activityId = 999; + + var mockDataManager = new Mock(); + mockDataManager.Setup(dm => dm.DbContext.ActivitiesSet.SingleOrDefaultAsync(a => a.IdActivity == activityId)) + .ReturnsAsync((ActivityEntity)null); + + var loggerMock = new Mock>(); + var activityRepository = new DbDataManager.ActivityRepository(mockDataManager.Object, loggerMock.Object); + + // Act + var result = await activityRepository.GetActivityByIdAsync(activityId); + + // Assert + Assert.Null(result); + } + + [Fact] + public async Task AddActivity_SuccessfullyAddsNewActivity() + { + // Arrange + var newActivity = new Activity { Type = "Walking" }; + + var mockDataManager = new Mock(); + mockDataManager.Setup(dm => dm.DbContext.AddItem(It.IsAny())) + .ReturnsAsync(newActivity.ToEntity()); + + var loggerMock = new Mock>(); + var activityRepository = new DbDataManager.ActivityRepository(mockDataManager.Object, loggerMock.Object); + + // Act + var result = await activityRepository.AddActivity(newActivity); + + // Assert + Assert.NotNull(result); + Assert.Equal(newActivity.Type, result.Type); + } + + } +} +*/ diff --git a/src/Tests/RepositoriesUnitTest/GlobalUsings.cs b/src/Tests/RepositoriesUnitTest/GlobalUsings.cs new file mode 100644 index 0000000..8c927eb --- /dev/null +++ b/src/Tests/RepositoriesUnitTest/GlobalUsings.cs @@ -0,0 +1 @@ +global using Xunit; \ No newline at end of file diff --git a/src/Tests/RepositoriesUnitTest/RepositoriesUnitTest.csproj b/src/Tests/RepositoriesUnitTest/RepositoriesUnitTest.csproj new file mode 100644 index 0000000..417f28f --- /dev/null +++ b/src/Tests/RepositoriesUnitTest/RepositoriesUnitTest.csproj @@ -0,0 +1,31 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + diff --git a/src/Tests/RepositoriesUnitTest/UnitTest1.cs b/src/Tests/RepositoriesUnitTest/UnitTest1.cs new file mode 100644 index 0000000..392318c --- /dev/null +++ b/src/Tests/RepositoriesUnitTest/UnitTest1.cs @@ -0,0 +1,10 @@ +namespace RepositoriesUnitTest; + +public class UnitTest1 +{ + [Fact] + public void Test1() + { + + } +} \ No newline at end of file diff --git a/src/Tests/TestApi/GlobalUsings.cs b/src/Tests/TestApi/GlobalUsings.cs deleted file mode 100644 index ab67c7e..0000000 --- a/src/Tests/TestApi/GlobalUsings.cs +++ /dev/null @@ -1 +0,0 @@ -global using Microsoft.VisualStudio.TestTools.UnitTesting; \ No newline at end of file diff --git a/src/Tests/TestApi/TestApi.csproj b/src/Tests/TestApi/TestApi.csproj deleted file mode 100644 index 719074b..0000000 --- a/src/Tests/TestApi/TestApi.csproj +++ /dev/null @@ -1,26 +0,0 @@ - - - - net8.0 - enable - enable - - false - true - - - - - - - - - - - - - - - - - diff --git a/src/Tests/TestApi/UserControllerTest.cs b/src/Tests/TestApi/UserControllerTest.cs deleted file mode 100644 index e69de29..0000000 diff --git a/src/Tests/UnitTestsEntities/DatabaseFixture.cs b/src/Tests/UnitTestsEntities/DatabaseFixture.cs index eaae26d..00dc9bf 100644 --- a/src/Tests/UnitTestsEntities/DatabaseFixture.cs +++ b/src/Tests/UnitTestsEntities/DatabaseFixture.cs @@ -7,7 +7,7 @@ namespace UnitTestsEntities; public class DatabaseFixture : IDisposable { - private readonly SqliteConnection _connection; + public readonly SqliteConnection _connection; public readonly DbContextOptions _options; public DatabaseFixture() { diff --git a/src/Tests/UnitTestsModel/EnumMapperTest.cs b/src/Tests/UnitTestsModel/EnumMapperTest.cs index e2dc382..5d3c0d7 100644 --- a/src/Tests/UnitTestsModel/EnumMapperTest.cs +++ b/src/Tests/UnitTestsModel/EnumMapperTest.cs @@ -17,7 +17,7 @@ namespace UnitTestsModel [InlineData("ByWeight", Shared.AthleteOrderCriteria.ByWeight)] [InlineData("ByDateOfBirth", Shared.AthleteOrderCriteria.ByDateOfBirth)] [InlineData("ByEmail", Shared.AthleteOrderCriteria.ByEmail)] - [InlineData("ByIsCoach", Shared.AthleteOrderCriteria.ByIsCoach)] + [InlineData("ByRole", Shared.AthleteOrderCriteria.ByRole)] [InlineData(null, Shared.AthleteOrderCriteria.None)] [InlineData("InvalidValue", Shared.AthleteOrderCriteria.None)] public void ToEnum_WithValidValue_ReturnsCorrectEnumValue(string? value, Shared.AthleteOrderCriteria expected) diff --git a/src/Tests/WebAPIConsoleTests/ActivityServiceAPI.cs b/src/Tests/WebAPIConsoleTests/ActivityServiceAPI.cs new file mode 100644 index 0000000..976808a --- /dev/null +++ b/src/Tests/WebAPIConsoleTests/ActivityServiceAPI.cs @@ -0,0 +1,113 @@ +/*! + * \file BookDataServiceAPI.cs + * \author HeartTeam + * \brief Fichier contenant la classe BookDataServiceAPI. + */ + +using System.Diagnostics; +using Dto; +using Model.Repository; +using Shared; +using APIMappers; +using Model; + +namespace WebAPIConsoleTests; + +/*! + * \brief Implémentation de l'interface IActivityRepository pour récupérer des activités via un service HTTP. + */ +public class ActivityServiceAPI : IActivityRepository +{ + private HttpRequest myRequest = new HttpRequest(); + + /*! + * \brief Constructeur de la classe ActivityServiceAPI. + * Initialise l'adresse de base du client HTTP. + */ + public ActivityServiceAPI() + { + myRequest.HttpClient.BaseAddress = new Uri("http://localhost:5030/api/v1/Activity/"); + } + + /*! + * \brief Récupère toutes les Activités de manière asynchrone. + * \return Une tâche représentant l'opération asynchrone qui retourne une liste d'Activity. + */ + public async Task?> GetActivities(int index, int count, ActivityOrderCriteria criteria, bool descending = false) + { + var activityDtos = await myRequest.GetAllAsync(); + return activityDtos?.ToModels(); + } + + /*! + * \brief Récupère les activités par index et compte de manière asynchrone. + * \param index L'index de départ pour la pagination. + * \param count Le nombre d'éléments à récupérer. + * \return Une tâche représentant l'opération asynchrone qui retourne une liste d'Activity. + */ + public async Task> GetBooksAsync(ActivityOrderCriteria criteria, bool descending, int index, int count) + { + var activityDtos = await myRequest.GetAsync(criteria, descending, index, count); + return (List)activityDtos.ToModels(); + } + + /*! + * \brief Récupère une activité par son identifiant de manière asynchrone. + * \param id L'identifiant du livre à récupérer. + * \return Une tâche représentant l'opération asynchrone qui retourne une liste d'Activity. + */ + public async Task GetActivityByIdAsync(int id) + { + var activityDtos = await myRequest.GetByIdAsync(id); + return activityDtos.ToModel(); + } + + /*! + * \brief Ajoute une activité de manière asynchrone. + * \param activity L'Activity à ajouter. + * \return Une tâche représentant l'opération asynchrone qui retourne l'activité ajouté (Activity). + */ + public async Task AddActivity(Model.Activity activity) + { + return (await myRequest.PostAsync(activity.ToDto())).ToModel(); + } + + /*! + * \brief Met à jour une activité de manière asynchrone. + * \param id L'identifiant de l'activité à mettre à jour. + * \param activity Les nouvelles données de l'activité à mettre à jour. + * \return Une tâche représentant l'opération asynchrone qui retourne l'activité mis à jour (Activity). + */ + public async Task UpdateActivity(int id, Model.Activity activity) + { + var activityDto = activity.ToDto(); + var updatedActivityDto = await myRequest.PutAsync(id, activityDto); + return updatedActivityDto?.ToModel(); + } + + /*! + * \brief Supprime une activité de manière asynchrone. + * \param id L'identifiant de l'activité à supprimer. + * \return Une tâche représentant l'opération asynchrone. + */ + public async Task DeleteActivity(int id) + { + await myRequest.DeleteAsync(id); + return true; + } + + public Task GetNbItems() + { + return myRequest.GetNbItems(); + } + + public async Task?> GetActivitiesByUser(int userId, int index, int count, ActivityOrderCriteria orderCriteria, bool descending = false) + { + return (await myRequest.GetActivitiesByUser(userId, index, count, orderCriteria, descending)).ToModels(); + } + + public Task GetNbActivitiesByUser(int userId) + { + return myRequest.GetNbActivitiesByUser(userId); + } +} \ No newline at end of file diff --git a/src/Tests/WebAPIConsoleTests/HttpRequest.cs b/src/Tests/WebAPIConsoleTests/HttpRequest.cs new file mode 100644 index 0000000..2b83ab6 --- /dev/null +++ b/src/Tests/WebAPIConsoleTests/HttpRequest.cs @@ -0,0 +1,101 @@ +/*! + * \file HttpRequest.cs + * \brief Fichier contenant la classe HttpRequest. + */ + +using System.Diagnostics; +using System.Net.Http.Json; +using Dto; +using Shared; + +namespace WebAPIConsoleTests; + +/*! + * \brief Classe représentant un client HTTP pour les requêtes vers un service de gestion de elément. + */ +public class HttpRequest where T : class +{ + private HttpClient _httpClient { get; } = new HttpClient(); + public HttpClient HttpClient => _httpClient; + + /*! + * \brief Récupère tous les activitée de manière asynchrone. + * \return Une tâche représentant l'opération asynchrone qui retourne une liste de T. + */ + public async Task> GetAllAsync() + { + return await _httpClient.GetFromJsonAsync>(""); + } + + /*! + * \brief Récupère les élements par index et compte de manière asynchrone. + * \param index L'index de départ pour la pagination. + * \param count Le nombre d'éléments à récupérer. + * \return Une tâche représentant l'opération asynchrone qui retourne une liste de T. + */ + // [TODO] enum + public async Task> GetAsync(Enum criteria, bool descending, int index, int count) + { + return await _httpClient.GetFromJsonAsync>($"?OrderingPropertyName={criteria}&Descending={descending}&Index={index}&Count={count}"); + } + + /*! + * \brief Récupère un elément par son identifiant de manière asynchrone. + * \param id L'identifiant du elément à récupérer. + * \return Une tâche représentant l'opération asynchrone qui retourne une liste de T. + */ + public async Task GetByIdAsync(int id) + { + return await _httpClient.GetFromJsonAsync($"{id}"); + } + + public Task GetNbItems() + { + return _httpClient.GetFromJsonAsync("count"); + } + + public Task?> GetActivitiesByUser(int userId, int index, int count, ActivityOrderCriteria orderCriteria, bool descending = false) + { + return _httpClient.GetFromJsonAsync?>($"?userId={userId}&index={index}&count={count}&orderCriteria={orderCriteria}&descending={descending}"); + } + + public Task GetNbActivitiesByUser(int userId) + { + return _httpClient.GetFromJsonAsync($"count?userId={userId}"); + } + + /*! + * \brief Ajoute une activity de manière asynchrone. + * \param book Le elément à ajouter. + * \return Une tâche représentant l'opération asynchrone qui retourne le activity ajouté (T). + */ + public async Task PostAsync(T activity) + { + var response = await _httpClient.PostAsJsonAsync("", activity); + + return await response.Content.ReadFromJsonAsync(); + } + + /*! + * \brief Met à jour un elément de manière asynchrone. + * \param id L'identifiant du elément à mettre à jour. + * \param book Les nouvelles données du elément à mettre à jour. + * \return Une tâche représentant l'opération asynchrone qui retourne le elément mis à jour (T). + */ + public async Task PutAsync(int id, T activity) + { + var response = await _httpClient.PutAsJsonAsync($"{id}", activity); + + return await response.Content.ReadFromJsonAsync(); + } + + /*! + * \brief Supprime un elément de manière asynchrone. + * \param id L'identifiant du elément à supprimer. + * \return Une tâche représentant l'opération asynchrone. + */ + public async Task DeleteAsync(int id) + { + await _httpClient.DeleteAsync($"{id}"); + } +} \ No newline at end of file diff --git a/src/Tests/WebAPIConsoleTests/Program.cs b/src/Tests/WebAPIConsoleTests/Program.cs new file mode 100644 index 0000000..8db0f5f --- /dev/null +++ b/src/Tests/WebAPIConsoleTests/Program.cs @@ -0,0 +1,66 @@ +using APIMappers; +using Dto; +using Model; +using Model.Repository; +using Shared; +using WebAPIConsoleTests; + + +IActivityRepository myConsoleTest = new ActivityServiceAPI(); + +// defini un delais d'attente du déploiement de l'API +await Task.Delay(5000); + +// Affiche toutes les activités +Console.WriteLine("Affichage de toutes les Activités : "); +var res = await myConsoleTest.GetActivities(0, 10, ActivityOrderCriteria.ByAthleteId, false); +foreach(var myActivity in res) +{ + Console.WriteLine(myActivity.Id + ", " + myActivity.Type + ", " + myActivity.StartTime + ", " + myActivity.EndTime + ", " + myActivity.DataSource + ", " + myActivity.Athlete); +} + +// Affiche les activités par id +Console.WriteLine("Affichage du livre d'id 1 : "); +res = (IEnumerable)await myConsoleTest.GetActivityByIdAsync(1); +foreach (var myActivity in res) +{ + Console.WriteLine(myActivity.Id + ", " + myActivity.Type + ", " + myActivity.StartTime + ", " + myActivity.EndTime + ", " + myActivity.DataSource + ", " + myActivity.Athlete); +} + +// Ajouter une nouvelle activité +Console.WriteLine("Ajout d'un nouveau livre : "); +var newActivity = new ActivityDto { Type = "New Activity", StartTime = DateTime.Now, EndTime = DateTime.Now, DataSource = new DataSourceDto{}, Athlete = new UserDto{ Username = "Hello", FirstName = "feee", Email = "exemple.com", LastName = "dddd", Sexe = "M" } }; +var addedActivity = await myConsoleTest.AddActivity(newActivity.ToModel()); +Console.WriteLine($"Id: {addedActivity.Id}, Type: {addedActivity.Type}, StartTime: {addedActivity.StartTime}, EndTime: {addedActivity.EndTime}, DataSource: {addedActivity.DataSource}, Athlete: {addedActivity.Athlete}"); + +// Mettre à jour l'activity ajouté +Console.WriteLine("Mise à jour du livre ajouté : "); +var activity = await myConsoleTest.UpdateActivity(1, new ActivityDto { Id = 1, Type = "Updated Activity", StartTime = DateTime.Now, EndTime = DateTime.Now, DataSource = new DataSourceDto{}, Athlete = new UserDto{ Username = "Hello", FirstName = "feee", Email = "exemple.com", LastName = "dddd", Sexe = "M" } }.ToModel()); +Console.WriteLine($"Id: {activity.Id}, Type: {activity.Type}, StartTime: {activity.StartTime}, EndTime: {activity.EndTime}, DataSource: {activity.DataSource}, Athlete: {activity.Athlete}"); + +// Supprimer l'activity ajouté +Console.WriteLine("Suppression du livre ajouté : "); +await myConsoleTest.DeleteActivity(newActivity.Id); +res = await myConsoleTest.GetActivities(0, 10, ActivityOrderCriteria.ByAthleteId, false); +foreach (var activity1 in res) +{ + Console.WriteLine(activity1.Id + ", " + activity1.Type + ", " + activity1.StartTime + ", " + activity1.EndTime + ", " + activity1.DataSource + ", " + activity1.Athlete); +} + +// Affiche le nombre d'activités +Console.WriteLine("Affichage du nombre d'activités : "); +var nb = await myConsoleTest.GetNbItems(); +Console.WriteLine(nb); + +// Affiche les activités par utilisateur +Console.WriteLine("Affichage des activités par utilisateur : "); +res = await myConsoleTest.GetActivitiesByUser(1, 0, 10, ActivityOrderCriteria.ByAthleteId, false); +foreach (var activity3 in res) +{ + Console.WriteLine(activity3.Id + ", " + activity3.Type + ", " + activity3.StartTime + ", " + activity3.EndTime + ", " + activity3.DataSource + ", " + activity3.Athlete); +} + +// Affiche le nombre d'activités par utilisateur +Console.WriteLine("Affichage du nombre d'activités par utilisateur : "); +nb = await myConsoleTest.GetNbActivitiesByUser(1); +Console.WriteLine(nb); \ No newline at end of file diff --git a/src/Tests/WebAPIConsoleTests/WebAPIConsoleTests.csproj b/src/Tests/WebAPIConsoleTests/WebAPIConsoleTests.csproj new file mode 100644 index 0000000..8f402c3 --- /dev/null +++ b/src/Tests/WebAPIConsoleTests/WebAPIConsoleTests.csproj @@ -0,0 +1,17 @@ + + + + + + + + + + + Exe + net8.0 + enable + enable + + +