Merge remote-tracking branch 'origin/tests_merging' into final

# Conflicts:
#	README.md
#	src/HeartTrack.sln
#	src/Tests/TestsAPI/UnitTestApi/Controllers/UsersControllerTest.cs
pull/10/head
David D'ALMEIDA 1 year ago
commit 323dbc14e2

@ -6,9 +6,11 @@
</div>
<div align = center>
---
&nbsp; ![C#](https://img.shields.io/badge/C%23-000?style=for-the-badge&logo=c-sharp&logoColor=white&color=purple)
&nbsp; ![Entity Framework](https://img.shields.io/badge/Entity_Framework-000?style=for-the-badge&logo=.net&logoColor=white&color=blue)
@ -29,7 +31,7 @@
</div>
# 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)

@ -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

@ -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
};
}

@ -3,15 +3,16 @@
public enum AthleteOrderCriteria
{
None,
ById,
ByUsername,
ByFirstName,
ByLastName,
ByEmail,
BySexe,
ByLenght,
ByWeight,
ByDateOfBirth,
ByEmail,
ByIsCoach
ByRole
}
}

@ -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
{

@ -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<DatabaseFixture>
{
private readonly DatabaseFixture _fixture;
public ActivityRepositoryTests(DatabaseFixture fixture)
{
_fixture = fixture;
}
[Fact]
public async Task GetActivities_ReturnsActivities()
{
var options = new DbContextOptionsBuilder<HeartTrackContext>()
.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<DbDataManager>();
mockDataManager.Setup(dm => dm.DbContext.ActivitiesSet.SingleOrDefaultAsync(a => a.IdActivity == activityId))
.ReturnsAsync(expectedActivity.ToEntity());
var loggerMock = new Mock<ILogger<DbDataManager>>();
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<DbDataManager>();
mockDataManager.Setup(dm => dm.DbContext.ActivitiesSet.SingleOrDefaultAsync(a => a.IdActivity == activityId))
.ReturnsAsync((ActivityEntity)null);
var loggerMock = new Mock<ILogger<DbDataManager>>();
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<DbDataManager>();
mockDataManager.Setup(dm => dm.DbContext.AddItem(It.IsAny<ActivityEntity>()))
.ReturnsAsync(newActivity.ToEntity());
var loggerMock = new Mock<ILogger<DbDataManager>>();
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);
}
}
}
*/

@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0" />
<PackageReference Include="Moq" Version="4.20.70" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="6.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Model2Entities\Model2Entities.csproj" />
<ProjectReference Include="..\UnitTestsEntities\UnitTestsEntities.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,10 @@
namespace RepositoriesUnitTest;
public class UnitTest1
{
[Fact]
public void Test1()
{
}
}

@ -1 +0,0 @@
global using Microsoft.VisualStudio.TestTools.UnitTesting;

@ -1,26 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0"/>
<PackageReference Include="MSTest.TestAdapter" Version="3.0.4"/>
<PackageReference Include="MSTest.TestFramework" Version="3.0.4"/>
<PackageReference Include="coverlet.collector" Version="6.0.0"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\HeartTrackAPI\HeartTrackAPI.csproj" />
<ProjectReference Include="..\..\Model\Model.csproj" />
<ProjectReference Include="..\..\Shared\Shared.csproj" />
<ProjectReference Include="..\..\StubAPI\StubAPI.csproj" />
</ItemGroup>
</Project>

@ -7,7 +7,7 @@ namespace UnitTestsEntities;
public class DatabaseFixture : IDisposable
{
private readonly SqliteConnection _connection;
public readonly SqliteConnection _connection;
public readonly DbContextOptions<HeartTrackContext> _options;
public DatabaseFixture()
{

@ -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)

@ -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<ActivityDto> myRequest = new HttpRequest<ActivityDto>();
/*!
* \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<IEnumerable<Model.Activity>?> 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<List<Model.Activity>> GetBooksAsync(ActivityOrderCriteria criteria, bool descending, int index, int count)
{
var activityDtos = await myRequest.GetAsync(criteria, descending, index, count);
return (List<Model.Activity>)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<Model.Activity?> 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<Model.Activity?> 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<Model.Activity?> 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<bool> DeleteActivity(int id)
{
await myRequest.DeleteAsync(id);
return true;
}
public Task<int> GetNbItems()
{
return myRequest.GetNbItems();
}
public async Task<IEnumerable<Model.Activity>?> GetActivitiesByUser(int userId, int index, int count, ActivityOrderCriteria orderCriteria, bool descending = false)
{
return (await myRequest.GetActivitiesByUser(userId, index, count, orderCriteria, descending)).ToModels();
}
public Task<int> GetNbActivitiesByUser(int userId)
{
return myRequest.GetNbActivitiesByUser(userId);
}
}

@ -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<T> 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<List<T>> GetAllAsync()
{
return await _httpClient.GetFromJsonAsync<List<T>>("");
}
/*!
* \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<List<T>> GetAsync(Enum criteria, bool descending, int index, int count)
{
return await _httpClient.GetFromJsonAsync<List<T>>($"?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<T?> GetByIdAsync(int id)
{
return await _httpClient.GetFromJsonAsync<T>($"{id}");
}
public Task<int> GetNbItems()
{
return _httpClient.GetFromJsonAsync<int>("count");
}
public Task<IEnumerable<T>?> GetActivitiesByUser(int userId, int index, int count, ActivityOrderCriteria orderCriteria, bool descending = false)
{
return _httpClient.GetFromJsonAsync<IEnumerable<T>?>($"?userId={userId}&index={index}&count={count}&orderCriteria={orderCriteria}&descending={descending}");
}
public Task<int> GetNbActivitiesByUser(int userId)
{
return _httpClient.GetFromJsonAsync<int>($"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<T> PostAsync(T activity)
{
var response = await _httpClient.PostAsJsonAsync("", activity);
return await response.Content.ReadFromJsonAsync<T>();
}
/*!
* \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<T> PutAsync(int id, T activity)
{
var response = await _httpClient.PutAsJsonAsync($"{id}", activity);
return await response.Content.ReadFromJsonAsync<T>();
}
/*!
* \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}");
}
}

@ -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<Model.Activity>)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);

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\..\Dto\Dto.csproj" />
<ProjectReference Include="..\..\Shared\Shared.csproj" />
<ProjectReference Include="..\..\Model\Model.csproj" />
<ProjectReference Include="..\..\APIMappers\APIMappers.csproj" />
</ItemGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
Loading…
Cancel
Save