Merge branch 'master' of https://codefirst.iut.uca.fr/git/corentin.richard/EntityFramework_ConsoDeServices_TP into DevPF
continuous-integration/drone/push Build is passing Details

pull/37/head
Pierre Ferreira 2 years ago
commit f3274ca258

@ -0,0 +1,75 @@
kind: pipeline
type: docker
name: EfCsLoL
trigger:
event:
- push
steps:
- name: build
image: mcr.microsoft.com/dotnet/sdk:6.0
volumes:
- name: docs
path: /docs
commands:
- cd Sources/
- dotnet restore LeagueOfLegends.sln
- dotnet build LeagueOfLegends.sln -c Release --no-restore
- dotnet publish LeagueOfLegends.sln -c Release --no-restore -o CI_PROJECT_DIR/build/release
# docker image build
- name: docker-build-and-push
image: plugins/docker
settings:
dockerfile: Sources/API_LoL/Dockerfile
context: Sources/
registry: hub.codefirst.iut.uca.fr
repo: hub.codefirst.iut.uca.fr/corentin.richard/entityframework_consodeservices_tp
username:
from_secret: SECRET_REGISTRY_USERNAME
password:
from_secret: SECRET_REGISTRY_PASSWORD
# docker test
- name: tests
image: mcr.microsoft.com/dotnet/sdk:6.0
commands:
- cd Sources/
- dotnet restore LeagueOfLegends.sln
- dotnet test LeagueOfLegends.sln --no-restore
depends_on: [docker-build-and-push]
- name: code-analysis
image: hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-dronesonarplugin-dotnet6
commands:
- cd Sources/
- dotnet restore LeagueOfLegends.sln
- dotnet sonarscanner begin /k:entityframework_consodeservices_tp /d:sonar.host.url=$${PLUGIN_SONAR_HOST} /d:sonar.coverageReportPaths="coveragereport/SonarQube.xml" /d:sonar.coverage.exclusions="Tests/**" /d:sonar.login=$${PLUGIN_SONAR_TOKEN}
- dotnet build LeagueOfLegends.sln -c Release --no-restore
- dotnet test LeagueOfLegends.sln --logger trx --no-restore /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura --collect "XPlat Code Coverage"
- reportgenerator -reports:"**/coverage.cobertura.xml" -reporttypes:SonarQube -targetdir:"coveragereport"
- dotnet publish LeagueOfLegends.sln -c Release --no-restore -o CI_PROJECT_DIR/build/release
- dotnet sonarscanner end /d:sonar.login=$${PLUGIN_SONAR_TOKEN}
secrets: [ SECRET_SONAR_LOGIN ]
settings:
# accessible en ligne de commande par ${PLUGIN_SONAR_HOST}
sonar_host: https://codefirst.iut.uca.fr/sonar/
# accessible en ligne de commande par ${PLUGIN_SONAR_TOKEN}
sonar_token:
from_secret: SECRET_SONAR_LOGIN
depends_on: [tests]
# container deployment
- name: deploy-container
image: hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-dockerproxy-clientdrone:latest
environment:
IMAGENAME: hub.codefirst.iut.uca.fr/corentin.richard/entityframework_consodeservices_tp:latest
CONTAINERNAME: entityframework_consodeservices_tp
COMMAND: create
OVERWRITE: true
ADMIN: corentinrichard,pierreferreira
depends_on: [ code-analysis, docker-build-and-push ]

@ -1,3 +1,108 @@
# Projet d'Entity FrameWork et Consomation et Développement de services
Notre projet à pour objectif la liaison entre une base de donnée et un client, par l'utilisation d' ``EntityFramework`` et d'une ``API`` C# créé par nous même.
![C#](https://img.shields.io/badge/c%23-%23239120.svg?style=for-the-badge&logo=c-sharp&logoColor=white)
![JWT](https://img.shields.io/badge/JWT-black?style=for-the-badge&logo=JSON%20web%20tokens)
![Markdown](https://img.shields.io/badge/markdown-%23000000.svg?style=for-the-badge&logo=markdown&logoColor=white)
> *A noter que seul la v1 est prise en compte, la v2 et v2.2 ne sont presentes uniquement pour prouver notre capacité à versionner*
Ce projet est decoupé en deux parties :
## :alien: Consomation et Développement de services :construction_worker:
#### :steam_locomotive: Comment lancer le projet ?
> (Explication...) :construction:
#### :checkered_flag: État des livrables :
:construction:
> * :heavy_check_mark: Mise en place de toutes les opérations CRUD
> * :heavy_check_mark: API RESTful (respect des règles de routage, utilisation des bons status code ...)
> * :heavy_exclamation_mark: Utilisation des fichiers configurations
> * :heavy_check_mark: Versionnage de l'api (avec versionnage de la doc)
> * :heavy_check_mark: Logs
> * :heavy_check_mark: Tests unitaires
> * :heavy_exclamation_mark: Réalisation du client MAUI et liaison avec l'api
> * :heavy_check_mark:Liaison avec la base de données
> * :heavy_check_mark:Filtrage + Pagination des données
> * :construction: Propreté du code (Vous pouvez vous servir de sonarqube)
> * :heavy_check_mark: Dockerisation et Hébergement des API (CodeFirst)
> * :heavy_exclamation_mark: Sécurité
> * :heavy_check_mark: Utilisation SonarQube
[![Build Status](https://codefirst.iut.uca.fr/api/badges/corentin.richard/EntityFramework_ConsoDeServices_TP/status.svg)](https://codefirst.iut.uca.fr/corentin.richard/EntityFramework_ConsoDeServices_TP)
#### Diagramme d'architechture :
=> Disponible à `./Diagramme d'architecture.jpg`
---
## :package: Entity FrameWork :construction_worker:
:construction:
#### :checkered_flag: État des livrables :
Partie 1 :
* Exo1 : :construction:
une base de données
une table de champion
utilisation du client console/mobile
requetes CRUD (+ tri, filtrage)
* Exo2 : :heavy_check_mark:
UT
Base de données stubbée
SQLiteInMemory
* Exo3 : :heavy_check_mark:
Déploiement EF et tests via code#0
---
Partie 2 :
* Exo4 : :heavy_check_mark:
implémentation des runes et skins (1 table -> pas de relation)
* Exo5 : :heavy_check_mark:
Relation entre champion et skin (OneToMany)
* Exo6 : :heavy_check_mark:
Relation entre Champion, RunePage et Rune (ManyToMany)
> La relation entre Rune et RunePage à été simplifiée par manque de temps, il ne s'agit donc pas d'un dictionaire mais d'un OneToMany.
* Exo7 : :heavy_check_mark:
mapping entre model et entité (intégration de qualité)
(en 1 table et avec relations)
* Exo8 : :heavy_exclamation_mark:
Ajouter le paterne UnitOfWork (rollback en cas de probleme sur les transaction)
---
## Explication de ce qu'on a fait et ce qu'on a pas fait et pourquoi on a priorisé ca plutot que d'autre :
:construction:
## Coordonnées :
``Corentin Richard`` : **[corentin.richard@etu.uca.fr](https://codefirst.iut.uca.fr/git/corentin.richard)**
``Pierre Ferreira`` : **[pierre.ferreira@etu.uca.fr](https://codefirst.iut.uca.fr/git/pierre.ferreira)**
---
# Sujet principal :
---
# prepaLoL
## Diagramme de classes du modèle

@ -0,0 +1,4 @@
[*.cs]
# CS8604: Possible null reference argument.
dotnet_diagnostic.CS8604.severity = none

@ -1,20 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>1c8da478-3029-41d1-b936-853a71a8b812</UserSecretsId>
<DockerDefaultTargetOS>Windows</DockerDefaultTargetOS>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="5.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.17.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DTO\DTO.csproj" />
<ProjectReference Include="..\EntityFramework\EntityFramework.csproj" />
<ProjectReference Include="..\Model\Model.csproj" />
<ProjectReference Include="..\StubLib\StubLib.csproj" />
</ItemGroup>

@ -3,61 +3,242 @@ using Model;
using StubLib;
using DTO;
using DTO.Mapper;
using System.CodeDom.Compiler;
using System.Drawing;
using System;
using API_LoL.Mapper;
using System.Xml.Linq;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using System.Reflection.PortableExecutable;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
namespace API_LoL.Controllers
{
[Route("api/[controller]")]
//[Route("api/[controller]")]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiController]
public class ChampionsController : ControllerBase
{
private StubData.ChampionsManager ChampionsManager { get; set; } = new StubData.ChampionsManager(new StubData());
// GET: api/<ChampionController>
public ChampionsController(IDataManager Manager) {
this._logger = LoggerFactory.Create(builder => builder.AddConsole()).CreateLogger<ChampionsController>();
this.ChampionsManager = Manager.ChampionsMgr;
this.SkinsManager = Manager.SkinsMgr;
}
private IChampionsManager ChampionsManager;
private ISkinsManager SkinsManager;
//private StubData stubData;
private ILogger logger;
private readonly ILogger _logger;
// GET api/<ChampionController>/5
[HttpGet("count")]
public async Task<IActionResult> GetCount()
{
_logger.LogInformation(message: "count returned", "Get", "/Champion/Count", 200, DateTime.Now);
return Ok(ChampionsManager.GetNbItems());
}
[HttpGet]
public async Task<IActionResult> Get()
public async Task<IActionResult> Get(string? name = null,String? skill = null, String? characteristic = null,int index = 0,int size =10)
{
var list = await ChampionsManager.GetItems(0,await ChampionsManager.GetNbItems());
if (list.Count<Champion>() == 0) {
return Ok(list.Select(champion => champion?.toDTO()));
}else {
return NoContent();
if (size - index > 10)
{
_logger.LogError(message : "Oversized","Get","/Champion",400,"name : "+name,"skill : "+skill,"characteristics : "+characteristic,"index : "+index,"size : "+size,DateTime.Now);
return BadRequest();
}
if (!string.IsNullOrEmpty(name))
{
var list = await ChampionsManager.GetItemsByName(name, index, size);
if (list.Count() != 0)
{
_logger.LogInformation(message: "Champion returned by name", "Get", "/Champion", 200, "name : " + name, "skill : " + skill, "characteristic : " + characteristic, "index : " + index, "size : " + size, DateTime.Now);
return Ok(list.Select(champion => champion?.ToDTO()));
}
else {
_logger.LogInformation(message: "No Champion found by name", "Get", "/Champion", 204, "name : " + name, "skill : " + skill, "characteristic : " + characteristic, "index : " + index, "size : " + size, DateTime.Now);
return NoContent(); }
}
else if(!string.IsNullOrEmpty(skill)) {
var list = await ChampionsManager.GetItemsBySkill(skill, index, size);
if (list.Count() != 0)
{
_logger.LogInformation(message: "Champion returned by skill", "Get", "/Champion", 200, "name : " + name, "skill : " + skill, "characteristic : " + characteristic, "index : " + index, "size : " + size, DateTime.Now);
return Ok(list.Select(champion => champion?.ToDTO()));
}
else {
_logger.LogInformation(message: "No Champion found by skill", "Get", "/Champion", 204, "name : " + name, "skill : " + skill, "characteristic : " + characteristic, "index : " + index, "size : " + size, DateTime.Now);
return NoContent(); }
}
else if(!string.IsNullOrEmpty (characteristic)) {
var list = await ChampionsManager.GetItems(index, size);
if (list.Count() != 0)
{
_logger.LogInformation(message: "Champion returned by characteristic", "Get", "/Champion", 200, "name : " + name, "skill : " + skill, "characteristic : " + characteristic, "index : " + index, "size : " + size, DateTime.Now);
return Ok(list.Select(champion => champion?.ToDTO()));
}
else {
_logger.LogInformation(message: "No Champion found by char", "Get", "/Champion", 204, "name : " + name, "skill : " + skill, "characteristic : " + characteristic, "index : " + index, "size : " + size, DateTime.Now);
return NoContent(); }
}
else {
var list = await ChampionsManager.GetItems(index, size);
if (list.Count() != 0)
{
_logger.LogInformation(message: "Champion returned default", "Get", "/Champion", 200, "name : " + name, "skill : " + skill, "characteristic : " + characteristic, "index : " + index, "size : " + size, DateTime.Now);
return Ok(list.Select(champion => champion?.ToDTO()));
}
else {
_logger.LogInformation(message: "No Champion found Default", "Get", "/Champion", 204, "name : " + name,"skill : " + skill,"characteristic : "+ characteristic,"index : "+index,"size : "+size, DateTime.Now);
return NoContent();
}
}
}
// GET api/<ChampionController>/5
[HttpGet("{id}")]
public string Get(String name)
[HttpGet("name")]
public async Task<IActionResult> GetByName(String name)
{
return "value";
if (string.IsNullOrEmpty(name))
{
_logger.LogError(message: "No paramater given", "Get", "/Champion/Name", 400, "name : " + name, DateTime.Now);
return BadRequest();
}
var list = await ChampionsManager.GetItemsByName(name, 0, 1);
if (list.Count() == 1)
{
_logger.LogInformation(message: "Champion found", "Get", "/Champion/Name", 20, "name : " + name, DateTime.Now);
return Ok(list.Select(champion => champion?.ToDTO()).First());
}
else {
_logger.LogInformation(message: "No Champion found", "Get", "/Champion/Name", 204, "name : " + name, DateTime.Now);
return NoContent();
}
}
[HttpGet("name/skins")]
public async Task<IActionResult> GetSkinsByName(String name)
{
if (string.IsNullOrEmpty(name))
{
_logger.LogError(message: "No paramater given", "Get", "/Champion/Name/Skins", 400, "name : " + name, DateTime.Now);
return BadRequest();
}
var list = await ChampionsManager.GetItemsByName(name, 0, 1);
if (list.Count() == 1)
{
var nb = await SkinsManager.GetNbItemsByChampion(list.First());
if (nb != 0)
{
var skins = await SkinsManager.GetItemsByChampion(list.First(), 0, nb);
return Ok(skins.Select(skin => skin?.ToDTO()));
}
else {
_logger.LogInformation(message: "No Skin found found", "Get", "/Champion/Name/Skins", 204, "name : " + name, DateTime.Now);
return NoContent(); }
}
else {
_logger.LogInformation(message: "No Champion found", "Get", "/Champion/Name/Skins", 204, "name : " + name, DateTime.Now);
return NoContent();
}
}
//[HttpGet("name/skills")]
//public async Task<IActionResult> GetSkillsByName(String name)
//{
// if (string.IsNullOrEmpty(name)) return BadRequest();
// var list = await ChampionsManager.GetItemsByName(name, 0, 1);
// if (list.Count() == 1)
// {
// var skins = await SkinsManager.GetItemsByChampion(list.First(), 0, await SkinsManager.GetNbItemsByChampion(list.First()));
// if (skins.Count() != 0)
// {
// return Ok(skins.Select(skin => skin?.ToDTO()));
// }
// else { return NoContent(); }
// }
// else { return NoContent(); }
//}
// POST api/<ChampionController>
[HttpPost]
public async Task<IActionResult> Post(ChampionDTO champion)
{
if (champion == null)
{
_logger.LogError(message: "Null paramater given", "Post", "/Champion", 422, "champion : " + champion.toString, DateTime.Now);
return UnprocessableEntity();
}
else
{
//ChampionsManager.AddItem(champion)
return CreatedAtAction("Post",champion.Name);
var list = await ChampionsManager.GetItemsByName(champion.Name, 0, 1);
Champion champ = list.FirstOrDefault();
if (champ != null)
{
if(champ.Name == champion.Name)
{
_logger.LogError(message: "Champion with this id already exists", "Post", "/Champion", 409, "champion : " + champion.toString, DateTime.Now);
return Conflict(champion);
}
}
await ChampionsManager.AddItem(champion.ToChampion());
_logger.LogInformation(message: "Champion created", "Post", "Champion/Name", 201, "champion : " + champion.toString, DateTime.Now);
return CreatedAtAction("Post",champion);
}
}
// PUT api/<ChampionController>/5
[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
[HttpPut("name")]
public async Task<IActionResult> Put(string name, ChampionDTO championDTO)
{
if (string.IsNullOrEmpty(name))
{
_logger.LogError(message: "Null paramater given for Name", "Put", "/Champion/Name", 400,"name : "+name, "champion : " + championDTO.toString, DateTime.Now);
return BadRequest();
}
if(championDTO == null)
{
_logger.LogError(message: "Null paramater given for Champion", "Put", "/Champion/Name", 422, "name : " + name, "champion : " + championDTO.toString, DateTime.Now);
return UnprocessableEntity();
}
var list = await ChampionsManager.GetItemsByName(name, 0, 1);
if (list.Count() == 1)
{
_logger.LogInformation(message: "Champion updated", "Put", "Champion/Name", 200, "name : " + name, "champion : " + championDTO.toString, DateTime.Now);
return Ok(ChampionsManager.UpdateItem(list.First(), championDTO.ToChampion()));
}
else {
_logger.LogInformation(message: "No champion Found", "Put", "/Champion/Name", 204, "name : " + name, "champion : " + championDTO.toString, DateTime.Now);
return NoContent();
}
}
// DELETE api/<ChampionController>/5
[HttpDelete("{id}")]
public void Delete(int id)
[HttpDelete("name")]
public async Task<IActionResult> Delete(string name)
{
if (string.IsNullOrEmpty(name))
{
_logger.LogError(message: "Null paramater given for Name", "Delete", "/Champion/Name", 400, "name : " + name, DateTime.Now);
return BadRequest();
}
var list = await ChampionsManager.GetItemsByName(name, 0, 1);
if(list.Count() == 1){
_logger.LogInformation(message: "Champion Deleted", "Delete", "/Champion/Name", 200, "name : " + name, DateTime.Now);
return Ok(await ChampionsManager.DeleteItem(list.First()));
}else {
_logger.LogInformation(message: "No champion Found", "Delete", "/Champion/Name", 204, "name : " + name, DateTime.Now);
return NoContent(); }
}
}
}

@ -0,0 +1,108 @@
using Microsoft.AspNetCore.Mvc;
using Model;
using StubLib;
using DTO;
using DTO.Mapper;
using System.CodeDom.Compiler;
namespace API_LoL.Controllers
{
[ApiVersion("2.0")]
[ApiVersion("2.2")]
[Route("api/v{version:apiVersion}/versioned")]
[ApiController]
public class ChampionsControllerVersioned : ControllerBase
{
public ChampionsControllerVersioned(IDataManager Manager)
{
this.ChampionsManager = Manager.ChampionsMgr;
}
private IChampionsManager ChampionsManager;
// GET api/<ChampionController>/5
//[HttpGet]
//public async Task<IActionResult> Get(String? name = null, String? skill = null, String? characteristic = null, int index = 0, int size = 10)
//{
// if (size - index > 10)
// {
// return BadRequest();
// }
// if (!string.IsNullOrEmpty(name))
// {
// var list = await ChampionsManager.GetItemsByName(name, index, size);
// if (list.Count() != 0)
// {
// return Ok(list.Select(champion => champion?.ToDTO()));
// }
// else { return NoContent(); }
// }
// else if (!string.IsNullOrEmpty(skill))
// {
// var list = await ChampionsManager.GetItemsBySkill(skill, index, size);
// if (list.Count() != 0)
// {
// return Ok(list.Select(champion => champion?.ToDTO()));
// }
// else { return NoContent(); }
// }
// else if (!string.IsNullOrEmpty(characteristic))
// {
// var list = await ChampionsManager.GetItems(index, size);
// if (list.Count() != 0)
// {
// return Ok(list.Select(champion => champion?.ToDTO()));
// }
// else { return NoContent(); }
// }
// else
// {
// var list = await ChampionsManager.GetItems(index, size);
// if (list.Count() != 0)
// {
// return Ok(list.Select(champion => champion?.ToDTO()));
// }
// else { return NoContent(); }
// }
//}
//// POST api/<ChampionController>
//[HttpPost]
//public async Task<IActionResult> Post(ChampionDTO champion)
//{
// if (champion == null)
// {
// return UnprocessableEntity();
// }
// else
// {
// await ChampionsManager.AddItem(champion.ToChampion());
// return CreatedAtAction("Post", champion);
// }
//}
//// PUT api/<ChampionController>/5
//[HttpPut("{id}")]
//public void Put(int id, [FromBody] string value)
//{
//}
//// DELETE api/<ChampionController>/5
//[HttpDelete("{id}")]
//public void Delete(int id)
//{
//}
///---------- Versioning ----------///
[HttpGet, MapToApiVersion("2.0")]
public string GetThatOnlySayHello() => "Hello v2.0!";
//! FIXME : not working, mais avec la version 2.0 ca marche !
[HttpGet, MapToApiVersion("2.2")]
public string GetThatOnlySayHelloV2() => "Hello but i'm from v2.2!";
}
}

@ -1,8 +1,5 @@
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
#Depending on the operating system of the host machines(s) that will build or run the containers, the image specified in the FROM statement may need to be changed.
#For more information, please see https://aka.ms/containercompat
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
@ -11,6 +8,10 @@ EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["API_LoL/API_LoL.csproj", "API_LoL/"]
COPY ["DTO/DTO.csproj", "DTO/"]
COPY ["Model/Model.csproj", "Model/"]
COPY ["Shared/Shared.csproj", "Shared/"]
COPY ["StubLib/StubLib.csproj", "StubLib/"]
RUN dotnet restore "API_LoL/API_LoL.csproj"
COPY . .
WORKDIR "/src/API_LoL"

@ -0,0 +1,25 @@
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
#Depending on the operating system of the host machines(s) that will build or run the containers, the image specified in the FROM statement may need to be changed.
#For more information, please see https://aka.ms/containercompat
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["API_LoL/API_LoL.csproj", "API_LoL/"]
RUN dotnet restore "API_LoL/API_LoL.csproj"
COPY . .
WORKDIR "/src/API_LoL"
RUN dotnet build "API_LoL.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "API_LoL.csproj" -c Release -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "API_LoL.dll"]

@ -0,0 +1,34 @@
using DTO;
using Model;
namespace API_LoL.Mapper
{
public static class ChampionClassMapper
{
public static string ToDTO(this ChampionClass championClass)
{
return championClass.ToString();
}
public static ChampionClass ToChampionClass(this String championClass)
{
switch (championClass)
{
case "Assassin":
return ChampionClass.Assassin;
case "Fighter":
return ChampionClass.Fighter;
case "Mage":
return ChampionClass.Mage;
case "Marksman":
return ChampionClass.Marksman;
case "Support":
return ChampionClass.Support;
case "Tank":
return ChampionClass.Tank;
default:
return ChampionClass.Unknown;
}
}
}
}

@ -1,4 +1,5 @@
using Model;
using API_LoL.Mapper;
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
@ -9,13 +10,15 @@ namespace DTO.Mapper
{
public static class ChampionMapper
{
public static ChampionDTO toDTO(this Champion champion)
public static ChampionDTO ToDTO(this Champion champion)
{
return new ChampionDTO()
{
Name = champion.Name,
Bio = champion.Bio,
};
return new ChampionDTO(champion.Name, champion.Bio, champion.Icon, champion.Class.ToDTO(), champion.Image.Base64);
}
public static Champion ToChampion(this ChampionDTO champion)
{
return new Champion(champion.Name, champClass: champion.Class.ToChampionClass(),icon: champion.Icon,bio: champion.Bio,image :champion.Image);
}
}
}

@ -0,0 +1,18 @@
using DTO;
using Model;
namespace API_LoL.Mapper
{
public static class SkinMapper
{
public static SkinDTO ToDTO(this Skin skin)
{
return new SkinDTO(skin.Name, skin.Description, skin.Icon,skin.Image.Base64,skin.Price);
}
public static Skin ToSkin(this SkinDTO skin)
{
return new Skin(skin.Name, null,price: skin.Price, icon:skin.Icon,image: skin.Image,description: skin.Description) ;
}
}
}

@ -1,19 +1,79 @@
using API_LoL;
using EntityFramework;
using EntityFramework.Manager;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.AspNetCore.Mvc.Versioning;
using Microsoft.Extensions.Logging;
using Model;
using StubLib;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
//Versioning
///NOT WORKING WHEN CHANGING VERSIONS :
/// voir sur https://blog.christian-schou.dk/how-to-use-api-versioning-in-net-core-web-api/ rubrique "Configure SwaggerOptions"
/// (mais requiere l'injection de d<>pendance).
/// Sinon, code plus simple disponible par le prof
// Add ApiExplorer to discover versions
builder.Services.AddVersionedApiExplorer(setup =>
{
setup.GroupNameFormat = "'v'VVV";
setup.SubstituteApiVersionInUrl = true;
});
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.ConfigureOptions<ConfigureSwaggerOptions>();
builder.Services.AddApiVersioning(o => o.ApiVersionReader = new UrlSegmentApiVersionReader());
// Add services to the container.
builder.Services.AddControllers();
//builder.Services.AddScoped<IDataManager,StubData>();
builder.Services.AddHttpClient();
//builder.Services.AddScoped<IDataManager,StubData>();
builder.Services.AddScoped<IDataManager,EFDataManager>();
builder.Services.AddDbContext<LoLDBContextWithStub>();
var app = builder.Build();
using(var scope = app.Services.CreateScope())
{
var context = scope.ServiceProvider.GetService<LoLDBContextWithStub>();
context.Database.EnsureCreated();
}
var apiVersionDescriptionProvider = app.Services.GetRequiredService<IApiVersionDescriptionProvider>();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
app.UseSwaggerUI(options =>
{
foreach (var description in apiVersionDescriptionProvider.ApiVersionDescriptions)
{
options.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json",
description.GroupName.ToUpperInvariant());
}
});
}
app.UseHttpsRedirection();

@ -0,0 +1,61 @@
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace API_LoL
{
public class ConfigureSwaggerOptions : IConfigureNamedOptions<SwaggerGenOptions>
{
private readonly IApiVersionDescriptionProvider _provider;
public ConfigureSwaggerOptions(IApiVersionDescriptionProvider provider)
{
_provider = provider;
}
/// <summary>
/// Configure each API discovered for Swagger Documentation
/// </summary>
/// <param name="options"></param>
public void Configure(SwaggerGenOptions options)
{
// add swagger document for every API version discovered
foreach (var description in _provider.ApiVersionDescriptions)
{
options.SwaggerDoc(description.GroupName, CreateVersionInfo(description));
}
}
/// <summary>
/// Configure Swagger Options. Inherited from the Interface
/// </summary>
/// <param name="name"></param>
/// <param name="options"></param>
public void Configure(string name, SwaggerGenOptions options)
{
Configure(options);
}
/// <summary>
/// Create information about the version of the API
/// </summary>
/// <param name="description"></param>
/// <returns>Information about the API</returns>
private OpenApiInfo CreateVersionInfo(ApiVersionDescription desc)
{
var info = new OpenApiInfo()
{
Title = ".NET Core (.NET 6) Web API",
Version = desc.ApiVersion.ToString()
};
if (desc.IsDeprecated)
{
info.Description += " This API version has been deprecated. Please use one of the new APIs available from the explorer.";
}
return info;
}
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -1 +0,0 @@
// See https://aka.ms/new-console-template for more information

@ -0,0 +1,34 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.9.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
<PackageReference Include="coverlet.collector" Version="3.1.2" />
<PackageReference Include="xunit.extensibility.core" Version="2.4.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\API_LoL\API_LoL.csproj" />
<ProjectReference Include="..\DTO\DTO.csproj" />
<ProjectReference Include="..\EntityFramework\EntityFramework.csproj" />
<ProjectReference Include="..\Model\Model.csproj" />
<ProjectReference Include="..\StubLib\StubLib.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,88 @@
using API_LoL.Controllers;
using DTO;
using FluentAssertions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.Extensions.Logging;
using Model;
using StubLib;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
namespace Api_UT
{
[TestClass]
public class ChampionControllerTest
{
ChampionsController api = new ChampionsController(new StubData());
[TestMethod]
public async Task Get_Default_OkList()
{
List<ChampionDTO> list = new List<ChampionDTO> {new ChampionDTO("Akali","","","Assassin",""), new ChampionDTO("Aatrox", "", "", "Fighter",""), new ChampionDTO("Ahri", "", "", "Mage",""), new ChampionDTO("Akshan", "", "", "Marksman",""), new ChampionDTO("Bard", "", "","Support",""), new ChampionDTO("Alistar", "", "","Tank","") };
IActionResult a = await api.Get();
a.Should().NotBeNull();
var aObject = a as OkObjectResult;
aObject.Should().NotBeNull();
var championresult = aObject.Value as IEnumerable<ChampionDTO>;
list.Should().BeEquivalentTo(championresult);
}
[TestMethod]
public async Task Get_MoreThanLimit_BadRequest()
{
IActionResult a = await api.Get(index :0,size :11);
a.Should().NotBeNull();
a.Should().BeOfType<BadRequestResult>();
}
[TestMethod]
public async Task Get_2First_OkListOf2()
{
List<ChampionDTO> list = new List<ChampionDTO> { new ChampionDTO("Akali", "", "", "Assassin",""), new ChampionDTO("Aatrox", "", "", "Fighter","") };
IActionResult a = await api.Get(index: 0,size: 2);
a.Should().NotBeNull();
a.Should().BeOfType<OkObjectResult>();
var aObject = a as OkObjectResult;
aObject.Should().NotBeNull();
var championresult = aObject.Value as IEnumerable<ChampionDTO>;
list.Should().BeEquivalentTo(championresult);
}
[TestMethod]
public async Task Get_FilterAName_OkListOf5()
{
List<ChampionDTO> list = new List<ChampionDTO> { new ChampionDTO("Akali", "", "", "Assassin", ""), new ChampionDTO("Akshan", "", "", "Marksman", "") };
IActionResult a = await api.Get(name: "Ak");
a.Should().NotBeNull();
a.Should().BeOfType<OkObjectResult>();
var aObject = a as OkObjectResult;
aObject.Should().NotBeNull();
var championresult = aObject.Value as IEnumerable<ChampionDTO>;
list.Should().BeEquivalentTo(championresult);
}
[TestMethod]
public async Task Post_ValidChampion_Created()
{
ChampionsController api = new ChampionsController(new StubData());
IActionResult a = await api.Post(new ChampionDTO("nom","bio","icon", "Assassin",""));
var action = (CreatedAtActionResult)a;
var champAction = action.Value as IEnumerable<ChampionDTO>;
Assert.IsNotNull(a);
ChampionDTO champ = new ChampionDTO("nom", "bio", "icon","Assassin", "");
Assert.IsTrue(champ.equals(other: (ChampionDTO)((CreatedAtActionResult)a).Value));
}
}
}

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

@ -7,4 +7,9 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\HttpClient\HttpClient.csproj" />
<ProjectReference Include="..\Model\Model.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,44 @@

using ConsoleApplication;
using EntityFramework;
using HttpClient;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Model;
var builder = WebApplication.CreateBuilder();
builder.Services.AddDbContext<LoLDBContextWithStub>();
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
var context = scope.ServiceProvider.GetService<LoLDBContextWithStub>();
context.Database.EnsureCreated();
}
IDataManager dataManager = new HttpClientManager();
string choice = "0";
while (choice != "9")
{
Utils.showMainMenu();
choice = Console.ReadLine();
switch (choice)
{
case "1":
{
Utils.championMenu(dataManager.ChampionsMgr);
break;
}
case "2":
{
//Utils.
break;
}
}
}

@ -0,0 +1,55 @@
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication
{
public static class Utils
{
public static void showMainMenu()
{
Console.WriteLine("-------- Menu -------");
Console.WriteLine(" 1 - Champions ");
Console.WriteLine(" 2 - Skills ");
Console.WriteLine("\n 9 - Quitter");
}
public static void showChampionMenu()
{
Console.WriteLine("-------- Champion -------");
Console.WriteLine(" 1 - Count ");
Console.WriteLine(" 2 - Default ");
Console.WriteLine("\n 9 - Quitter");
}
public static async void championMenu(IChampionsManager championsManager ) {
string choix = "0";
while (choix != "9")
{
Utils.showChampionMenu();
choix = Console.ReadLine();
switch (choix)
{
case "1":
//Console.WriteLine("# result : "+ await championsManager.GetNbItems());
break;
case "2":
var list = await championsManager.GetItems(0, 10);
foreach(var cham in list)
{
Console.WriteLine("# result : " +cham.ToString());
}
break;
}
}
}
}
}

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DTO\DTO.csproj" />
<ProjectReference Include="..\Model\Model.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,194 @@
// See https://aka.ms/new-console-template for more information
using System.Net.Security;
using Model;
using System.Net.Http;
using System.Reflection.Metadata;
using Newtonsoft.Json;
using DTO;
using System.Text.Json;
using Microsoft.AspNetCore.Mvc;
using System.Net.Http.Json;
class APIResponse
{
public string status { get; set; }
public List<string> champions { get; set; }
}
static class Program
{
static HttpClient client = new HttpClient();
static async Task Main(string[] args) {
HttpClient client = new HttpClient();
await DisplayMainMenu();
}
public static async Task DisplayMainMenu()
{
Dictionary<int, string> choices = new Dictionary<int, string>()
{
[1] = "1- Manage Champions",
[2] = "2- Manage Skins",
[3] = "3- Manage Runes",
[4] = "4- Manage Rune Pages",
[99] = "99- Quit"
};
while (true)
{
int input = DisplayAMenu(choices);
switch (input)
{
case 1:
await DisplayChampionsMenu();
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 99:
Console.WriteLine("Bye bye!");
return;
default:
break;
}
}
}
private static int DisplayAMenu(Dictionary<int, string> choices)
{
int input = -1;
while (true)
{
Console.WriteLine("What is your choice?");
Console.WriteLine("--------------------");
foreach (var choice in choices.OrderBy(kvp => kvp.Key).Select(kvp => kvp.Value))
{
Console.WriteLine(choice);
}
if (!int.TryParse(Console.ReadLine(), out input) || input == -1)
{
Console.WriteLine("I do not understand what your choice is. Please try again.");
continue;
}
break;
}
Console.WriteLine($"You have chosen: {choices[input]}");
Console.WriteLine();
return input;
}
public static async Task DisplayChampionsMenu()
{
Dictionary<int, string> choices = new Dictionary<int, string>()
{
[0] = "0- Get number of champions",
[1] = "1- Get champions",
[2] = "2- Find champions by name",
[3] = "3- Find champions by characteristic",
[4] = "4- Find champions by class",
[5] = "5- Find champions by skill",
[6] = "6- Add new champion",
[7] = "7- Delete a champion",
[8] = "8- Update a champion",
};
int input = DisplayAMenu(choices);
switch (input)
{
case 0:
case 1:
{
var response = await client.GetFromJsonAsync<Object>(
"https://localhost:7144/api/Champions");
Console.WriteLine(response.ToString());
string? json = response.ToString();
List<ChampionDTO> f = System.Text.Json.JsonSerializer.Deserialize<List<ChampionDTO>>(json: json);
foreach(var c in f)
{
Console.WriteLine(c.ToString());
}
}
break;
case 2:
{
}
break;
case 3:
{
}
break;
case 4:
{
}
break;
case 5:
{
}
break;
case 6:
{
}
break;
case 7:
{
}
break;
case 8:
{
}
break;
default:
break;
}
}
public static void DisplayCreationChampionMenu(Champion champion)
{
Dictionary<int, string> choices = new Dictionary<int, string>()
{
[1] = "1- Add a skill",
[2] = "2- Add a skin",
[3] = "3- Add a characteristic",
[99] = "99- Finish"
};
while (true)
{
int input = DisplayAMenu(choices);
switch (input)
{
case 1:
case 2:
case 3:
case 99:
return;
default:
break;
}
}
}
}

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DTO
{
public class ChampionClassDTO
{
public string Name;
public ChampionClassDTO(string name) {
this.Name = name;
}
}
}

@ -1,11 +1,33 @@
namespace DTO
using Model;
using System.Collections.Immutable;
namespace DTO
{
public class ChampionDTO
{
public ChampionDTO(string name, string bio, string icon, string Class, string image)
{
Name = name;
Bio = bio;
Icon = icon;
this.Class = Class;
Image = image;
}
public string Name { get; set; }
public string Bio { get; set; }
public string Icon { get; set; }
public string Image { get; set; }
public string Class { get; set; }
public bool equals(ChampionDTO other)
{
return other.Name==this.Name && other.Bio==this.Bio && other.Icon==this.Icon;
}
public string toString()
{
return Name + Bio + Icon;
}
}
}

@ -6,4 +6,9 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Model\Model.csproj" />
<ProjectReference Include="..\StubLib\StubLib.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,30 @@
//using Model;
//using StubLib;
//var builder = WebApplication.CreateBuilder(args);
//// Add services to the container.
//builder.Services.AddControllers();
//// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
//builder.Services.AddEndpointsApiExplorer();
//builder.Services.AddSwaggerGen();
//builder.Services.AddScoped<IDataManager,StubData>();
//var app = builder.Build();
//// Configure the HTTP request pipeline.
//if (app.Environment.IsDevelopment())
//{
// app.UseSwagger();
// app.UseSwaggerUI();
//}
//app.UseHttpsRedirection();
//app.UseAuthorization();
//app.MapControllers();
//app.Run();

@ -0,0 +1,29 @@
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DTO
{
public class SkinDTO
{
public string Name { get; set; }
public string Description { get; set; }
public string Icon { get; set; }
public string Image { get; set; }
public float Price { get; set; }
public SkinDTO(string name,string description,string icon,string image,float price) {
this.Name = name;
this.Description = description;
this.Icon = icon;
this.Image = image;
this.Price = price;
}
}
}

@ -0,0 +1,53 @@
using EntityFramework;
using EntityFramework.Manager;
using FluentAssertions;
using FluentAssertions.Primitives;
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EF_UT
{
[TestClass]
public class EFDataManagerChampionTest
{
[TestMethod]
public void Add_ValidChampion_Added()
{
IDataManager dataManager = new EFDataManager();
IChampionsManager championsManager = dataManager.ChampionsMgr;
var champ = championsManager.AddItem(new Champion("test"));
}
[TestMethod]
public async Task GetItemsByName_DefaultChamp_One()
{
var builder = WebApplication.CreateBuilder();
builder.Services.AddDbContext<LoLDBContextWithStub>();
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
var context = scope.ServiceProvider.GetService<LoLDBContextWithStub>();
context.Database.EnsureCreated();
}
IDataManager dataManager = new EFDataManager();
IChampionsManager championsManager = dataManager.ChampionsMgr;
var ak = (await championsManager.GetItemsByName("A", 0, 1)).First();
Assert.IsNotNull(ak);
Assert.AreEqual("Aatrox", ak.Name);
}
}
}

@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
<PackageReference Include="coverlet.collector" Version="3.1.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\API_LoL\API_LoL.csproj" />
<ProjectReference Include="..\Api_UT\Api_UT.csproj" />
<ProjectReference Include="..\DTO\DTO.csproj" />
<ProjectReference Include="..\EntityFramework\EntityFramework.csproj" />
<ProjectReference Include="..\Model\Model.csproj" />
<ProjectReference Include="..\StubLib\StubLib.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,90 @@
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EntityFramework;
using System.Threading.Tasks;
namespace EF_UT
{
[TestClass]
public class EntityTest
{
[TestMethod]
public void TestAdd()
{
var options = new DbContextOptionsBuilder<LoLDbContext>()
.UseInMemoryDatabase(databaseName: "Add_Test_database").Options;
//prepares the database with one instance of the context
using (var context = new LoLDbContext(options))
{
ChampionEntity chewie = new ChampionEntity { Name = "Chewbacca", Bio = "", Icon = "" };
ChampionEntity yoda = new ChampionEntity{ Name = "Yoda", Bio = "", Icon = "" };
ChampionEntity ewok = new ChampionEntity{ Name = "Ewok", Bio = "", Icon = "" };
//SkinEntity defaulSkin = new SkinEntity("Skin Default", chewie);
//chewie.AddSkin(defaulSkin);
Console.WriteLine("Creates and inserts new Champion for tests");
context.Add(chewie);
context.Add(yoda);
context.Add(ewok);
context.SaveChanges();
}
//prepares the database with one instance of the context
using (var context = new LoLDbContext(options))
{
Assert.AreEqual(3, context.Champions.Count());
Assert.AreEqual("Chewbacca", context.Champions.First().Name);
}
}
[TestMethod]
public void TestUpdate()
{
var options = new DbContextOptionsBuilder<LoLDbContext>()
.UseInMemoryDatabase(databaseName: "Modify_Test_database")
.Options;
//prepares the database with one instance of the context
using (var context = new LoLDbContext(options))
{
ChampionEntity chewie = new ChampionEntity{ Name = "Chewbacca", Bio = "ewa", Icon = "" };
ChampionEntity yoda = new ChampionEntity{ Name = "Yoda", Bio = "wewo", Icon = "" };
ChampionEntity ewok = new ChampionEntity{ Name = "Ewok", Bio = "", Icon = "" };
context.Add(chewie);
context.Add(yoda);
context.Add(ewok);
context.SaveChanges();
}
//prepares the database with one instance of the context
using (var context = new LoLDbContext(options))
{
string BioToFind = "ew";
Assert.AreEqual(2, context.Champions.Where(n => n.Bio.ToLower().Contains(BioToFind)).Count());
BioToFind = "ewo";
Assert.AreEqual(1, context.Champions.Where(n => n.Bio.ToLower().Contains(BioToFind)).Count());
var ewok = context.Champions.Where(n => n.Bio.ToLower().Contains(BioToFind)).First();
ewok.Bio = "Wicket";
context.SaveChanges();
}
//prepares the database with one instance of the context
//using (var context = new LoLDbContext(options))
//{
// string NameToFind = "ew";
// Assert.AreEqual(1, context.Champions.Where(n => n.Bio.ToLower().Contains(NameToFind)).Count());
// NameToFind = "wick";
// Assert.AreEqual(1, context.Champions.Where(n => n.Bio.ToLower().Contains(NameToFind)).Count());
//}
}
}
}

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

@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Collections.ObjectModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntityFramework
{
[Table("Champion")]
public class ChampionEntity
{
//[Key]
//[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
//public int Id { get; set; }
[Key]
[MaxLength(50)]
public string Name { get; set; }
[MaxLength(500)]
[Column("Bio", TypeName = "string")]
public string Bio { get; set; }
[Required]
public string Icon { get; set; }
//public ImmutableHashSet<Skill> Skills => skills.ToImmutableHashSet();
//private HashSet<Skill> skills = new HashSet<Skill>();
public ICollection<SkillEntity> Skills { get; set; } = new Collection<SkillEntity>();
//public ReadOnlyCollection<SkinEntity> Skins { get; private set; }
//private List<SkinEntity> skins = new();
public ICollection<SkinEntity> skins { get; set; } = new Collection<SkinEntity>();
//public LargeImageEntity? Image { get; set; } ====> voir pour faire "plus propre" => créé une table pour l'entity Largeimage
public string? Image { get; set; }
// Pour le many to many Champion *<---->* RunePage
public ICollection<RunePageEntity> RunePageEntities{ get; set; }
/// <summary>
/// pas besoin de constructeur ! (sans lui, il est possible d'utiliser la syntaxe utilisé dans le stubbedbDBCOntext)
/// </summary>
/// <returns></returns>
//public ChampionEntity(string name,string bio,string icon) {
// this.Name = name;
// this.Bio = bio;
// this.Icon = icon;
// Skills= new List<SkillEntity>();
// //Skins = new ReadOnlyCollection<SkinEntity>(skins);
//}
public override string ToString()
{
return Name;
}
public void AddSkill(SkillEntity skill)
=> Skills.Add(skill);
public void RemoveSkill(SkillEntity skill)
=> Skills.Remove(skill);
public bool AddSkin(SkinEntity skin)
{
if (skins.Contains(skin))
return false;
skins.Add(skin);
return true;
}
}
}

@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<StartWorkingDirectory>$(MSBuildProjectDirectory)</StartWorkingDirectory>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Manager\EFDataManager.Champion.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Manager\EFDataManager.Champion.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Model\Model.csproj" />
<ProjectReference Include="..\StubLib\StubLib.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntityFramework
{
public enum EnumCategory
{
Major,
Minor1,
Minor2,
Minor3,
OtherMinor1,
OtherMinor2
}
}

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntityFramework
{
public enum ChampionClass
{
Unknown,
Assassin,
Fighter,
Mage,
Marksman,
Support,
Tank
}
}

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntityFramework
{
public enum EnumRuneFamily
{
Unknown,
Precision,
Domination
}
}

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntityFramework
{
public enum SkillType
{
Unknown,
Basic,
Passive,
Ultimate
}
}

@ -0,0 +1,22 @@
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntityFramework
{
public class LargeImageEntity
{
public int Id { get; set; }
public string Base64 { get; set; }
//public LargeImageEntity(string base64)
//{
// Base64 = base64;
//}
}
}

@ -0,0 +1,25 @@
using EntityFramework.Mapper;
using Microsoft.EntityFrameworkCore;
using StubLib;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntityFramework
{
public class LoLDBContextWithStub : LoLDbContext
{
protected override async void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
var stub = new StubData.ChampionsManager(new StubData());
var list = await stub.GetItems(0, await stub.GetNbItems());
modelBuilder.Entity<ChampionEntity>().HasData(
list.Select(champion => champion.ToEntity())
);
}
}
}

@ -0,0 +1,100 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace EntityFramework
{
public class LoLDbContext : DbContext
{
public DbSet<ChampionEntity> Champions { get; set; }
public DbSet<SkinEntity> Skins { get; set; }
public DbSet<LargeImageEntity> Image { get; set; }
public DbSet<RuneEntity> Rune { get; set; }
public DbSet<RunePageEntity> RunePage { get; set; }
public LoLDbContext()
{ }
public LoLDbContext(DbContextOptions<LoLDbContext> options)
: base(options)
{ }
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
if (!options.IsConfigured)
{
options.UseSqlite("Data Source=champion.db");
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<ChampionEntity>().HasKey(entity => entity.Name);
modelBuilder.Entity<ChampionEntity>().ToTable("Champions");
//modelBuilder.Entity<ChampionEntity>().Property(entity => entity.Id)
// .ValueGeneratedOnAdd();
modelBuilder.Entity<ChampionEntity>().Property(entity => entity.Name)
.IsRequired()
.HasMaxLength(50);
modelBuilder.Entity<ChampionEntity>().Property(entity => entity.Bio)
.HasMaxLength(500)
.HasColumnName("Bio")
.HasColumnType("string");
modelBuilder.Entity<ChampionEntity>().Property(entity => entity.Icon)
.IsRequired();
/// One to many
/// ChampionEntity 1 ---> * SkinEntity
//création de la table Skin
modelBuilder.Entity<SkinEntity>().HasKey(skin => skin.Name); //définition de la clé primaire
modelBuilder.Entity<SkinEntity>().Property(skin => skin.Name)
.ValueGeneratedOnAdd(); //définition du mode de génération de la clé : génération à l'insertion
// Add the shadow property to the model
modelBuilder.Entity<SkinEntity>()
.Property<string>("ChampionEntityForeignKey");
// Use the shadow property as a foreign key
modelBuilder.Entity<SkinEntity>()
.HasOne(skin => skin.Champion)
.WithMany(champion => champion.skins)
.HasForeignKey("ChampionEntityForeignKey");
// Many to Many ChampionEntity - RunePageEntity
modelBuilder.Entity<RuneEntity>().HasKey(entity => entity.Name);
modelBuilder.Entity<RunePageEntity>().HasKey(entity => entity.Name);
modelBuilder.Entity<RunePageEntity>().ToTable("RunePage");
// Use the shadow property as a foreign key
modelBuilder.Entity<RunePageEntity>()
.HasMany(r => r.Champion)
.WithMany(c => c.RunePageEntities);
//.HasForeignKey("AlbumForeignKey");
modelBuilder.Entity<ChampionEntity>()
.HasMany(c => c.RunePageEntities)
.WithMany(r => r.Champion);
//.HasForeignKey("AlbumForeignKey");
}
}
}

@ -0,0 +1,186 @@
using EntityFramework.Mapper;
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntityFramework.Manager
{
public partial class EFDataManager
{
public class ChampionsManager : IChampionsManager
{
private readonly EFDataManager parent;
public ChampionsManager(EFDataManager parent)
{
this.parent = parent;
}
public async Task<Champion?> AddItem(Champion? item)
{
using(var context = new LoLDBContextWithStub())
{
if (item != null)
{
context.Add(item.ToEntity());
context.SaveChanges();
return item;
}
else
{
throw new Exception();
}
}
}
public async Task<bool> DeleteItem(Champion? item)
{
using (var context = new LoLDBContextWithStub())
{
var champ = context.Champions.Select(c => c == item.ToEntity());
if(champ.Count()<1)
{
return false;
}
context.Champions.Remove(item.ToEntity());
context.SaveChanges();
return true;
}
}
public async Task<IEnumerable<Champion?>> GetItems(int index, int count, string? orderingPropertyName = null, bool descending = false)
{
using(var context = new LoLDBContextWithStub() )
{
var champ = context.Champions.ToArray();
if (descending == false)
{
return champ.ToList().Skip(index * count).Take(count).Select(c => c.ToChampion()).OrderBy(c => c.Name);
}
else
{
return champ.ToList().Skip(index * count).Take(count).Select(c => c.ToChampion()).OrderByDescending(c => c.Name);
}
}
}
public Task<IEnumerable<Champion?>> GetItemsByCharacteristic(string charName, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
throw new NotImplementedException();
}
public Task<IEnumerable<Champion?>> GetItemsByClass(Model.ChampionClass championClass, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
throw new NotImplementedException();
}
public async Task<IEnumerable<Champion?>> GetItemsByName(string substring, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
using (var context = new LoLDBContextWithStub())
{
var champ = context.Champions.Where(c => c.Name.Contains(substring)).AsEnumerable();
if (descending == false)
{
return champ.Select(c => c.ToChampion()).ToList().Skip(index * count).Take(count).OrderBy(c=> c.Name);
}
else
{
return champ.Select(c => c.ToChampion()).ToList().Skip(index*count).Take(count).OrderByDescending(c => c.Name);
}
}
}
public Task<IEnumerable<Champion?>> GetItemsByRunePage(RunePage? runePage, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
throw new NotImplementedException();
}
public Task<IEnumerable<Champion?>> GetItemsBySkill(Skill? skill, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
throw new NotImplementedException();
}
public async Task<IEnumerable<Champion?>> GetItemsBySkill(string skill, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
using(var context = new LoLDBContextWithStub())
{
var champ = context.Champions.Where(c => c.Skills.Any(c => c.Name.Contains(skill)));
if (descending.Equals(false))
{
return champ.Select(c=> c.ToChampion()).ToList().Skip(index * count).Take(count).OrderBy(c => c.Name);
}
else
{
return champ.Select(c => c.ToChampion()).ToList().Skip(index * count).Take(count).OrderByDescending(c => c.Name);
}
}
}
public async Task<int> GetNbItems()
{
using(var context = new LoLDBContextWithStub())
{
return context.Champions.Count();
}
}
public Task<int> GetNbItemsByCharacteristic(string charName)
{
throw new NotImplementedException();
}
public Task<int> GetNbItemsByClass(Model.ChampionClass championClass)
{
throw new NotImplementedException();
}
public Task<int> GetNbItemsByName(string substring)
{
throw new NotImplementedException();
}
public Task<int> GetNbItemsByRunePage(RunePage? runePage)
{
throw new NotImplementedException();
}
public Task<int> GetNbItemsBySkill(Skill? skill)
{
throw new NotImplementedException();
}
public Task<int> GetNbItemsBySkill(string skill)
{
throw new NotImplementedException();
}
public async Task<Champion?> UpdateItem(Champion? oldItem, Champion? newItem)
{
using(var context = new LoLDBContextWithStub())
{
if (oldItem != null && newItem != null)
{
var champ = context.Champions.Where(c => c == oldItem.ToEntity()).First();
champ = newItem.ToEntity();
context.SaveChanges();
return newItem;
}
else { throw new Exception(); }
}
}
}
}
}

@ -0,0 +1,85 @@
using EntityFramework.Mapper;
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntityFramework.Manager
{
public partial class EFDataManager
{
public class SkinsManager : ISkinsManager
{
private readonly EFDataManager parent;
public SkinsManager(EFDataManager parent)
{
this.parent = parent;
}
public Task<Skin?> AddItem(Skin? item)
{
throw new NotImplementedException();
}
public Task<bool> DeleteItem(Skin? item)
{
throw new NotImplementedException();
}
public Task<IEnumerable<Skin?>> GetItems(int index, int count, string? orderingPropertyName = null, bool descending = false)
{
throw new NotImplementedException();
}
public async Task<IEnumerable<Skin?>> GetItemsByChampion(Champion? champion, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
using (var context = new LoLDBContextWithStub())
{
var skins = context.Skins.Where(c => c.Champion.Equals(champion)).ToList();
if (descending == false)
{
return skins.Select(c => c.ToSkin()).ToList().Skip(index * count).Take(count).OrderBy(c => c.Name);
}
else
{
return skins.Select(c => c.ToSkin()).ToList().Skip(index * count).Take(count).OrderByDescending(c => c.Name);
}
}
}
public Task<IEnumerable<Skin?>> GetItemsByName(string substring, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
throw new NotImplementedException();
}
public Task<int> GetNbItems()
{
throw new NotImplementedException();
}
public async Task<int> GetNbItemsByChampion(Champion? champion)
{
using(var context = new LoLDBContextWithStub())
{
return context.Skins.Where(c => c.Champion.Equals(champion.ToEntity())).Count();
}
}
public Task<int> GetNbItemsByName(string substring)
{
throw new NotImplementedException();
}
public Task<Skin?> UpdateItem(Skin? oldItem, Skin? newItem)
{
throw new NotImplementedException();
}
}
}
}

@ -0,0 +1,25 @@
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntityFramework.Manager
{
public partial class EFDataManager : IDataManager
{
public EFDataManager() {
ChampionsMgr = new ChampionsManager(this);
SkinsMgr = new SkinsManager(this);
}
public IChampionsManager ChampionsMgr { get; }
public ISkinsManager SkinsMgr { get; }
public IRunesManager RunesMgr { get; }
public IRunePagesManager RunePagesMgr { get; }
}
}

@ -0,0 +1,22 @@
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntityFramework.Mapper
{
public static class ChampionMapper
{
public static ChampionEntity ToEntity(this Champion champion) {
return new ChampionEntity { Name = champion.Name, Bio = champion.Bio, Icon = champion.Icon };
}
public static Champion ToChampion(this ChampionEntity champion)
{
return new Champion(champion.Name,bio: champion.Bio,icon: champion.Icon);
}
}
}

@ -0,0 +1,24 @@
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntityFramework.Mapper
{
public static class SkinMapper
{
public static SkinEntity ToEntity(this Skin skin)
{
return new SkinEntity { Champion = skin.Champion.ToEntity(), Description = skin.Description, Icon = skin.Icon, Image = skin.Image.Base64, Name = skin.Name, Price = skin.Price };
}
public static Skin ToSkin(this SkinEntity entity)
{
return new Skin(entity.Name,entity.Champion.ToChampion(),price: entity.Price,icon: entity.Icon, image: entity.Image,description: entity.Description);
}
}
}

@ -0,0 +1,132 @@
// See https://aka.ms/new-console-template for more information
using EntityFramework;
using EntityFramework.Manager;
using Microsoft.EntityFrameworkCore;
using Model;
using System.Buffers.Text;
using ( var context = new LoLDbContext())
{
//context.Add(new ChampionEntity{ Name = "test", Bio = "test", Icon = "test" } );
context.SaveChanges();
ChampionEntity champ = context.Find<ChampionEntity>("Akali");
if( champ != null)
{
Console
.WriteLine(champ.ToString());
}
else
{
Console.WriteLine("Not Found");
}
//Test BDD Skills
ChampionEntity champSkill = new ChampionEntity { Name="nomSkill", Bio="bioSkill", Icon="iconSkill" };
//SkillEntity s1 = new SkillEntity { Name = "Skill1", Description = "desc", Type = SkillType.Unknown };
SkillEntity s2 = new SkillEntity { Name="Skill2", Description="desc2", Type= EntityFramework.SkillType.Ultimate };
SkillEntity s3 = new SkillEntity { Name = "Skill3", Description = "desc3", Type = EntityFramework.SkillType.Passive };
champSkill.AddSkill(new SkillEntity { Name = "Skill1", Description = "desc", Type = EntityFramework.SkillType.Unknown });
champSkill.AddSkill(s2);
champSkill.AddSkill(s3);
context.Add(champSkill);
context.SaveChanges();
IDataManager dataManager = new EFDataManager();
IChampionsManager championsManager = dataManager.ChampionsMgr;
IEnumerable<Champion?> champions = await championsManager.GetItemsByName("A", 0, 1);
Console.WriteLine(champions.First().Name);
//using ( var context = new LoLDbContext())
//{
// //context.Add(new ChampionEntity{ Name = "test", Bio = "test", Icon = "test" } );
// context.SaveChanges();
// ChampionEntity champ = context.Find<ChampionEntity>("Akali");
// if( champ != null)
// {
// Console
// .WriteLine(champ.ToString());
// }
// else
// {
// Console.WriteLine("Not Found");
// }
// //Test BDD Skills
// ChampionEntity champSkill = new ChampionEntity { Name="nomSkill", Bio="bioSkill", Icon="iconSkill" };
// //SkillEntity s1 = new SkillEntity { Name = "Skill1", Description = "desc", Type = SkillType.Unknown };
// SkillEntity s2 = new SkillEntity { Name="Skill2", Description="desc2", Type=SkillType.Ultimate };
// SkillEntity s3 = new SkillEntity { Name = "Skill3", Description = "desc3", Type = SkillType.Passive };
// champSkill.AddSkill(new SkillEntity { Name = "Skill1", Description = "desc", Type = SkillType.Unknown });
// champSkill.AddSkill(s2);
// champSkill.AddSkill(s3);
// context.Add(champSkill);
// context.SaveChanges();
// //OneToMany
// Console.WriteLine("Champions : ");
// foreach (var champi in context.Champions.Include(a => a.skins))
// {
// Console.WriteLine($"\t{champi.Name} : {champi.Bio}");
// foreach (var s in champi.skins)
// {
// Console.WriteLine($"\t\t{s.Name}");
// }
// }
// Console.WriteLine();
// Console.WriteLine("Skin :");
// foreach (var s in context.Skins)
// {
// Console.WriteLine($"\t{s.Name}: {s.Description} (Champion : {s.Champion.Name})");
// }
var r1 = new RuneEntity { Name = "Rune1", Description = "aaa", Family = EnumRuneFamily.Domination, Image = new LargeImage("base") };
var r2 = new RuneEntity { Name = "Rune2", Description = "aaa", Family = EnumRuneFamily.Domination, Image = new LargeImage("base") };
var corichard = new ChampionEntity { Name = "Corichard", Bio = "biobio", Icon = "Icon.png" };
var pintrand = new ChampionEntity { Name = "Pintrand", Bio = "biobio", Icon = "Icon.png" };
var rp1 = new RunePageEntity { Name = "RP1", Rune = new RuneEntity { Name = "aa", Description = "aaa", Family = EnumRuneFamily.Domination, Image = new LargeImage("base") }, Champion = new List<ChampionEntity> { corichard } };
var rp2 = new RunePageEntity { Name = "RP2", Rune = new RuneEntity{ Name = "aaa", Description = "aaa", Family = EnumRuneFamily.Domination, Image = new LargeImage("base") }, Champion = new List<ChampionEntity> { pintrand } };
context.Rune.AddRange(new[] { r1, r2 });
context.Champions.AddRange(new[] { corichard, pintrand });
context.RunePage.AddRange(new[] { rp1, rp2 });
context.SaveChanges();
}
// Console.WriteLine("\nAjout d'un Champion et 6 Skins...\n");
// ChampionEntity captainMarvel = new ChampionEntity { Name = "Captain Marvel", Bio="Mais que fait un avenger ici ??", Icon="Icon.png"};
// SkinEntity[] skins = { new SkinEntity {Name = "La Fiesta", Champion = captainMarvel},
// new SkinEntity { Name = "Five Hundred Miles High", Champion = captainMarvel },
// new SkinEntity { Name = "Captain Marvel", Champion = captainMarvel },
// new SkinEntity { Name = "Time's Lie", Champion = captainMarvel },
// new SkinEntity { Name = "Lush Life", Champion = captainMarvel },
// new SkinEntity { Name = "Day Waves", Champion = captainMarvel }
// };
// foreach (var s in skins)
// {
// captainMarvel.skins.Add(s);
// }
// context.Add(captainMarvel);
// context.SaveChanges();
//}

@ -0,0 +1,24 @@
using Model;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntityFramework
{
//[Table("Rune")]
public class RuneEntity
{
[Key]
public string Name;
public string Description;
public EnumRuneFamily Family;
public LargeImage Image;
}
}

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static Model.RunePage;
namespace EntityFramework
{
public class RunePageEntity
{
[Key]
public string Name { get; set; }
public RuneEntity? Rune { get; set; }
//? voir si cela pause probleme
public Dictionary<EnumCategory, Rune> Dico = new Dictionary<EnumCategory, Rune>();
// Pour le many to many Champion *<---->* RunePage
public ICollection<ChampionEntity> Champion{ get; set; }
public void CheckRunes(EnumCategory newRuneCategory){}
public void CheckFamilies(EnumCategory cat1, EnumCategory cat2){}
public void UpdateMajorFamily(EnumCategory minor, bool expectedValue){}
}
}

@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntityFramework
{
public class SkillEntity
{
public SkillType Type { get; set; }
[Key]
public string Name { get; set; }
//public string Name
//{
// get => name;
// private init
// {
// if (string.IsNullOrWhiteSpace(value))
// {
// throw new ArgumentException("a Skill needs a name");
// }
// name = value;
// }
//}
//private readonly string name = null!;
public string Description { get; set; }
//public string Description
//{
// get => description;
// set
// {
// if (string.IsNullOrWhiteSpace(value))
// {
// description = "";
// return;
// }
// description = value;
// }
//}
//private string description = "";
//public SkillEntity(string Name, string Description, SkillType Type) {
// this.name = Name;
// this.Description = Description;
// this.Type = Type;
//}
}
}

@ -0,0 +1,79 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntityFramework
{
public class SkinEntity //ONE TO MANY
{
public string? Name { get; set; }
public string? Description { get; set; }
//public string Name
//{
// get => name;
// private init
// {
// if (string.IsNullOrWhiteSpace(value))
// {
// throw new ArgumentException("A skin must have a name");
// }
// name = value;
// }
//}
//private readonly string name = null!;
//public string Description
//{
// get => description;
// set
// {
// if (string.IsNullOrWhiteSpace(value))
// {
// description = "";
// return;
// }
// description = value;
// }
//}
//private string description = "";
public string Icon { get; set; } = "";
//public LargeImageEntity Image { get; set; }
public string? Image { get; set; }
public float Price { get; set; }
public ChampionEntity Champion { get; set; }
//public ChampionEntity Champion
//{
// get => champion;
// private init
// {
// if (value == null)
// throw new ArgumentNullException("A skill can't have a null champion");
// champion = value;
// }
//}
//private readonly ChampionEntity champion = null!;
//public SkinEntity(string name, ChampionEntity champion, float price = 0.0f, string icon = "", string image = "", string description = "")
//{
// Name = name;
// Champion = champion;
// //Champion.AddSkin(this);
// Price = price;
// Icon = icon;
// Image = new LargeImageEntity(image);
// Description = description;
//}
}
}

@ -0,0 +1,51 @@
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntityFramework
{
public class StubbedContext : LoLDbContext
{
//protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
//{
// optionsBuilder.EnableSensitiveDataLogging();
//}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
ChampionEntity corichard = new ChampionEntity { Name = "Corichard", Bio = "biobiobiobio", Icon = "/a/a/a/a" };
ChampionEntity pintrand = new ChampionEntity { Name = "Pintrand", Bio = "mimimimimim", Icon = "/small.png" };
RuneEntity r1 = new RuneEntity { Name = "FirstRune", Description = "desc", Family = EnumRuneFamily.Domination };
RuneEntity r2 = new RuneEntity { Name = "SecondRune", Description = "desc", Family = EnumRuneFamily.Unknown };
//ChampionEntity corichard = new ChampionEntity() { Name = "Corichard", Bio = "biobiobiobio", Icon = "/a/a/a/a", Image = new LargeImageEntity { Base64 = "base" } };
//ChampionEntity pintrand = new ChampionEntity { Name = "Pintrand", Bio = "mimimimimim", Icon = "/small.png", Image = new LargeImageEntity { Base64 = "base" } };
modelBuilder.Entity<ChampionEntity>().HasData(corichard, pintrand);
modelBuilder.Entity<SkinEntity>().HasData(new { Name = "aaaa", ChampionEntityForeignKey = "Corichard", Description = "So What", Icon="/Icon.png", Price=10.0f },
new { Name = "skin", ChampionEntityForeignKey = "Corichard", Description = "So What", Icon = "/Icon.png", Price = 10.0f },
new { Name = "bo", ChampionEntityForeignKey = "Corichard", Description = "So What", Icon = "/Icon.png", Price = 10.0f },
new { Name = "Joulie", ChampionEntityForeignKey = "Corichard", Description = "So What", Icon = "/Icon.png", Price = 10.0f },
new { Name = "Radiance", ChampionEntityForeignKey = "Corichard", Description = "So What", Icon = "/Icon.png", Price = 10.0f },
new { Name = "void", ChampionEntityForeignKey = "Corichard", Description = "So What", Icon = "/Icon.png", Price = 10.0f },
new { Name = "Radiance", ChampionEntityForeignKey = "Pintrand", Description = "So What", Icon = "/Icon.png", Price = 10.0f },
new { Name = "void", ChampionEntityForeignKey = "Pintrand", Description = "So What", Icon = "/Icon.png", Price = 10.0f },
new { Name = "DarkTheme", ChampionEntityForeignKey = "Pintrand", Description = "So What", Icon = "/Icon.png", Price = 10.0f },
new { Name = "gold", ChampionEntityForeignKey = "Pintrand", Description = "So What", Icon = "/Icon.png", Price = 10.0f },
new { Name = "ruby", ChampionEntityForeignKey = "Pintrand", Description = "So What", Icon = "/Icon.png", Price = 10.0f }
);
modelBuilder.Entity<RunePageEntity>().HasData(new { Name = "RP1", Rune = r1, Champion = corichard},
new { Name = "RP2", Rune = r2, Champion = pintrand}
);
}
}
}

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Net.Http" Version="4.3.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\API_LoL\API_LoL.csproj" />
<ProjectReference Include="..\Model\Model.csproj" />
<ProjectReference Include="..\Shared\Shared.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,128 @@
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Json;
using System.Reflection;
using System.Reflection.Metadata;
using System.Runtime.ConstrainedExecution;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace HttpClient
{
public partial class HttpClientManager
{
public class ChampionManager : IChampionsManager
{
private readonly HttpClientManager parent;
private System.Net.Http.HttpClient httpc;
public string BaseAddress;
public ChampionManager(HttpClientManager parent, System.Net.Http.HttpClient httpc) {
this.httpc = httpc;
this.parent = parent;
}
public async Task<Champion?> AddItem(Champion? item) //return le champion ajouté, null sinon ?
{
if(item==null) throw new ArgumentNullException("item is null");
var response = await httpc.PostAsJsonAsync("/Champion?Name = " + item.Name, item);
return response.IsSuccessStatusCode ? item : null;
}
public async Task<bool> DeleteItem(Champion? item)
{
HttpResponseMessage response = await httpc.DeleteAsync("/Champion?Name=" + item.Name);
return response.IsSuccessStatusCode;
}
public Task<IEnumerable<Champion?>> GetItems(int index, int count, string? orderingPropertyName = null, bool descending = false)
{
return httpc.GetFromJsonAsync<IEnumerable<Champion>>("/Champion?index="+index+"&size="+count);
}
public Task<IEnumerable<Champion?>> GetItemsByCharacteristic(string charName, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
throw new NotImplementedException();
}
public Task<IEnumerable<Champion?>> GetItemsByClass(ChampionClass championClass, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
throw new NotImplementedException();
}
public Task<IEnumerable<Champion?>> GetItemsByName(string substring, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
return httpc.GetFromJsonAsync<IEnumerable<Champion>>("/Champion?name="+substring+"&index=" + index + "&size=" + count);
}
public Task<IEnumerable<Champion?>> GetItemsByRunePage(RunePage? runePage, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
throw new NotImplementedException();
}
public Task<IEnumerable<Champion?>> GetItemsBySkill(Skill? skill, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
throw new NotImplementedException();
}
public Task<IEnumerable<Champion?>> GetItemsBySkill(string skill, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
throw new NotImplementedException();
}
public Task<int> GetNbItems()
{
throw new NotImplementedException();
}
public Task<int> GetNbItemsByCharacteristic(string charName)
{
throw new NotImplementedException();
}
public Task<int> GetNbItemsByClass(ChampionClass championClass)
{
throw new NotImplementedException();
}
public Task<int> GetNbItemsByName(string substring)
{
throw new NotImplementedException();
}
public Task<int> GetNbItemsByRunePage(RunePage? runePage)
{
throw new NotImplementedException();
}
public Task<int> GetNbItemsBySkill(Skill? skill)
{
throw new NotImplementedException();
}
public Task<int> GetNbItemsBySkill(string skill)
{
throw new NotImplementedException();
}
public Task<Champion?> UpdateItem(Champion? oldItem, Champion? newItem)
{
throw new NotImplementedException();
}
}
}
}

@ -0,0 +1,29 @@
using Model;
namespace HttpClient
{
public partial class HttpClientManager : IDataManager
{
public System.Net.Http.HttpClient httpC { get; set; } = new System.Net.Http.HttpClient();
public string BaseAddress;
public HttpClientManager() {
ChampionsMgr = new ChampionManager(this, httpC);
httpC.BaseAddress = new Uri("https://localhost:7144/api/");
}
public ISkinsManager SkinsMgr => throw new NotImplementedException();
public IRunesManager RunesMgr => throw new NotImplementedException();
public IRunePagesManager RunePagesMgr => throw new NotImplementedException();
public IChampionsManager ChampionsMgr { get; set; }
}
}

@ -7,8 +7,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Model", "Model\Model.csproj
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{C76D0C23-1FFA-4963-93CD-E12BD643F030}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleTests", "Tests\ConsoleTests\ConsoleTests.csproj", "{1889FA6E-B7C6-416E-8628-9449FB9070B9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Shared", "Shared\Shared.csproj", "{3B720C0C-53FE-4642-A2DB-87FD8634CD74}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Stub", "Stub", "{2C607793-B163-4731-A4D1-AFE8A7C4C170}"
@ -17,9 +15,18 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StubLib", "StubLib\StubLib.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "API_LoL", "API_LoL\API_LoL.csproj", "{BE86E19B-3461-4EF6-8871-94E6CCB75928}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApiTests", "ApiTests\ApiTests.csproj", "{AE65F7E0-FA95-4D64-938D-78DB6C905F7B}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DTO", "DTO\DTO.csproj", "{E39C3FBC-DE5E-4DAF-945A-98CE4ADE54D9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EntityFramework", "EntityFramework\EntityFramework.csproj", "{23483395-5091-4956-822F-17234E8C9E5C}"
ProjectSection(ProjectDependencies) = postProject
{2960F9BA-49DE-494D-92E3-CE5A794BA1A9} = {2960F9BA-49DE-494D-92E3-CE5A794BA1A9}
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Api_UT", "Api_UT\Api_UT.csproj", "{20A1A7DC-1E93-4506-BD32-8597A5DADD7B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EF_UT", "EF_UT\EF_UT.csproj", "{74F469C3-A94A-4507-9DC7-7DBADCD18173}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DTO", "DTO\DTO.csproj", "{E39C3FBC-DE5E-4DAF-945A-98CE4ADE54D9}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HttpClient", "HttpClient\HttpClient.csproj", "{DE2E40D5-1B4D-491C-B7E7-4E91B32DB93F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -31,10 +38,6 @@ Global
{2960F9BA-49DE-494D-92E3-CE5A794BA1A9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2960F9BA-49DE-494D-92E3-CE5A794BA1A9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2960F9BA-49DE-494D-92E3-CE5A794BA1A9}.Release|Any CPU.Build.0 = Release|Any CPU
{1889FA6E-B7C6-416E-8628-9449FB9070B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1889FA6E-B7C6-416E-8628-9449FB9070B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1889FA6E-B7C6-416E-8628-9449FB9070B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1889FA6E-B7C6-416E-8628-9449FB9070B9}.Release|Any CPU.Build.0 = Release|Any CPU
{3B720C0C-53FE-4642-A2DB-87FD8634CD74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3B720C0C-53FE-4642-A2DB-87FD8634CD74}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3B720C0C-53FE-4642-A2DB-87FD8634CD74}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -47,22 +50,34 @@ Global
{BE86E19B-3461-4EF6-8871-94E6CCB75928}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BE86E19B-3461-4EF6-8871-94E6CCB75928}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BE86E19B-3461-4EF6-8871-94E6CCB75928}.Release|Any CPU.Build.0 = Release|Any CPU
{AE65F7E0-FA95-4D64-938D-78DB6C905F7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AE65F7E0-FA95-4D64-938D-78DB6C905F7B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AE65F7E0-FA95-4D64-938D-78DB6C905F7B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AE65F7E0-FA95-4D64-938D-78DB6C905F7B}.Release|Any CPU.Build.0 = Release|Any CPU
{E39C3FBC-DE5E-4DAF-945A-98CE4ADE54D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E39C3FBC-DE5E-4DAF-945A-98CE4ADE54D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E39C3FBC-DE5E-4DAF-945A-98CE4ADE54D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E39C3FBC-DE5E-4DAF-945A-98CE4ADE54D9}.Release|Any CPU.Build.0 = Release|Any CPU
{23483395-5091-4956-822F-17234E8C9E5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{23483395-5091-4956-822F-17234E8C9E5C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{23483395-5091-4956-822F-17234E8C9E5C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{23483395-5091-4956-822F-17234E8C9E5C}.Release|Any CPU.Build.0 = Release|Any CPU
{20A1A7DC-1E93-4506-BD32-8597A5DADD7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{20A1A7DC-1E93-4506-BD32-8597A5DADD7B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{20A1A7DC-1E93-4506-BD32-8597A5DADD7B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{20A1A7DC-1E93-4506-BD32-8597A5DADD7B}.Release|Any CPU.Build.0 = Release|Any CPU
{74F469C3-A94A-4507-9DC7-7DBADCD18173}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{74F469C3-A94A-4507-9DC7-7DBADCD18173}.Debug|Any CPU.Build.0 = Debug|Any CPU
{74F469C3-A94A-4507-9DC7-7DBADCD18173}.Release|Any CPU.ActiveCfg = Release|Any CPU
{74F469C3-A94A-4507-9DC7-7DBADCD18173}.Release|Any CPU.Build.0 = Release|Any CPU
{DE2E40D5-1B4D-491C-B7E7-4E91B32DB93F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DE2E40D5-1B4D-491C-B7E7-4E91B32DB93F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DE2E40D5-1B4D-491C-B7E7-4E91B32DB93F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DE2E40D5-1B4D-491C-B7E7-4E91B32DB93F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{1889FA6E-B7C6-416E-8628-9449FB9070B9} = {C76D0C23-1FFA-4963-93CD-E12BD643F030}
{B01D7EF2-2D64-409A-A29A-61FB7BB7A9DB} = {2C607793-B163-4731-A4D1-AFE8A7C4C170}
{AE65F7E0-FA95-4D64-938D-78DB6C905F7B} = {C76D0C23-1FFA-4963-93CD-E12BD643F030}
{20A1A7DC-1E93-4506-BD32-8597A5DADD7B} = {C76D0C23-1FFA-4963-93CD-E12BD643F030}
{74F469C3-A94A-4507-9DC7-7DBADCD18173} = {C76D0C23-1FFA-4963-93CD-E12BD643F030}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {92F3083D-793F-4552-8A9A-0AD6534159C9}

@ -0,0 +1,12 @@
{
"profiles": {
"Model": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:49972;http://localhost:49973"
}
}
}

@ -8,7 +8,7 @@ namespace StubLib
private List<Champion> champions = new()
{
new Champion("Akali", ChampionClass.Assassin),
new Champion("Aatrox", ChampionClass.Fighter),
new Champion("Aatrox", ChampionClass.Fighter),
new Champion("Ahri", ChampionClass.Mage),
new Champion("Akshan", ChampionClass.Marksman),
new Champion("Bard", ChampionClass.Support),

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
@ -8,6 +8,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\API_LoL\API_LoL.csproj" />
<ProjectReference Include="..\..\Model\Model.csproj" />
<ProjectReference Include="..\..\StubLib\StubLib.csproj" />
</ItemGroup>

@ -0,0 +1,12 @@
{
"profiles": {
"ConsoleTests": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:49970;http://localhost:49971"
}
}
}

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
<PackageReference Include="coverlet.collector" Version="3.1.2" />
</ItemGroup>
</Project>

@ -0,0 +1,10 @@
namespace Tests;
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
}
}

@ -0,0 +1 @@
global using Microsoft.VisualStudio.TestTools.UnitTesting;
Loading…
Cancel
Save