diff --git a/.drone.yml b/.drone.yml
new file mode 100644
index 0000000..82743c5
--- /dev/null
+++ b/.drone.yml
@@ -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 ]
+
diff --git a/README.md b/README.md
index 3228583..b0ba7c5 100644
--- a/README.md
+++ b/README.md
@@ -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.
+
+
+
+
+
+> *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
+
+[](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
diff --git a/Sources/.editorconfig b/Sources/.editorconfig
new file mode 100644
index 0000000..73bb42e
--- /dev/null
+++ b/Sources/.editorconfig
@@ -0,0 +1,4 @@
+[*.cs]
+
+# CS8604: Possible null reference argument.
+dotnet_diagnostic.CS8604.severity = none
diff --git a/Sources/API_LoL/API_LoL.csproj b/Sources/API_LoL/API_LoL.csproj
index 8902068..91c61d0 100644
--- a/Sources/API_LoL/API_LoL.csproj
+++ b/Sources/API_LoL/API_LoL.csproj
@@ -1,20 +1,24 @@
-
+
net6.0
enable
enable
1c8da478-3029-41d1-b936-853a71a8b812
- Windows
+ Linux
+
+
+
+
diff --git a/Sources/API_LoL/Controllers/ChampionsController.cs b/Sources/API_LoL/Controllers/ChampionsController.cs
index 9461ad4..2c35997 100644
--- a/Sources/API_LoL/Controllers/ChampionsController.cs
+++ b/Sources/API_LoL/Controllers/ChampionsController.cs
@@ -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/
+ public ChampionsController(IDataManager Manager) {
+ this._logger = LoggerFactory.Create(builder => builder.AddConsole()).CreateLogger();
+ 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//5
+
+ [HttpGet("count")]
+ public async Task GetCount()
+ {
+ _logger.LogInformation(message: "count returned", "Get", "/Champion/Count", 200, DateTime.Now);
+ return Ok(ChampionsManager.GetNbItems());
+ }
+
[HttpGet]
- public async Task Get()
+ public async Task 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() == 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//5
- [HttpGet("{id}")]
- public string Get(String name)
+ [HttpGet("name")]
+ public async Task 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 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 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/
[HttpPost]
public async Task 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//5
- [HttpPut("{id}")]
- public void Put(int id, [FromBody] string value)
+ [HttpPut("name")]
+ public async Task 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//5
- [HttpDelete("{id}")]
- public void Delete(int id)
+ [HttpDelete("name")]
+ public async Task 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(); }
}
}
}
diff --git a/Sources/API_LoL/Controllers/ChampionsControllerVersioned.cs b/Sources/API_LoL/Controllers/ChampionsControllerVersioned.cs
new file mode 100644
index 0000000..87598d9
--- /dev/null
+++ b/Sources/API_LoL/Controllers/ChampionsControllerVersioned.cs
@@ -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//5
+
+ //[HttpGet]
+ //public async Task 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/
+ //[HttpPost]
+ //public async Task Post(ChampionDTO champion)
+ //{
+ // if (champion == null)
+ // {
+ // return UnprocessableEntity();
+ // }
+ // else
+ // {
+ // await ChampionsManager.AddItem(champion.ToChampion());
+ // return CreatedAtAction("Post", champion);
+ // }
+ //}
+
+ //// PUT api//5
+ //[HttpPut("{id}")]
+ //public void Put(int id, [FromBody] string value)
+ //{
+ //}
+
+ //// DELETE api//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!";
+ }
+}
diff --git a/Sources/API_LoL/Dockerfile b/Sources/API_LoL/Dockerfile
index 5634a24..7ff2075 100644
--- a/Sources/API_LoL/Dockerfile
+++ b/Sources/API_LoL/Dockerfile
@@ -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"
diff --git a/Sources/API_LoL/Dockerfile.original b/Sources/API_LoL/Dockerfile.original
new file mode 100644
index 0000000..5634a24
--- /dev/null
+++ b/Sources/API_LoL/Dockerfile.original
@@ -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"]
\ No newline at end of file
diff --git a/Sources/API_LoL/Mapper/ChampionClassMapper.cs b/Sources/API_LoL/Mapper/ChampionClassMapper.cs
new file mode 100644
index 0000000..638f500
--- /dev/null
+++ b/Sources/API_LoL/Mapper/ChampionClassMapper.cs
@@ -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;
+ }
+ }
+ }
+}
diff --git a/Sources/API_LoL/Mapper/ChampionMapper.cs b/Sources/API_LoL/Mapper/ChampionMapper.cs
index f091999..632149e 100644
--- a/Sources/API_LoL/Mapper/ChampionMapper.cs
+++ b/Sources/API_LoL/Mapper/ChampionMapper.cs
@@ -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);
+
}
}
}
diff --git a/Sources/API_LoL/Mapper/SkinMapper.cs b/Sources/API_LoL/Mapper/SkinMapper.cs
new file mode 100644
index 0000000..5b18c55
--- /dev/null
+++ b/Sources/API_LoL/Mapper/SkinMapper.cs
@@ -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) ;
+ }
+ }
+}
diff --git a/Sources/API_LoL/Program.cs b/Sources/API_LoL/Program.cs
index 48863a6..78d467f 100644
--- a/Sources/API_LoL/Program.cs
+++ b/Sources/API_LoL/Program.cs
@@ -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();
+
+
+builder.Services.AddApiVersioning(o => o.ApiVersionReader = new UrlSegmentApiVersionReader());
+
+// Add services to the container.
+builder.Services.AddControllers();
+
+
+
+//builder.Services.AddScoped();
+
+
+builder.Services.AddHttpClient();
+
+//builder.Services.AddScoped();
+builder.Services.AddScoped();
+
+builder.Services.AddDbContext();
+
var app = builder.Build();
+using(var scope = app.Services.CreateScope())
+{
+ var context = scope.ServiceProvider.GetService();
+ context.Database.EnsureCreated();
+}
+
+var apiVersionDescriptionProvider = app.Services.GetRequiredService();
+
+
// 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();
diff --git a/Sources/API_LoL/SwaggerOptions.cs b/Sources/API_LoL/SwaggerOptions.cs
new file mode 100644
index 0000000..46ad759
--- /dev/null
+++ b/Sources/API_LoL/SwaggerOptions.cs
@@ -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
+ {
+ private readonly IApiVersionDescriptionProvider _provider;
+
+ public ConfigureSwaggerOptions(IApiVersionDescriptionProvider provider)
+ {
+ _provider = provider;
+ }
+
+ ///
+ /// Configure each API discovered for Swagger Documentation
+ ///
+ ///
+ 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));
+ }
+ }
+
+ ///
+ /// Configure Swagger Options. Inherited from the Interface
+ ///
+ ///
+ ///
+ public void Configure(string name, SwaggerGenOptions options)
+ {
+ Configure(options);
+ }
+
+ ///
+ /// Create information about the version of the API
+ ///
+ ///
+ /// Information about the API
+ 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;
+ }
+ }
+}
diff --git a/Sources/API_LoL/champion.db b/Sources/API_LoL/champion.db
new file mode 100644
index 0000000..cfdeed2
Binary files /dev/null and b/Sources/API_LoL/champion.db differ
diff --git a/Sources/API_LoL/champion.db-shm b/Sources/API_LoL/champion.db-shm
new file mode 100644
index 0000000..39d4916
Binary files /dev/null and b/Sources/API_LoL/champion.db-shm differ
diff --git a/Sources/API_LoL/champion.db-wal b/Sources/API_LoL/champion.db-wal
new file mode 100644
index 0000000..932d20c
Binary files /dev/null and b/Sources/API_LoL/champion.db-wal differ
diff --git a/Sources/ApiTests/Program.cs b/Sources/ApiTests/Program.cs
deleted file mode 100644
index a5af879..0000000
--- a/Sources/ApiTests/Program.cs
+++ /dev/null
@@ -1 +0,0 @@
-// See https://aka.ms/new-console-template for more information
diff --git a/Sources/Api_UT/Api_UT.csproj b/Sources/Api_UT/Api_UT.csproj
new file mode 100644
index 0000000..efdc9e5
--- /dev/null
+++ b/Sources/Api_UT/Api_UT.csproj
@@ -0,0 +1,34 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+ false
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Sources/Api_UT/ChampionControllerTest.cs b/Sources/Api_UT/ChampionControllerTest.cs
new file mode 100644
index 0000000..0a93acf
--- /dev/null
+++ b/Sources/Api_UT/ChampionControllerTest.cs
@@ -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 list = new List {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;
+ 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();
+ }
+
+ [TestMethod]
+ public async Task Get_2First_OkListOf2()
+ {
+ List list = new List { new ChampionDTO("Akali", "", "", "Assassin",""), new ChampionDTO("Aatrox", "", "", "Fighter","") };
+
+ IActionResult a = await api.Get(index: 0,size: 2);
+
+ a.Should().NotBeNull();
+ a.Should().BeOfType();
+ var aObject = a as OkObjectResult;
+ aObject.Should().NotBeNull();
+ var championresult = aObject.Value as IEnumerable;
+ list.Should().BeEquivalentTo(championresult);
+ }
+
+ [TestMethod]
+ public async Task Get_FilterAName_OkListOf5()
+ {
+ List list = new List { new ChampionDTO("Akali", "", "", "Assassin", ""), new ChampionDTO("Akshan", "", "", "Marksman", "") };
+
+ IActionResult a = await api.Get(name: "Ak");
+
+ a.Should().NotBeNull();
+ a.Should().BeOfType();
+ var aObject = a as OkObjectResult;
+ aObject.Should().NotBeNull();
+ var championresult = aObject.Value as IEnumerable;
+ 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;
+ Assert.IsNotNull(a);
+ ChampionDTO champ = new ChampionDTO("nom", "bio", "icon","Assassin", "");
+ Assert.IsTrue(champ.equals(other: (ChampionDTO)((CreatedAtActionResult)a).Value));
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Sources/Api_UT/Usings.cs b/Sources/Api_UT/Usings.cs
new file mode 100644
index 0000000..ab67c7e
--- /dev/null
+++ b/Sources/Api_UT/Usings.cs
@@ -0,0 +1 @@
+global using Microsoft.VisualStudio.TestTools.UnitTesting;
\ No newline at end of file
diff --git a/Sources/ApiTests/ApiTests.csproj b/Sources/ConsoleApplication/ConsoleApplication.csproj
similarity index 60%
rename from Sources/ApiTests/ApiTests.csproj
rename to Sources/ConsoleApplication/ConsoleApplication.csproj
index 74abf5c..3e93ad0 100644
--- a/Sources/ApiTests/ApiTests.csproj
+++ b/Sources/ConsoleApplication/ConsoleApplication.csproj
@@ -7,4 +7,9 @@
enable
+
+
+
+
+
diff --git a/Sources/ConsoleApplication/Program.cs b/Sources/ConsoleApplication/Program.cs
new file mode 100644
index 0000000..d3916f1
--- /dev/null
+++ b/Sources/ConsoleApplication/Program.cs
@@ -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();
+
+var app = builder.Build();
+
+using (var scope = app.Services.CreateScope())
+{
+ var context = scope.ServiceProvider.GetService();
+ 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;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Sources/ConsoleApplication/Utils.cs b/Sources/ConsoleApplication/Utils.cs
new file mode 100644
index 0000000..fb70443
--- /dev/null
+++ b/Sources/ConsoleApplication/Utils.cs
@@ -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;
+ }
+ }
+ }
+
+
+ }
+}
diff --git a/Sources/ConsoleTestAPI/ConsoleTestAPI.csproj b/Sources/ConsoleTestAPI/ConsoleTestAPI.csproj
new file mode 100644
index 0000000..a2be5fa
--- /dev/null
+++ b/Sources/ConsoleTestAPI/ConsoleTestAPI.csproj
@@ -0,0 +1,20 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Sources/ConsoleTestAPI/Program.cs b/Sources/ConsoleTestAPI/Program.cs
new file mode 100644
index 0000000..0f9440f
--- /dev/null
+++ b/Sources/ConsoleTestAPI/Program.cs
@@ -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 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 choices = new Dictionary()
+ {
+ [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 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 choices = new Dictionary()
+ {
+ [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
diff --git a/Sources/DTO/Program.cs b/Sources/DTO/Program.cs
new file mode 100644
index 0000000..8133fe8
--- /dev/null
+++ b/Sources/DTO/Program.cs
@@ -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();
+
+//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();
diff --git a/Sources/DTO/SkinDTO.cs b/Sources/DTO/SkinDTO.cs
new file mode 100644
index 0000000..eb255f6
--- /dev/null
+++ b/Sources/DTO/SkinDTO.cs
@@ -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;
+
+ }
+ }
+}
diff --git a/Sources/EF_UT/EFDataManagerChampionTest.cs b/Sources/EF_UT/EFDataManagerChampionTest.cs
new file mode 100644
index 0000000..486a8be
--- /dev/null
+++ b/Sources/EF_UT/EFDataManagerChampionTest.cs
@@ -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();
+
+ var app = builder.Build();
+
+ using (var scope = app.Services.CreateScope())
+ {
+ var context = scope.ServiceProvider.GetService();
+ 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);
+ }
+ }
+}
diff --git a/Sources/EF_UT/EF_UT.csproj b/Sources/EF_UT/EF_UT.csproj
new file mode 100644
index 0000000..eadf5a3
--- /dev/null
+++ b/Sources/EF_UT/EF_UT.csproj
@@ -0,0 +1,27 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Sources/EF_UT/EntityTest.cs b/Sources/EF_UT/EntityTest.cs
new file mode 100644
index 0000000..5fd0afb
--- /dev/null
+++ b/Sources/EF_UT/EntityTest.cs
@@ -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()
+ .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()
+ .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());
+ //}
+ }
+ }
+}
diff --git a/Sources/EF_UT/Usings.cs b/Sources/EF_UT/Usings.cs
new file mode 100644
index 0000000..ab67c7e
--- /dev/null
+++ b/Sources/EF_UT/Usings.cs
@@ -0,0 +1 @@
+global using Microsoft.VisualStudio.TestTools.UnitTesting;
\ No newline at end of file
diff --git a/Sources/EntityFramework/ChampionEntity.cs b/Sources/EntityFramework/ChampionEntity.cs
new file mode 100644
index 0000000..c090b08
--- /dev/null
+++ b/Sources/EntityFramework/ChampionEntity.cs
@@ -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 Skills => skills.ToImmutableHashSet();
+ //private HashSet skills = new HashSet();
+
+ public ICollection Skills { get; set; } = new Collection();
+
+ //public ReadOnlyCollection Skins { get; private set; }
+ //private List skins = new();
+
+ public ICollection skins { get; set; } = new Collection();
+
+ //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 RunePageEntities{ get; set; }
+
+
+
+ ///
+ /// pas besoin de constructeur ! (sans lui, il est possible d'utiliser la syntaxe utilisé dans le stubbedbDBCOntext)
+ ///
+ ///
+ //public ChampionEntity(string name,string bio,string icon) {
+ // this.Name = name;
+ // this.Bio = bio;
+ // this.Icon = icon;
+ // Skills= new List();
+ // //Skins = new ReadOnlyCollection(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;
+ }
+
+
+ }
+}
diff --git a/Sources/EntityFramework/EntityFramework.csproj b/Sources/EntityFramework/EntityFramework.csproj
new file mode 100644
index 0000000..358fe36
--- /dev/null
+++ b/Sources/EntityFramework/EntityFramework.csproj
@@ -0,0 +1,33 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+ $(MSBuildProjectDirectory)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
diff --git a/Sources/EntityFramework/EnumCategory.cs b/Sources/EntityFramework/EnumCategory.cs
new file mode 100644
index 0000000..8276ed2
--- /dev/null
+++ b/Sources/EntityFramework/EnumCategory.cs
@@ -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
+ }
+}
diff --git a/Sources/EntityFramework/EnumChampionClass.cs b/Sources/EntityFramework/EnumChampionClass.cs
new file mode 100644
index 0000000..b8a039f
--- /dev/null
+++ b/Sources/EntityFramework/EnumChampionClass.cs
@@ -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
+ }
+}
diff --git a/Sources/EntityFramework/EnumRuneFamily.cs b/Sources/EntityFramework/EnumRuneFamily.cs
new file mode 100644
index 0000000..cbeacc0
--- /dev/null
+++ b/Sources/EntityFramework/EnumRuneFamily.cs
@@ -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
+ }
+}
diff --git a/Sources/EntityFramework/EnumSkillType.cs b/Sources/EntityFramework/EnumSkillType.cs
new file mode 100644
index 0000000..f8f56f8
--- /dev/null
+++ b/Sources/EntityFramework/EnumSkillType.cs
@@ -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
+ }
+}
diff --git a/Sources/EntityFramework/LargeImageEntity.cs b/Sources/EntityFramework/LargeImageEntity.cs
new file mode 100644
index 0000000..b925a83
--- /dev/null
+++ b/Sources/EntityFramework/LargeImageEntity.cs
@@ -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;
+ //}
+ }
+}
diff --git a/Sources/EntityFramework/LoLDBContextWithStub.cs b/Sources/EntityFramework/LoLDBContextWithStub.cs
new file mode 100644
index 0000000..7379162
--- /dev/null
+++ b/Sources/EntityFramework/LoLDBContextWithStub.cs
@@ -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().HasData(
+ list.Select(champion => champion.ToEntity())
+ );
+ }
+ }
+}
diff --git a/Sources/EntityFramework/LoLDbContext.cs b/Sources/EntityFramework/LoLDbContext.cs
new file mode 100644
index 0000000..042b646
--- /dev/null
+++ b/Sources/EntityFramework/LoLDbContext.cs
@@ -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 Champions { get; set; }
+
+ public DbSet Skins { get; set; }
+
+ public DbSet Image { get; set; }
+
+
+ public DbSet Rune { get; set; }
+
+ public DbSet RunePage { get; set; }
+
+ public LoLDbContext()
+ { }
+
+ public LoLDbContext(DbContextOptions 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().HasKey(entity => entity.Name);
+ modelBuilder.Entity().ToTable("Champions");
+
+ //modelBuilder.Entity().Property(entity => entity.Id)
+ // .ValueGeneratedOnAdd();
+
+ modelBuilder.Entity().Property(entity => entity.Name)
+ .IsRequired()
+ .HasMaxLength(50);
+
+ modelBuilder.Entity().Property(entity => entity.Bio)
+ .HasMaxLength(500)
+ .HasColumnName("Bio")
+ .HasColumnType("string");
+
+ modelBuilder.Entity().Property(entity => entity.Icon)
+ .IsRequired();
+
+
+
+ /// One to many
+ /// ChampionEntity 1 ---> * SkinEntity
+ //création de la table Skin
+ modelBuilder.Entity().HasKey(skin => skin.Name); //définition de la clé primaire
+ modelBuilder.Entity().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()
+ .Property("ChampionEntityForeignKey");
+
+ // Use the shadow property as a foreign key
+ modelBuilder.Entity()
+ .HasOne(skin => skin.Champion)
+ .WithMany(champion => champion.skins)
+ .HasForeignKey("ChampionEntityForeignKey");
+
+
+
+
+
+ // Many to Many ChampionEntity - RunePageEntity
+ modelBuilder.Entity().HasKey(entity => entity.Name);
+ modelBuilder.Entity().HasKey(entity => entity.Name);
+ modelBuilder.Entity().ToTable("RunePage");
+
+
+ // Use the shadow property as a foreign key
+ modelBuilder.Entity()
+ .HasMany(r => r.Champion)
+ .WithMany(c => c.RunePageEntities);
+ //.HasForeignKey("AlbumForeignKey");
+
+ modelBuilder.Entity()
+ .HasMany(c => c.RunePageEntities)
+ .WithMany(r => r.Champion);
+ //.HasForeignKey("AlbumForeignKey");
+ }
+ }
+}
diff --git a/Sources/EntityFramework/Manager/EFDataManager.Champions.cs b/Sources/EntityFramework/Manager/EFDataManager.Champions.cs
new file mode 100644
index 0000000..689959b
--- /dev/null
+++ b/Sources/EntityFramework/Manager/EFDataManager.Champions.cs
@@ -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 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 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> 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> GetItemsByCharacteristic(string charName, int index, int count, string? orderingPropertyName = null, bool descending = false)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task> GetItemsByClass(Model.ChampionClass championClass, int index, int count, string? orderingPropertyName = null, bool descending = false)
+ {
+ throw new NotImplementedException();
+ }
+
+ public async Task> 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> GetItemsByRunePage(RunePage? runePage, int index, int count, string? orderingPropertyName = null, bool descending = false)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task> GetItemsBySkill(Skill? skill, int index, int count, string? orderingPropertyName = null, bool descending = false)
+ {
+ throw new NotImplementedException();
+ }
+
+ public async Task> 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 GetNbItems()
+ {
+ using(var context = new LoLDBContextWithStub())
+ {
+ return context.Champions.Count();
+ }
+ }
+
+ public Task GetNbItemsByCharacteristic(string charName)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task GetNbItemsByClass(Model.ChampionClass championClass)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task GetNbItemsByName(string substring)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task GetNbItemsByRunePage(RunePage? runePage)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task GetNbItemsBySkill(Skill? skill)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task GetNbItemsBySkill(string skill)
+ {
+ throw new NotImplementedException();
+ }
+
+ public async Task 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(); }
+ }
+ }
+ }
+ }
+}
diff --git a/Sources/EntityFramework/Manager/EFDataManager.Skins.cs b/Sources/EntityFramework/Manager/EFDataManager.Skins.cs
new file mode 100644
index 0000000..bed5678
--- /dev/null
+++ b/Sources/EntityFramework/Manager/EFDataManager.Skins.cs
@@ -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 AddItem(Skin? item)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task DeleteItem(Skin? item)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task> GetItems(int index, int count, string? orderingPropertyName = null, bool descending = false)
+ {
+ throw new NotImplementedException();
+ }
+
+ public async Task> 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> GetItemsByName(string substring, int index, int count, string? orderingPropertyName = null, bool descending = false)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task GetNbItems()
+ {
+ throw new NotImplementedException();
+ }
+
+ public async Task GetNbItemsByChampion(Champion? champion)
+ {
+ using(var context = new LoLDBContextWithStub())
+ {
+ return context.Skins.Where(c => c.Champion.Equals(champion.ToEntity())).Count();
+ }
+ }
+
+ public Task GetNbItemsByName(string substring)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task UpdateItem(Skin? oldItem, Skin? newItem)
+ {
+ throw new NotImplementedException();
+ }
+ }
+ }
+}
diff --git a/Sources/EntityFramework/Manager/EFDataManager.cs b/Sources/EntityFramework/Manager/EFDataManager.cs
new file mode 100644
index 0000000..5c5d677
--- /dev/null
+++ b/Sources/EntityFramework/Manager/EFDataManager.cs
@@ -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; }
+
+ }
+}
diff --git a/Sources/EntityFramework/Mapper/ChampionMapper.cs b/Sources/EntityFramework/Mapper/ChampionMapper.cs
new file mode 100644
index 0000000..da146b2
--- /dev/null
+++ b/Sources/EntityFramework/Mapper/ChampionMapper.cs
@@ -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);
+ }
+
+ }
+}
diff --git a/Sources/EntityFramework/Mapper/SkinMapper.cs b/Sources/EntityFramework/Mapper/SkinMapper.cs
new file mode 100644
index 0000000..3ce09ff
--- /dev/null
+++ b/Sources/EntityFramework/Mapper/SkinMapper.cs
@@ -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);
+ }
+
+
+ }
+}
diff --git a/Sources/EntityFramework/Program.cs b/Sources/EntityFramework/Program.cs
new file mode 100644
index 0000000..56915f8
--- /dev/null
+++ b/Sources/EntityFramework/Program.cs
@@ -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("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 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("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 { corichard } };
+ var rp2 = new RunePageEntity { Name = "RP2", Rune = new RuneEntity{ Name = "aaa", Description = "aaa", Family = EnumRuneFamily.Domination, Image = new LargeImage("base") }, Champion = new List { 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();
+
+
+//}
diff --git a/Sources/EntityFramework/RuneEntity.cs b/Sources/EntityFramework/RuneEntity.cs
new file mode 100644
index 0000000..c9de7da
--- /dev/null
+++ b/Sources/EntityFramework/RuneEntity.cs
@@ -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;
+ }
+}
diff --git a/Sources/EntityFramework/RunePageEntity.cs b/Sources/EntityFramework/RunePageEntity.cs
new file mode 100644
index 0000000..842806b
--- /dev/null
+++ b/Sources/EntityFramework/RunePageEntity.cs
@@ -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 Dico = new Dictionary();
+
+ // Pour le many to many Champion *<---->* RunePage
+ public ICollection Champion{ get; set; }
+
+
+
+ public void CheckRunes(EnumCategory newRuneCategory){}
+ public void CheckFamilies(EnumCategory cat1, EnumCategory cat2){}
+ public void UpdateMajorFamily(EnumCategory minor, bool expectedValue){}
+ }
+}
diff --git a/Sources/EntityFramework/SkillEntity.cs b/Sources/EntityFramework/SkillEntity.cs
new file mode 100644
index 0000000..505a427
--- /dev/null
+++ b/Sources/EntityFramework/SkillEntity.cs
@@ -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;
+ //}
+ }
+}
diff --git a/Sources/EntityFramework/SkinEntity.cs b/Sources/EntityFramework/SkinEntity.cs
new file mode 100644
index 0000000..e9650b3
--- /dev/null
+++ b/Sources/EntityFramework/SkinEntity.cs
@@ -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;
+ //}
+ }
+}
diff --git a/Sources/EntityFramework/StubbedContext.cs b/Sources/EntityFramework/StubbedContext.cs
new file mode 100644
index 0000000..3731035
--- /dev/null
+++ b/Sources/EntityFramework/StubbedContext.cs
@@ -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().HasData(corichard, pintrand);
+
+ modelBuilder.Entity().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().HasData(new { Name = "RP1", Rune = r1, Champion = corichard},
+ new { Name = "RP2", Rune = r2, Champion = pintrand}
+ );
+ }
+
+ }
+}
diff --git a/Sources/HttpClient/HttpClient.csproj b/Sources/HttpClient/HttpClient.csproj
new file mode 100644
index 0000000..9e4e01f
--- /dev/null
+++ b/Sources/HttpClient/HttpClient.csproj
@@ -0,0 +1,19 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Sources/HttpClient/HttpClientManager.Champion.cs b/Sources/HttpClient/HttpClientManager.Champion.cs
new file mode 100644
index 0000000..9ffc79b
--- /dev/null
+++ b/Sources/HttpClient/HttpClientManager.Champion.cs
@@ -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 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 DeleteItem(Champion? item)
+ {
+ HttpResponseMessage response = await httpc.DeleteAsync("/Champion?Name=" + item.Name);
+ return response.IsSuccessStatusCode;
+ }
+
+ public Task> GetItems(int index, int count, string? orderingPropertyName = null, bool descending = false)
+ {
+ return httpc.GetFromJsonAsync>("/Champion?index="+index+"&size="+count);
+ }
+
+
+
+
+
+ public Task> GetItemsByCharacteristic(string charName, int index, int count, string? orderingPropertyName = null, bool descending = false)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task> GetItemsByClass(ChampionClass championClass, int index, int count, string? orderingPropertyName = null, bool descending = false)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task> GetItemsByName(string substring, int index, int count, string? orderingPropertyName = null, bool descending = false)
+ {
+ return httpc.GetFromJsonAsync>("/Champion?name="+substring+"&index=" + index + "&size=" + count);
+ }
+
+ public Task> GetItemsByRunePage(RunePage? runePage, int index, int count, string? orderingPropertyName = null, bool descending = false)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task> GetItemsBySkill(Skill? skill, int index, int count, string? orderingPropertyName = null, bool descending = false)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task> GetItemsBySkill(string skill, int index, int count, string? orderingPropertyName = null, bool descending = false)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task GetNbItems()
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task GetNbItemsByCharacteristic(string charName)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task GetNbItemsByClass(ChampionClass championClass)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task GetNbItemsByName(string substring)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task GetNbItemsByRunePage(RunePage? runePage)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task GetNbItemsBySkill(Skill? skill)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task GetNbItemsBySkill(string skill)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task UpdateItem(Champion? oldItem, Champion? newItem)
+ {
+ throw new NotImplementedException();
+ }
+ }
+ }
+}
diff --git a/Sources/HttpClient/HttpClientManager.cs b/Sources/HttpClient/HttpClientManager.cs
new file mode 100644
index 0000000..49ddb70
--- /dev/null
+++ b/Sources/HttpClient/HttpClientManager.cs
@@ -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; }
+
+ }
+}
diff --git a/Sources/LeagueOfLegends.sln b/Sources/LeagueOfLegends.sln
index 5339e1f..007e972 100644
--- a/Sources/LeagueOfLegends.sln
+++ b/Sources/LeagueOfLegends.sln
@@ -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}
diff --git a/Sources/Model/Properties/launchSettings.json b/Sources/Model/Properties/launchSettings.json
new file mode 100644
index 0000000..ed8cba2
--- /dev/null
+++ b/Sources/Model/Properties/launchSettings.json
@@ -0,0 +1,12 @@
+{
+ "profiles": {
+ "Model": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "applicationUrl": "https://localhost:49972;http://localhost:49973"
+ }
+ }
+}
\ No newline at end of file
diff --git a/Sources/StubLib/StubData.Champions.cs b/Sources/StubLib/StubData.Champions.cs
index ad19275..90a33d9 100644
--- a/Sources/StubLib/StubData.Champions.cs
+++ b/Sources/StubLib/StubData.Champions.cs
@@ -8,7 +8,7 @@ namespace StubLib
private List 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),
diff --git a/Sources/Tests/ConsoleTests/ConsoleTests.csproj b/Sources/Tests/ConsoleTests/ConsoleTests.csproj
index 1602b94..d401cce 100644
--- a/Sources/Tests/ConsoleTests/ConsoleTests.csproj
+++ b/Sources/Tests/ConsoleTests/ConsoleTests.csproj
@@ -1,4 +1,4 @@
-
+
Exe
@@ -8,6 +8,7 @@
+
diff --git a/Sources/Tests/ConsoleTests/Properties/launchSettings.json b/Sources/Tests/ConsoleTests/Properties/launchSettings.json
new file mode 100644
index 0000000..c8ab57c
--- /dev/null
+++ b/Sources/Tests/ConsoleTests/Properties/launchSettings.json
@@ -0,0 +1,12 @@
+{
+ "profiles": {
+ "ConsoleTests": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "applicationUrl": "https://localhost:49970;http://localhost:49971"
+ }
+ }
+}
\ No newline at end of file
diff --git a/Sources/Tests/Tests.csproj b/Sources/Tests/Tests.csproj
new file mode 100644
index 0000000..01bb70b
--- /dev/null
+++ b/Sources/Tests/Tests.csproj
@@ -0,0 +1,18 @@
+
+
+
+ net7.0
+ enable
+ enable
+
+ false
+
+
+
+
+
+
+
+
+
+
diff --git a/Sources/Tests/UnitTest1.cs b/Sources/Tests/UnitTest1.cs
new file mode 100644
index 0000000..872f935
--- /dev/null
+++ b/Sources/Tests/UnitTest1.cs
@@ -0,0 +1,10 @@
+namespace Tests;
+
+[TestClass]
+public class UnitTest1
+{
+ [TestMethod]
+ public void TestMethod1()
+ {
+ }
+}
\ No newline at end of file
diff --git a/Sources/Tests/Usings.cs b/Sources/Tests/Usings.cs
new file mode 100644
index 0000000..ab67c7e
--- /dev/null
+++ b/Sources/Tests/Usings.cs
@@ -0,0 +1 @@
+global using Microsoft.VisualStudio.TestTools.UnitTesting;
\ No newline at end of file