Compare commits

...

43 Commits

Author SHA1 Message Date
Lucas DELANIER d61badd2c1 Mise à jour de 'README.md'
continuous-integration/drone/push Build is failing Details
2 years ago
Louison PARANT 43e79ad879 Mise à jour de 'README.md'
continuous-integration/drone/push Build is failing Details
2 years ago
Louison PARANT 30006c2a05 merge EF master
continuous-integration/drone/push Build is failing Details
2 years ago
Louison PARANT 9d5bb44db7 merge EF
2 years ago
Louison PARANT 954a5beaf4 merge
2 years ago
Lucas Delanier 320af91c4d Merge branch 'master' of https://codefirst.iut.uca.fr/git/lucas.delanier/LOLProject
continuous-integration/drone/push Build is failing Details
2 years ago
Lucas Delanier ec30c62a53 ut
2 years ago
Lucas DELANIER 6ad3d04bfc Mise à jour de 'README.md'
continuous-integration/drone/push Build is failing Details
2 years ago
Lucas DELANIER 85f983101b Mise à jour de 'README.md'
continuous-integration/drone/push Build is failing Details
2 years ago
Lucas DELANIER 2375d451ac Transférer les fichiers vers 'Documentations'
continuous-integration/drone/push Build is failing Details
2 years ago
Lucas DELANIER 977038d6e1 Mise à jour de 'README.md'
continuous-integration/drone/push Build is failing Details
2 years ago
Lucas DELANIER c3bf8ae799 Transférer les fichiers vers 'Documentations'
continuous-integration/drone/push Build is failing Details
2 years ago
Lucas DELANIER 759fb1d702 Transférer les fichiers vers 'Documentations'
continuous-integration/drone/push Build is failing Details
2 years ago
Lucas DELANIER 466e5d1742 Mise à jour de 'README.md'
continuous-integration/drone/push Build is failing Details
2 years ago
Lucas DELANIER 86db87a6b4 Mise à jour de 'README.md'
continuous-integration/drone/push Build is failing Details
2 years ago
Lucas DELANIER 9c510c1169 Transférer les fichiers vers 'Documentations'
continuous-integration/drone/push Build is failing Details
2 years ago
Lucas DELANIER d3a6115aab Transférer les fichiers vers 'Documentations'
continuous-integration/drone/push Build is failing Details
2 years ago
Lucas Delanier 9d9d1633e9 Merge branch 'master' of https://codefirst.iut.uca.fr/git/lucas.delanier/LOLProject
continuous-integration/drone/push Build is failing Details
2 years ago
Lucas Delanier 740c953f3d update v2
2 years ago
Lucas DELANIER 9e060e989c Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
2 years ago
Louison PARANT b343313730 Mise à jour de 'README.md'
continuous-integration/drone/push Build is failing Details
2 years ago
Louison PARANT d6e1228511 Mise à jour de 'README.md'
continuous-integration/drone/push Build is failing Details
2 years ago
Louison PARANT d10e81e08b Mise à jour de 'README.md'
continuous-integration/drone/push Build is failing Details
2 years ago
Louison PARANT 5b561762aa Supprimer 'Documentations/Group 13.png'
continuous-integration/drone/push Build is failing Details
2 years ago
Louison PARANT ccb1ebea3f Transférer les fichiers vers 'Documentations'
continuous-integration/drone/push Build is failing Details
2 years ago
Louison PARANT b0200bf1a9 Supprimer 'Mask group.png'
continuous-integration/drone/push Build is failing Details
2 years ago
Louison PARANT 5a3155e5a9 Transférer les fichiers vers ''
continuous-integration/drone/push Build is failing Details
2 years ago
Lucas DELANIER ed176bd5d7 Mise à jour de 'README.md'
continuous-integration/drone/push Build is failing Details
2 years ago
Lucas DELANIER 429aacf744 Mise à jour de 'README.md'
2 years ago
Lucas DELANIER a6915bff52 Mise à jour de 'README.md'
continuous-integration/drone/push Build is failing Details
2 years ago
Lucas Delanier 65a211fd85 test ci
continuous-integration/drone/push Build is failing Details
2 years ago
Lucas Delanier f0e9f43284 Merge branch 'master' of https://codefirst.iut.uca.fr/git/lucas.delanier/LOLProject
continuous-integration/drone/push Build is failing Details
2 years ago
Lucas Delanier 55447bf403 push
2 years ago
Louison PARANT bce3933e33 Mise à jour de 'README.md'
continuous-integration/drone/push Build is failing Details
2 years ago
Louison PARANT 8ddb7d39a8 Mise à jour de 'README.md'
continuous-integration/drone/push Build is failing Details
2 years ago
Lucas Delanier c14dd95142 push merge
continuous-integration/drone/push Build is failing Details
2 years ago
Lucas Delanier 1dcd5db1fc Merge branch 'master' of https://codefirst.iut.uca.fr/git/lucas.delanier/LOLProject
continuous-integration/drone/push Build is failing Details
2 years ago
Lucas Delanier 78c79cfea1 merge master
2 years ago
Lucas DELANIER 42be77e907 Transférer les fichiers vers 'Documentations'
continuous-integration/drone/push Build is passing Details
2 years ago
Lucas DELANIER 2dd3fd8088 Mise à jour de 'README.md'
continuous-integration/drone/push Build is passing Details
2 years ago
Lucas DELANIER 61524f2bb0 Mise à jour de 'README.md'
continuous-integration/drone/push Build is passing Details
2 years ago
Lucas DELANIER 920efc3bec Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
2 years ago
Lucas Delanier 306d637b53 test ignored
continuous-integration/drone/push Build is passing Details
2 years ago

@ -26,25 +26,24 @@ steps:
- dotnet test LeagueOfLegends.sln --no-restore
depends_on: [build]
#- 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:TEST /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]
- 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:LOLProject /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: [ SONAR_TOKEN ]
settings:
sonar_host: https://codefirst.iut.uca.fr/sonar/
sonar_token:
from_secret: SONAR_TOKEN
depends_on: [tests]
- name: generate-and-deploy-docs
image: hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-docdeployer
@ -77,7 +76,7 @@ steps:
image: hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-dockerproxy-clientdrone:latest
environment:
IMAGENAME: hub.codefirst.iut.uca.fr/lucas.delanier/lolproject:latest
CONTAINERNAME: container_lol
CONTAINERNAME: containerlol
COMMAND: create
OVERWRITE: true
volumes:

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

@ -1,168 +1,97 @@
# prepaLoL
## Diagramme de classes du modèle
```mermaid
classDiagram
class LargeImage{
+/Base64 : string
}
class Champion{
+/Name : string
+/Bio : string
+/Icon : string
+/Characteristics : Dictionary~string, int~
~ AddSkin(skin : Skin) bool
~ RemoveSkin(skin: Skin) bool
+ AddSkill(skill: Skill) bool
+ RemoveSkill(skill: Skill) bool
+ AddCharacteristics(someCharacteristics : params Tuple~string, int~[])
+ RemoveCharacteristics(label : string) bool
+ this~label : string~ : int?
}
Champion --> "1" LargeImage : Image
class ChampionClass{
<<enumeration>>
Unknown,
Assassin,
Fighter,
Mage,
Marksman,
Support,
Tank,
}
Champion --> "1" ChampionClass : Class
class Skin{
+/Name : string
+/Description : string
+/Icon : string
+/Price : float
}
Skin --> "1" LargeImage : Image
Champion "1" -- "*" Skin
class Skill{
+/Name : string
+/Description : string
}
class SkillType{
<<enumeration>>
Unknown,
Basic,
Passive,
Ultimate,
}
Skill --> "1" SkillType : Type
Champion --> "*" Skill
class Rune{
+/Name : string
+/Description : string
}
Rune --> "1" LargeImage : Image
class RuneFamily{
<<enumeration>>
Unknown,
Precision,
Domination
}
Rune --> "1" RuneFamily : Family
class Category{
<<enumeration>>
Major,
Minor1,
Minor2,
Minor3,
OtherMinor1,
OtherMinor2
}
class RunePage{
+/Name : string
+/this[category : Category] : Rune?
- CheckRunes(newRuneCategory : Category)
- CheckFamilies(cat1 : Category, cat2 : Category) bool?
- UpdateMajorFamily(minor : Category, expectedValue : bool)
}
RunePage --> "*" Rune : Dictionary~Category,Rune~
```
## Diagramme de classes des interfaces de gestion de l'accès aux données
```mermaid
classDiagram
direction LR;
class IGenericDataManager~T~{
<<interface>>
GetNbItems() Task~int~
GetItems(index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~T~~
GetNbItemsByName(substring : string)
GetItemsByName(substring : string, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~T~~
UpdateItem(oldItem : T, newItem : T) Task~T~~
AddItem(item : T) Task~T~
DeleteItem(item : T) Task~bool~
}
class IChampionsManager{
<<interface>>
GetNbItemsByCharacteristic(charName : string)
GetItemsByCharacteristic(charName : string, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~Champion?~~
GetNbItemsByClass(championClass : ChampionClass)
GetItemsByClass(championClass : ChampionClass, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~Champion?~~
GetNbItemsBySkill(skill : Skill?)
GetItemsBySkill(skill : Skill?, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~Champion?~~
GetNbItemsBySkill(skill : string)
GetItemsBySkill(skill : string, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~Champion?~~
GetNbItemsByRunePage(runePage : RunePage?)
GetItemsByRunePage(runePage : RunePage?, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~Champion?~~
}
class ISkinsManager{
<<interface>>
GetNbItemsByChampion(champion : Champion?)
GetItemsByChampion(champion : Champion?, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~Skin?~~
}
class IRunesManager{
<<interface>>
GetNbItemsByFamily(family : RuneFamily)
GetItemsByFamily(family : RuneFamily, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~Rune?~~
}
class IRunePagesManager{
<<interface>>
GetNbItemsByRune(rune : Rune?)
GetItemsByRune(rune : Rune?, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~RunePage?~~
GetNbItemsByChampion(champion : Champion?)
GetItemsByChampion(champion : Champion?, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~RunePage?~~
}
IGenericDataManager~Champion?~ <|.. IChampionsManager : T--Champion?
IGenericDataManager~Skin?~ <|.. ISkinsManager : T--Skin?
IGenericDataManager~Rune?~ <|.. IRunesManager : T--Rune?
IGenericDataManager~RunePage?~ <|.. IRunePagesManager : T--RunePage?
class IDataManager{
<<interface>>
}
IChampionsManager <-- IDataManager : ChampionsMgr
ISkinsManager <-- IDataManager : SkinsMgr
IRunesManager <-- IDataManager : RunesMgr
IRunePagesManager <-- IDataManager : RunePagesMgr
```
## Diagramme de classes simplifié du Stub
```mermaid
classDiagram
direction TB;
IDataManager <|.. StubData
ChampionsManager ..|> IChampionsManager
StubData --> ChampionsManager
RunesManager ..|> IRunesManager
StubData --> RunesManager
RunePagesManager ..|> IRunePagesManager
StubData --> RunePagesManager
SkinsManager ..|> ISkinsManager
StubData --> SkinsManager
StubData --> RunesManager
StubData --> "*" Champion
StubData --> "*" Rune
StubData --> "*" RunePages
StubData --> "*" Skins
```
## LOLProject
**LOLProject** est un projet reliant une API C# et EntityFramework afin de produire une API qui renvoie les informations d'une base de données SQLite sur un client MAUI
Merci de noter la v1 de l'api qui est tenu a jour la v2 sert uniquement a montrer que nous pouvons versionner.
## :floppy_disk: FEATURES
- L'API dispose des principales requêtes CRUD sur les champions, skills, skins, runes, runepages aussi consultables sur le swagger UI.
- L'ORM réalisé avec EntityFramework afin d'enregistrer dans une base de données SQLite
- L'application MAUI pour faire des requêtes depuis un client et les afficher.
![](https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png)
## :dizzy: Getting Started
Une fois le dépot cloné, vous pouvez lancer le code sur votre téléphone Android grâce à l'outil Android Studio ou grâce à un émulateur Android.
## Architecture
![](https://codefirst.iut.uca.fr/git/lucas.delanier/LOLProject/raw/branch/master/Documentations/Schema_architecture.png)
Ce schéma d'architecure globale permet de comprendre la composition interne de la solution.
Sur la partie gauche on peut voir la partie client qui fait appel a l'api via des requetes http en utilisant les routes de l'api Rest Full.
Pour tout a fait comprendre, comment communiquent et fonctionnent les différentes briques de la solution nous allons vous détailler brique par brique, relation par relation les différentes point rouge du schéma.
## 1 - La déserialization
Le client est une solution qui va intérragir avec notre api grace des requetes sur internet. Il nécessite donc impérativement d'une connexion internet afin de pouvoir communiquer grace a des requetes http(s). Une fois qu'il a récupéré les données demandé. Il doit transoformer ce document json en classe métier de son model. Cela s'appel la déserialization. Ce processus ce traduit ar le code suivant en C#.
![](https://codefirst.iut.uca.fr/git/lucas.delanier/LOLProject/raw/branch/master/Documentations/Capture%20d%27%C3%A9cran%202023-03-26%20111526.png)
## 2 - La communication Client - Api
Maintenant que vous savez comment le client traite les données renvoyées par l'API, nous allons a présent voir comment ils communiquent entre eux. Cette communication se fait par des requetes http(s) sous la forme suivante.
"codefirst.iut.uca.fr/containers/lucasdelanier-containerlol/api/v{version}/{controller}"
Lors de l'appel de l'API, le client peut choisir la version ( v1, v2, etc) mais aussi indiquer le controlleur qu'il souhaite intérroger. Par exemple Champion lui permettra de récuperer des informations sur les champions que connait l'API. Il est aussi possible de rajouter de précisions en ajoutant par exemple un nom apres le controller pour demander les informations spécifique a un champion en particulié. Lors des communications, les objects sons traduit sous la forme DTO. Cela permet de controller l'envoie de certaines données au client comme pr exemple un id unique ou des données sensibles qui ne doivent pas etre connu par l'utilisateur. Voici un exemple.
![](https://codefirst.iut.uca.fr/git/lucas.delanier/LOLProject/raw/branch/master/Documentations/Capture%20d%27%C3%A9cran%202023-03-26%20113439.png)
Ci dessus on voit que l'object champion a une nouvelle "forme" ChampionDTO que l'on construit a partir des attributs d'un champion. Dans l'exemple, il reprend les memes informations qu'un champion mais on aurait put imaginer qu'il en perde certains que l'on ne veut pas renvoyer a l'utilisateur. Pour permettre le passage d'un DTO en object et d'un object en DTO il faut ce qu'on appel des Mappers. Voici l'exemple des méthodes ToModel() et ToDTO()
![](https://codefirst.iut.uca.fr/git/lucas.delanier/LOLProject/raw/branch/master/Documentations/Capture%20d%27%C3%A9cran%202023-03-26%20113710.png)
## 3 - L'utilisation du stub dans l'API
Avant de faire la relation avec une base de données. Il était impotant de pouvoir tester l'application avec un Stub qui est une classe contenant des listes d'object. Une sorte de base de données fictive. Pour permettre a l'api d'intéroger ce stub, il a fallut faire un manager spécialement destiné à l'utilisation du stub (StubData) qui hérite d'un manager commun qui est une interface composé des méthodes nécessaire a l'interrogation des données (IDataManager).
![](https://codefirst.iut.uca.fr/git/lucas.delanier/LOLProject/raw/branch/master/Documentations/Capture%20d%27%C3%A9cran%202023-03-26%20114811.png)
## 4 - Lien entre API et Entityframework
Pour relier l'API avec la partie EntityFramework, cela se passe du côté de l'API. En effet, en ayant implémenter des managers en EntityFramework, il suffit de les instancier côté API puis de demander la requête adéquate pour obtenir les données de la base de données avec l'API. Ces managers regroupent plusieurs petits managers gérant chacun une entité de la base de données (Champion, RunePage, Rune, ...). Il n'y a pas de managers de Skill car ceux-ci sont compris dans le manager Champion (un peu comme les mappers côté API).
## 5 - Mappage des classes métier en tables
Afin de rentrer les classes métiers en base de données, il faut avant tout les mapper. Ainsi, il y a un mapper pour chaque entité de la base de données (même pour Skill par exemple). Ensuite, il faut deux méthodes pour chaque mapper :
<br> 1- ToEntity : elle prend en paramètre un objet du modèle et permet de le transformer en entité afin de pouvoir l'insérer en base de données.
<br> 2- ToModel : elle prend en paramètre une entité et permet de la transformer en objet.
Grâce à ces deux méthodes, nous pouvons facilement mapper des entités en objet et inversement.
## 6 - Lien avec base de données SQLite
Il y a deux manières d'utiliser la base de données SQLite. On peut soit, utiliser la base de données interne à l'appareil ou bien utiliser la mémoire de l'appareil pour sauvegarder les données en local. Pour créer la base, il faut avoir des classes entités représentant chacune une table de la base. Il peut aussi y avoir des entités représentant des liaisons entre deux tables (RunePageRuneEntity par exemple représente la table entre RunePage et Rune). Ensuite, il faut un contexte (SQLiteContext pour notre projet) qui a pour attributs des DbSets, des listes d'entités à mettre en base de données. Pour remplir la base de données, avec un Stub par exemple, on peut utiliser la méthode onCreate du contexte pour insérer des entités créees manuellement. Cependant, pour mettre des objets en base, il faut donc les mapper en entité puis, passer par un manager (dans notre cas) pour enfin le rentrer en base.
## :wrench: SUPPORT
En cas de problème lors de l'utilisation de l'application, vous pouvez nous contacter aux adresses suivantes :
Lucas Delanier : **Lucas.DELANIER@etu.uca.fr** </br>
Louison Parant : **Louison.PARANT@etu.uca.fr**
![](https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png)
## ✨ Contributors
<a href = "https://codefirst.iut.uca.fr/git/lucas.delanier">
<img src ="https://codefirst.iut.uca.fr/git/avatars/6a3835d734392fccff3949f7c82a63b9?size=870" height="50px">
</a>
<a href = "https://codefirst.iut.uca.fr/git/louison.parant">
<img src ="https://codefirst.iut.uca.fr/git/avatars/b337a607f680a2d9af25eb09ea457be9?size=870" height="50px">
</a>

@ -19,6 +19,8 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Design" Version="1.1.6" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="Swashbuckle.Core" Version="5.6.0" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.abstractions" Version="2.0.3" />
</ItemGroup>
<ItemGroup>

@ -12,7 +12,7 @@ namespace APILOL.Controllers.v2
{
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiVersion("2")]
[ApiVersion("2.0")]
public class ChampionsController : ControllerBase
{
@ -24,18 +24,17 @@ namespace APILOL.Controllers.v2
{
this.dataManager = dataManager.ChampionsMgr;
this._logger = logger;
}
// GET: api/<ChampionController>
[MapToApiVersion("2")]
[MapToApiVersion("2.0")]
[HttpGet]
public async Task<IActionResult> Get([FromQuery] PageRequest request)
{
_logger.LogInformation("API call - [GET] - CHAMPION");
_logger.LogInformation("API call - [GET] - CHAMPION ");
try
{
@ -44,48 +43,50 @@ namespace APILOL.Controllers.v2
IEnumerable<ChampionDTO> items = champions.Select(c => c.ToDto());
if (items.Count() == 0)
{
_logger.LogInformation("No champion found.");
_logger.LogError("No champion found.");
return NotFound("No champion found.");
}
return Ok(new { data = items, count = await dataManager.GetNbItems(), offset = request.Offset, limit = request.Limit });
}
catch(Exception error)
catch (Exception error)
{
_logger.LogInformation("Error in the request");
return BadRequest(error.Message);
}
}
// GET api/<ChampionController>/5
[MapToApiVersion("2")]
[MapToApiVersion("2.0")]
[HttpGet("{name}")]
public async Task<IActionResult> Get([FromQuery] PageRequest request,string name)
public async Task<IActionResult> Get([FromQuery] PageRequest request, string name)
{
_logger.LogInformation("API call - [GET / NAME] - CHAMPION");
_logger.LogInformation("API call - [GET / NAME] - CHAMPION {name}", name);
try
{
if (dataManager.GetNbItemsByName(name) != null)
{
var champions = await dataManager.GetItemsByName(name, request.Offset, request.Limit, request.OrderingPropertyName, request.IsDesc);
IEnumerable <ChampionDTO> items = champions.Select(c => c.ToDto());
IEnumerable<ChampionDTO> items = champions.Select(c => c.ToDto());
if (items.Count() == 0)
{
_logger.LogInformation("No champion found.");
_logger.LogError("No champion found.");
return NotFound("No champion found.");
}
return Ok(items);
return Ok(new { data = items, count = dataManager.GetNbItems() });
}
return NotFound("No champion matching with this name.");
}
catch (Exception error)
{
_logger.LogInformation("Error in the request");
return BadRequest(error.Message);
}
}
// POST api/<ChampionController>
[MapToApiVersion("2")]
[MapToApiVersion("2.0")]
[HttpPost]
public async Task<IActionResult> Post([FromBody] ChampionDTO championDTO)
{
@ -93,12 +94,12 @@ namespace APILOL.Controllers.v2
try
{
if(await dataManager.GetNbItemsByName(championDTO.Name) == 0)
if (await dataManager.GetNbItemsByName(championDTO.Name) == 0)
{
await dataManager.AddItem(championDTO.ToModel());
return CreatedAtAction(nameof(Get), championDTO);
}
_logger.LogInformation("A champion already exist with this Name. ( Unique Name )");
_logger.LogError("A champion already exist with this Name. ( Unique Name )");
return BadRequest("A champion already exist with this Name. ( Unique Name )");
}
catch (Exception error)
@ -109,7 +110,7 @@ namespace APILOL.Controllers.v2
}
// PUT api/<ChampionController>/5
[MapToApiVersion("2")]
[MapToApiVersion("2.0")]
[HttpPut("{name}")]
public async Task<IActionResult> PutAsync(string name, [FromBody] ChampionDTO championDTO)
{
@ -118,24 +119,24 @@ namespace APILOL.Controllers.v2
{
var champion = await dataManager
.GetItemsByName(name, 0, await dataManager.GetNbItems());
Console.WriteLine(champion.First().Name) ;
Console.WriteLine(champion.First().Name);
var champion2 = await dataManager
.GetItemsByName(championDTO.Name, 0, await dataManager.GetNbItems());
if (champion != null)
{
if(champion2.Count() == 0)
if (champion2.Count() == 0)
{
await dataManager.UpdateItem(champion.First(), championDTO.ToModel());
return Ok();
}
_logger.LogInformation("champion already exist with this unique name.");
_logger.LogError("champion already exist with this unique name.");
return BadRequest("champion already exist with this unique name.");
}
else
{
_logger.LogInformation("champion not found.");
_logger.LogError("champion not found.");
return NotFound("champion not found.");
}
await dataManager.UpdateItem(champion.First(), championDTO.ToModel());
@ -144,13 +145,14 @@ namespace APILOL.Controllers.v2
}
catch (Exception e)
{
_logger.LogInformation("Error in the request");
return BadRequest(e.Message);
}
}
// DELETE api/<ChampionController>/5
[MapToApiVersion("2")]
[MapToApiVersion("2.0")]
[HttpDelete("{name}")]
public async Task<IActionResult> Delete(string name)
{
@ -158,7 +160,7 @@ namespace APILOL.Controllers.v2
try
{
var champion = await (dataManager.GetItemsByName(name, 0, await dataManager.GetNbItems()));
if (champion.Count() != 0)
{
var championDto = champion.First().ToDto();
@ -167,13 +169,14 @@ namespace APILOL.Controllers.v2
}
else
{
_logger.LogInformation("No matching Champion with this name");
_logger.LogError("No matching Champion with this name");
return NotFound("No matching Champion with this name");
}
}
catch(Exception error)
catch (Exception error)
{
_logger.LogInformation("Error in the request");
return BadRequest(error);
}
}

@ -11,7 +11,7 @@ namespace APILOL.Controllers.v2
{
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiVersion("2")]
[ApiVersion("2.0")]
public class RuneController : ControllerBase
{
IRunesManager dataManager;
@ -28,7 +28,7 @@ namespace APILOL.Controllers.v2
// GET: api/<RuneController>
[MapToApiVersion("2")]
[MapToApiVersion("2.0")]
[HttpGet]
public async Task<IActionResult> Get([FromQuery] PageRequest request)
{
@ -54,7 +54,7 @@ namespace APILOL.Controllers.v2
}
// GET api/<RuneController>/5
[MapToApiVersion("2")]
[MapToApiVersion("2.0")]
[HttpGet("{name}")]
public async Task<IActionResult> Get([FromQuery] PageRequest request, string name)
{
@ -82,7 +82,7 @@ namespace APILOL.Controllers.v2
}
// POST api/<RuneController>
[MapToApiVersion("2")]
[MapToApiVersion("2.0")]
[HttpPost]
public async Task<IActionResult> Post([FromBody] RuneDTO runeDTO)
{
@ -106,7 +106,7 @@ namespace APILOL.Controllers.v2
}
// PUT api/<Rune>/5
[MapToApiVersion("2")]
[MapToApiVersion("2.0")]
[HttpPut("{name}")]
public async Task<IActionResult> PutAsync(string name, [FromBody] RuneDTO runeDTO)
{
@ -147,7 +147,7 @@ namespace APILOL.Controllers.v2
}
// DELETE api/<RuneController>/5
[MapToApiVersion("2")]
[MapToApiVersion("2.0")]
[HttpDelete("{name}")]
public async Task<IActionResult> Delete(string name)
{

@ -11,7 +11,7 @@ namespace APILOL.Controllers.v2
{
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiVersion("2")]
[ApiVersion("2.0")]
public class RunePageController : ControllerBase
{
IRunePagesManager dataManager;
@ -28,7 +28,7 @@ namespace APILOL.Controllers.v2
// GET: api/<RunePageController>
[MapToApiVersion("2")]
[MapToApiVersion("2.0")]
[HttpGet]
public async Task<IActionResult> Get([FromQuery] PageRequest request)
{
@ -54,11 +54,11 @@ namespace APILOL.Controllers.v2
}
// GET api/<RunePageController>/5
[MapToApiVersion("2")]
[MapToApiVersion("2.0")]
[HttpGet("{name}")]
public async Task<IActionResult> Get([FromQuery] PageRequest request, string name)
{
_logger.LogInformation("API call - [GET / NAME] - RUNEPAGE {name}",name);
_logger.LogInformation("API call - [GET / NAME] - RUNEPAGE");
try
{
if (dataManager.GetNbItemsByName(name) != null)
@ -82,7 +82,7 @@ namespace APILOL.Controllers.v2
}
// POST api/<RunePageController>
[MapToApiVersion("2")]
[MapToApiVersion("2.0")]
[HttpPost]
public async Task<IActionResult> Post([FromBody] RunePageDTO runePageDTO)
{
@ -106,11 +106,11 @@ namespace APILOL.Controllers.v2
}
// PUT api/<RunePage>/5
[MapToApiVersion("2")]
[MapToApiVersion("2.0")]
[HttpPut("{name}")]
public async Task<IActionResult> PutAsync(string name, [FromBody] RunePageDTO runePageDTO)
{
_logger.LogInformation("API call - [PUT / NAME] - RUNEPAGE {name}", name);
_logger.LogInformation("API call - [PUT / NAME] - RUNEPAGE");
try
{
var runePage = await dataManager
@ -147,11 +147,11 @@ namespace APILOL.Controllers.v2
}
// DELETE api/<RunePageController>/5
[MapToApiVersion("2")]
[MapToApiVersion("2.0")]
[HttpDelete("{name}")]
public async Task<IActionResult> Delete(string name)
{
_logger.LogInformation("API call - [DELETE / NAME] - RUNEPAGE {name}", name);
_logger.LogInformation("API call - [DELETE / NAME] - RUNEPAGE");
try
{
var runePage = await (dataManager.GetItemsByName(name, 0, await dataManager.GetNbItems()));

@ -8,7 +8,7 @@ namespace APILOL.Controllers.v2
{
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiVersion("2")]
[ApiVersion("2.0")]
public class SkinController : ControllerBase
{
@ -26,7 +26,7 @@ namespace APILOL.Controllers.v2
// GET: api/<SkinController>
[MapToApiVersion("2")]
[MapToApiVersion("2.0")]
[HttpGet]
public async Task<IActionResult> Get([FromQuery] PageRequest request)
{
@ -52,11 +52,11 @@ namespace APILOL.Controllers.v2
}
// GET api/<SkinController>/5
[MapToApiVersion("2")]
[MapToApiVersion("2.0")]
[HttpGet("{name}")]
public async Task<IActionResult> Get([FromQuery] PageRequest request, string name)
{
_logger.LogInformation("API call - [GET / NAME] - SKIN {name}", name);
_logger.LogInformation("API call - [GET / NAME] - SKIN");
try
{
if (dataManager.GetNbItemsByName(name) != null)
@ -80,11 +80,11 @@ namespace APILOL.Controllers.v2
}
// POST api/<SkinController>
[MapToApiVersion("2")]
[MapToApiVersion("2.0")]
[HttpPost]
public async Task<IActionResult> Post([FromBody] SkinDTO skinDTO)
{
_logger.LogInformation("API call - [POST] - SKIN ");
_logger.LogInformation("API call - [POST] - SKIN");
try
{
@ -104,7 +104,7 @@ namespace APILOL.Controllers.v2
}
// PUT api/<Skin>/5
[MapToApiVersion("2")]
[MapToApiVersion("2.0")]
[HttpPut("{name}")]
public async Task<IActionResult> PutAsync(string name, [FromBody] SkinDTO skinDTO)
{
@ -145,7 +145,7 @@ namespace APILOL.Controllers.v2
}
// DELETE api/<SkinController>/5
[MapToApiVersion("2")]
[MapToApiVersion("2.0")]
[HttpDelete("{name}")]
public async Task<IActionResult> Delete(string name)
{

@ -16,8 +16,7 @@ namespace APILOL.Mapper
Class = champion.Class,
Icon = champion.Icon,
Image = champion.Image,
Characteristics = champion.Characteristics,
Skills = champion.Skills,
Skills = champion.Skills.Select(skill => skill.ToDto()),
};
}

@ -27,5 +27,20 @@ namespace APILOL.Mapper
public static Skill ToModel(this SkillEntity entity)
=> new(entity.Name, entity.Type, entity.Description);
public static SkillDTO ToDto(this Skill skill)
{
return new SkillDTO()
{
Type = skill.Type,
Name = skill.Name,
Description = skill.Description
};
}
public static Skill ToModel(this SkillDTO skill)
{
return new Skill(skill.Name, skill.Type, skill.Description);
}
}
}

@ -16,8 +16,7 @@ namespace DTO
public LargeImage Image { get; set; }
public ReadOnlyDictionary<string, int> Characteristics { get; set; }
public ImmutableHashSet<Skill> Skills { get; set; }
public IEnumerable<SkillDTO> Skills { get; set; }
}
}

@ -14,6 +14,8 @@
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Design" Version="1.1.6" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.abstractions" Version="2.0.3" />
</ItemGroup>
<ItemGroup>

@ -15,4 +15,6 @@ namespace DTO
public string Description { get; set; }
}
}

@ -19,6 +19,8 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.abstractions" Version="2.0.3" />
</ItemGroup>
<ItemGroup>

@ -23,7 +23,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EntityFrameworkLOL", "Entit
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUnitaire", "TestUnitaire\TestUnitaire.csproj", "{D24FBC48-F9C3-45CA-8D51-A851559C307F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ManagersEF", "ManagersEF\ManagersEF.csproj", "{A8685E74-67E4-4382-AF91-38045AC0014B}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ManagersEF", "ManagersEF\ManagersEF.csproj", "{A8685E74-67E4-4382-AF91-38045AC0014B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestEF", "TestEF\TestEF.csproj", "{81CEA57F-3CCB-4CF8-8315-2B5BC403E0FD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -67,6 +69,10 @@ Global
{A8685E74-67E4-4382-AF91-38045AC0014B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A8685E74-67E4-4382-AF91-38045AC0014B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A8685E74-67E4-4382-AF91-38045AC0014B}.Release|Any CPU.Build.0 = Release|Any CPU
{81CEA57F-3CCB-4CF8-8315-2B5BC403E0FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{81CEA57F-3CCB-4CF8-8315-2B5BC403E0FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{81CEA57F-3CCB-4CF8-8315-2B5BC403E0FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{81CEA57F-3CCB-4CF8-8315-2B5BC403E0FD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

@ -6,6 +6,11 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.abstractions" Version="2.0.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Model\Model.csproj" />
<ProjectReference Include="..\EntityFrameworkLOL\EntityFrameworkLOL.csproj" />

@ -20,6 +20,8 @@
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Design" Version="1.1.6" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.abstractions" Version="2.0.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\Shared.csproj" />

@ -14,6 +14,8 @@
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Design" Version="1.1.6" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.abstractions" Version="2.0.3" />
</ItemGroup>
</Project>

@ -14,6 +14,8 @@
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Design" Version="1.1.6" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.abstractions" Version="2.0.3" />
</ItemGroup>
<ItemGroup>

@ -0,0 +1,189 @@
using EntityFrameworkLOL.Entities;
using EntityFrameworkLOL.DBContexts;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Model;
using Shared;
using System.Xml.Linq;
using Xunit.Abstractions;
using Xunit;
using ManagersEF;
namespace TestEF
{
public class TestChampions
{
[Fact]
public async void Test_Add()
{
var connection = new SqliteConnection("DataSource=:memory:");
connection.Open();
var options = new DbContextOptionsBuilder<SQLiteContext>()
.UseSqlite(connection)
.Options;
using (var context = new SQLiteContext(options))
{
var manager = new EFManager(context).ChampionsMgr;
context.Database.EnsureCreated();
Champion batman = new("Batman", ChampionClass.Assassin, "icon_1", "image_1", "L'ombre de la nuit");
batman.AddSkill(new("Bat-signal", SkillType.Basic, "Envoie le signal"));
batman.AddCharacteristics(new[] {
Tuple.Create("Force", 150),
Tuple.Create("Agilité", 500)
});
Champion endeavor = new("Endeavor", ChampionClass.Tank, "icon_2", "image_2", "Feu brûlant énernel");
endeavor.AddSkill(new("Final flames", SkillType.Ultimate, "Dernière flamme d'un héro"));
endeavor.AddCharacteristics(new[] {
Tuple.Create("Force", 200),
Tuple.Create("Défense", 300),
Tuple.Create("Alter", 800)
});
Champion escanor = new("Escanor", ChampionClass.Fighter, "icon_3", "image_3", "1, 2, 3, Soleil");
escanor.AddSkill(new("Croissance solaire", SkillType.Passive, "Le soleil rends plus fort !"));
escanor.AddCharacteristics(new[] {
Tuple.Create("Force", 500),
Tuple.Create("Défense", 500)
});
await manager.AddItem(batman);
await manager.AddItem(endeavor);
await manager.AddItem(escanor);
}
using (var context = new SQLiteContext(options))
{
var manager = new EFManager(context).ChampionsMgr;
context.Database.EnsureCreated();
var nbItems = await manager.GetNbItems();
Assert.Equal(3, nbItems);
var items = await manager.GetItemsByName("Batman", 0, nbItems);
Assert.Equal("Batman", items.First().Name);
Assert.Equal(2, await manager.GetNbItemsByName("E"));
items = await manager.GetItemsBySkill("Croissance solaire", 0, nbItems);
Assert.Equal("Escanor", items.First().Name);
items = await manager.GetItemsBySkill(new Skill("Final flames", SkillType.Ultimate, "Dernière flamme d'un héro"),
0, nbItems);
Assert.Equal("Endeavor", items.First().Name);
items = await manager.GetItemsByCharacteristic("Alter", 0, nbItems);
Assert.Equal("Endeavor", items.First().Name);
Assert.Equal(2, await manager.GetNbItemsByCharacteristic("Défense"));
}
}
[Fact]
public async void Test_Update()
{
var connection = new SqliteConnection("DataSource=:memory:");
connection.Open();
var options = new DbContextOptionsBuilder<SQLiteContext>()
.UseSqlite(connection)
.Options;
using (var context = new SQLiteContext(options))
{
var manager = new EFManager(context).ChampionsMgr;
context.Database.EnsureCreated();
Champion batman = new("Batman", ChampionClass.Assassin, "icon_1", "image_1", "L'ombre de la nuit");
Champion endeavor = new("Endeavor", ChampionClass.Tank, "icon_2", "image_2", "Feu brûlant énernel");
Champion escanor = new("Escanor", ChampionClass.Fighter, "icon_3", "image_3", "1, 2, 3, Soleil");
await manager.AddItem(batman);
await manager.AddItem(endeavor);
await manager.AddItem(escanor);
}
using (var context = new SQLiteContext(options))
{
var manager = new EFManager(context).ChampionsMgr;
context.Database.EnsureCreated();
var items = await manager.GetItemsByName("E", 0, 3);
Assert.Equal(2, items.Count());
var escanor = context.Champion.Where(n => n.Name.Contains("Esc")).First();
escanor.Class = ChampionClass.Tank;
context.SaveChanges();
items = await manager.GetItemsByClass(ChampionClass.Tank, 0, 3);
Assert.Contains("Escanor", items.Select(x => x.Name));
Assert.Equal(2, await manager.GetNbItemsByClass(ChampionClass.Tank));
}
}
[Fact]
public async void Test_Delete()
{
var connection = new SqliteConnection("DataSource=:memory:");
connection.Open();
var options = new DbContextOptionsBuilder<SQLiteContext>()
.UseSqlite(connection)
.Options;
using (var context = new SQLiteContext(options))
{
var manager = new EFManager(context).ChampionsMgr;
context.Database.EnsureCreated();
Champion batman = new("Batman", ChampionClass.Assassin, "icon_1", "image_1", "L'ombre de la nuit");
batman.AddSkill(new("Charge", SkillType.Basic, "Coup de base"));
batman.AddSkill(new("Double Saut", SkillType.Basic, ""));
Champion endeavor = new("Endeavor", ChampionClass.Tank, "icon_2", "image_2", "Feu brûlant énernel");
endeavor.AddSkill(new("Charge", SkillType.Basic, "Coup de base"));
Champion escanor = new("Escanor", ChampionClass.Fighter, "icon_3", "image_3", "1, 2, 3, Soleil");
escanor.AddSkill(new("Charge", SkillType.Basic, "Coup de base"));
batman.AddSkill(new("Double Saut", SkillType.Basic, ""));
await manager.AddItem(batman);
await manager.AddItem(endeavor);
await manager.AddItem(escanor);
}
using (var context = new SQLiteContext(options))
{
var manager = new EFManager(context).ChampionsMgr;
context.Database.EnsureCreated();
var endeavor = (await manager.GetItemsByName("Endeavor", 0, 3)).First();
var itemsByName = await manager.DeleteItem(endeavor);
Assert.Equal(2, await manager.GetNbItems());
var items = await manager.GetItems(0, await manager.GetNbItems());
Assert.DoesNotContain("Endeavor", items.Select(x => x.Name));
Assert.Equal(1, await manager.GetNbItemsBySkill(new Skill("Double Saut", SkillType.Basic, "")));
Assert.Equal(2, await manager.GetNbItemsBySkill("Charge"));
}
}
}
}

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="7.0.2" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.abstractions" Version="2.0.3" />
<ProjectReference Include="..\Model\Model.csproj" />
<ProjectReference Include="..\EntityFrameworkLOL\EntityFrameworkLOL.csproj" />
<ProjectReference Include="..\APILOL\APILOL.csproj" />
<ProjectReference Include="..\ManagersEF\ManagersEF.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,277 @@
using ManagersEF;
using EntityFrameworkLOL.Entities;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Model;
using Shared;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static Model.RunePage;
using System.Xml.Linq;
using Xunit;
using EntityFrameworkLOL.DBContexts;
namespace TestEF
{
public class TestRunePages
{
[Fact]
public async void Test_Add()
{
var connection = new SqliteConnection("DataSource=:memory:");
connection.Open();
var options = new DbContextOptionsBuilder<SQLiteContext>()
.UseSqlite(connection)
.Options;
using (var context = new SQLiteContext(options))
{
var manager = new EFManager(context).RunePagesMgr;
var runeManager = new EFManager(context).RunesMgr;
var championManager = new EFManager(context).ChampionsMgr;
context.Database.EnsureCreated();
Model.Rune rune1 = new("Sanglante", RuneFamily.Domination);
Model.Rune rune2 = new("Oeil de l'esprit", RuneFamily.Precision);
Model.Rune rune3 = new("Concrétisation", RuneFamily.Unknown);
Model.Rune rune4 = new("The moon", RuneFamily.Unknown);
Model.Rune rune5 = new("Radiance", RuneFamily.Domination);
Model.Rune rune6 = new("Bullseye", RuneFamily.Precision);
RunePage runepage1 = new("Damages");
runepage1[Category.Major] = rune1;
runepage1[Category.Minor1] = rune2;
runepage1[Category.Minor2] = rune5;
RunePage runepage2 = new("Hawk");
runepage2[Category.Major] = rune6;
runepage2[Category.Minor1] = rune2;
RunePage runepage3 = new("Juggler");
runepage3[Category.Major] = rune5;
runepage3[Category.Minor1] = rune3;
runepage3[Category.Minor2] = rune2;
await runeManager.AddItem(rune1);
await runeManager.AddItem(rune2);
await runeManager.AddItem(rune3);
await runeManager.AddItem(rune4);
await runeManager.AddItem(rune5);
await runeManager.AddItem(rune6);
await manager.AddItem(runepage1);
await manager.AddItem(runepage2);
await manager.AddItem(runepage3);
Champion batman = new("Batman", ChampionClass.Assassin, "icon_1", "image_1", "L'ombre de la nuit");
Champion endeavor = new("Endeavor", ChampionClass.Tank, "icon_2", "image_2", "Feu brûlant énernel");
Champion escanor = new("Escanor", ChampionClass.Fighter, "icon_3", "image_3", "1, 2, 3, Soleil");
await championManager.AddItem(batman);
await championManager.AddItem(endeavor);
await championManager.AddItem(escanor);
var runepage_entities = context.RunePage;
var champion_entities = context.Champion;
var damages = runepage_entities.Find("Damages");
var hawk = runepage_entities.Find("Hawk");
var juggler = runepage_entities.Find("Juggler");
champion_entities.Find("Batman")!.RunePages = new List<RunePageEntity>() { hawk, juggler };
champion_entities.Find("Endeavor")!.RunePages = new List<RunePageEntity>() { damages };
champion_entities.Find("Escanor")!.RunePages = new List<RunePageEntity>() { damages };
context.SaveChanges();
}
using (var context = new SQLiteContext(options))
{
var manager = new EFManager(context).RunePagesMgr;
var championManager = new EFManager(context).ChampionsMgr;
context.Database.EnsureCreated();
Model.Rune rune5 = new("Radiance", RuneFamily.Domination);
Model.Rune rune1 = new("Sanglante", RuneFamily.Domination);
Champion batman = new("Batman", ChampionClass.Assassin, "icon_1", "image_1", "L'ombre de la nuit");
Champion endeavor = new("Endeavor", ChampionClass.Tank, "icon_2", "image_2", "Feu brûlant énernel");
var nbItems = await manager.GetNbItems();
Assert.Equal(3, nbItems);
var items = await manager.GetItemsByName("Ha", 0, nbItems);
Assert.Equal("Hawk", items.First().Name);
Assert.Equal(2, await manager.GetNbItemsByName("a"));
Assert.Equal(1, await manager.GetNbItemsByRune(rune5));
items = await manager.GetItemsByRune(rune1, 0, nbItems);
Assert.Equal("Damages", items.First().Name);
Assert.Equal(2, await manager.GetNbItemsByChampion(batman));
Assert.Equal("Damages", (await manager.GetItemsByChampion(endeavor, 0, 3)).First()!.Name);
Assert.Equal(2, await championManager.GetNbItemsByRunePage(new("Damages")));
Assert.Equal("Batman", (await championManager.GetItemsByRunePage(new("Juggler"), 0, 3)).First()!.Name);
}
}
[Fact]
public async void Test_Update()
{
var connection = new SqliteConnection("DataSource=:memory:");
connection.Open();
var options = new DbContextOptionsBuilder<SQLiteContext>()
.UseSqlite(connection)
.Options;
using (var context = new SQLiteContext(options))
{
var manager = new EFManager(context).RunePagesMgr;
var runeManager = new EFManager(context).RunesMgr;
context.Database.EnsureCreated();
Model.Rune rune1 = new("Sanglante", RuneFamily.Domination);
Model.Rune rune2 = new("Oeil de l'esprit", RuneFamily.Precision);
Model.Rune rune3 = new("Concrétisation", RuneFamily.Unknown);
Model.Rune rune4 = new("The moon", RuneFamily.Unknown);
Model.Rune rune5 = new("Radiance", RuneFamily.Domination);
Model.Rune rune6 = new("Bullseye", RuneFamily.Precision);
RunePage runepage1 = new("Damages");
runepage1[Category.Major] = rune1;
runepage1[Category.Minor1] = rune2;
runepage1[Category.Minor2] = rune5;
RunePage runepage2 = new("Hawk");
runepage2[Category.Major] = rune6;
runepage2[Category.Minor1] = rune2;
RunePage runepage3 = new("Juggler");
runepage3[Category.Major] = rune5;
runepage3[Category.Minor1] = rune3;
runepage3[Category.Minor2] = rune2;
await runeManager.AddItem(rune1);
await runeManager.AddItem(rune2);
await runeManager.AddItem(rune3);
await runeManager.AddItem(rune4);
await runeManager.AddItem(rune5);
await runeManager.AddItem(rune6);
await manager.AddItem(runepage1);
await manager.AddItem(runepage2);
await manager.AddItem(runepage3);
}
using (var context = new SQLiteContext(options))
{
var manager = new EFManager(context).RunePagesMgr;
Model.Rune rune1 = new("Sanglante", RuneFamily.Domination);
Model.Rune rune6 = new("Bullseye", RuneFamily.Precision);
context.Database.EnsureCreated();
Assert.Equal(1, await manager.GetNbItemsByRune(rune1));
Assert.Equal(1, await manager.GetNbItemsByRune(rune6));
RunePage after = new("Hawk");
after[Category.Major] = rune1;
await manager.UpdateItem(new("Hawk"), after);
Assert.Equal(2, await manager.GetNbItemsByRune(rune1));
Assert.Equal(0, await manager.GetNbItemsByRune(rune6));
context.SaveChanges();
}
}
[Fact]
public async void Test_Delete()
{
var connection = new SqliteConnection("DataSource=:memory:");
connection.Open();
var options = new DbContextOptionsBuilder<SQLiteContext>()
.UseSqlite(connection)
.Options;
using (var context = new SQLiteContext(options))
{
var manager = new EFManager(context).RunePagesMgr;
var runeManager = new EFManager(context).RunesMgr;
context.Database.EnsureCreated();
Model.Rune rune1 = new("Sanglante", RuneFamily.Domination);
Model.Rune rune2 = new("Oeil de l'esprit", RuneFamily.Precision);
Model.Rune rune3 = new("Concrétisation", RuneFamily.Unknown);
Model.Rune rune4 = new("The moon", RuneFamily.Unknown);
Model.Rune rune5 = new("Radiance", RuneFamily.Domination);
Model.Rune rune6 = new("Bullseye", RuneFamily.Precision);
RunePage runepage1 = new("Damages");
runepage1[Category.Major] = rune1;
runepage1[Category.Minor1] = rune2;
runepage1[Category.Minor2] = rune5;
RunePage runepage2 = new("Hawk");
runepage2[Category.Major] = rune6;
runepage2[Category.Minor1] = rune2;
RunePage runepage3 = new("Juggler");
runepage3[Category.Major] = rune5;
runepage3[Category.Minor1] = rune3;
runepage3[Category.Minor2] = rune2;
await runeManager.AddItem(rune1);
await runeManager.AddItem(rune2);
await runeManager.AddItem(rune3);
await runeManager.AddItem(rune4);
await runeManager.AddItem(rune5);
await runeManager.AddItem(rune6);
await manager.AddItem(runepage1);
await manager.AddItem(runepage2);
await manager.AddItem(runepage3);
}
using (var context = new SQLiteContext(options))
{
var manager = new EFManager(context).RunePagesMgr;
Model.Rune rune2 = new("Oeil de l'esprit", RuneFamily.Precision);
context.Database.EnsureCreated();
Assert.Equal(3, await manager.GetNbItems());
await manager.DeleteItem(new("Juggler"));
Assert.Equal(2, await manager.GetNbItems());
Assert.Equal(1, await manager.GetNbItemsByName("e"));
Assert.Equal(1, await manager.GetNbItemsByRune(rune2));
}
}
}
}

@ -0,0 +1,154 @@
using ManagersEF;
using EntityFrameworkLOL.Entities;
using EntityFrameworkLOL.DBContexts;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Model;
using Shared;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using Xunit;
namespace TestEF
{
public class TestRunes
{
[Fact]
public async void Test_Add()
{
var connection = new SqliteConnection("DataSource=:memory:");
connection.Open();
var options = new DbContextOptionsBuilder<SQLiteContext>()
.UseSqlite(connection)
.Options;
using (var context = new SQLiteContext(options))
{
var manager = new EFManager(context).RunesMgr;
context.Database.EnsureCreated();
Model.Rune rune1 = new("Sanglante", RuneFamily.Domination);
Model.Rune rune2 = new("Oeil de l'esprit", RuneFamily.Precision);
Model.Rune rune3 = new("Concrétisation", RuneFamily.Unknown);
await manager.AddItem(rune1);
await manager.AddItem(rune2);
await manager.AddItem(rune3);
}
using (var context = new SQLiteContext(options))
{
var manager = new EFManager(context).RunesMgr;
context.Database.EnsureCreated();
var nbItems = await manager.GetNbItems();
Assert.Equal(3, nbItems);
var items = await manager.GetItemsByName("Sanglante", 0, nbItems);
Assert.Equal("Sanglante", items.First().Name);
Assert.Equal(1, await manager.GetNbItemsByName("Concrétisation"));
items = await manager.GetItemsByFamily(RuneFamily.Precision, 0, nbItems);
Assert.Equal("Oeil de l'esprit", items.First().Name);
Assert.Equal(1, await manager.GetNbItemsByFamily(RuneFamily.Unknown));
}
}
[Fact]
public async void Test_Update()
{
var connection = new SqliteConnection("DataSource=:memory:");
connection.Open();
var options = new DbContextOptionsBuilder<SQLiteContext>()
.UseSqlite(connection)
.Options;
using (var context = new SQLiteContext(options))
{
var manager = new EFManager(context).RunesMgr;
context.Database.EnsureCreated();
Model.Rune rune1 = new("Sanglante", RuneFamily.Domination);
Model.Rune rune2 = new("Oeil de l'esprit", RuneFamily.Precision);
Model.Rune rune3 = new("Concrétisation", RuneFamily.Unknown);
await manager.AddItem(rune1);
await manager.AddItem(rune2);
await manager.AddItem(rune3);
}
using (var context = new SQLiteContext(options))
{
var manager = new EFManager(context).RunesMgr;
context.Database.EnsureCreated();
Assert.Equal(1, await manager.GetNbItemsByFamily(RuneFamily.Precision));
Model.Rune before = new("Concrétisation", RuneFamily.Unknown);
Model.Rune after = new("Concrétisation", RuneFamily.Precision);
await manager.UpdateItem(before, after);
Assert.Equal(2, await manager.GetNbItemsByFamily(RuneFamily.Precision));
context.SaveChanges();
}
}
[Fact]
public async void Test_Delete()
{
var connection = new SqliteConnection("DataSource=:memory:");
connection.Open();
var options = new DbContextOptionsBuilder<SQLiteContext>()
.UseSqlite(connection)
.Options;
using (var context = new SQLiteContext(options))
{
var manager = new EFManager(context).RunesMgr;
context.Database.EnsureCreated();
Model.Rune rune1 = new("Sanglante", RuneFamily.Domination);
Model.Rune rune2 = new("Oeil de l'esprit", RuneFamily.Precision);
Model.Rune rune3 = new("Concrétisation", RuneFamily.Unknown);
await manager.AddItem(rune1);
await manager.AddItem(rune2);
await manager.AddItem(rune3);
}
using (var context = new SQLiteContext(options))
{
var manager = new EFManager(context).RunesMgr;
context.Database.EnsureCreated();
Assert.Equal(3, await manager.GetNbItems());
await manager.DeleteItem(new("Concrétisation", RuneFamily.Unknown));
Assert.Equal(2, await manager.GetNbItems());
Assert.Equal(0, await manager.GetNbItemsByName("Concrétisation"));
}
}
}
}

@ -0,0 +1,182 @@
using ManagersEF;
using EntityFrameworkLOL.Entities;
using EntityFrameworkLOL.DBContexts;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Model;
using Shared;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using Xunit;
namespace TestEF
{
public class TestSkins
{
[Fact]
public async void Test_Add()
{
var connection = new SqliteConnection("DataSource=:memory:");
connection.Open();
var options = new DbContextOptionsBuilder<SQLiteContext>()
.UseSqlite(connection)
.Options;
using (var context = new SQLiteContext(options))
{
var manager = new EFManager(context).SkinsMgr;
var championManager = new EFManager(context).ChampionsMgr;
context.Database.EnsureCreated();
Champion batman = new("Batman", ChampionClass.Assassin);
Champion endeavor = new("Endeavor", ChampionClass.Tank);
await championManager.AddItem(batman);
await championManager.AddItem(endeavor);
Skin batman_skin_1 = new("Batman de glace", batman);
Skin batman_skin_2 = new("Batman gold", batman);
Skin batman_skin_3 = new("L'homme araignée", batman);
Skin endeavor_skin_1 = new("L'abominable Endeavor", endeavor);
await manager.AddItem(batman_skin_1);
await manager.AddItem(batman_skin_2);
await manager.AddItem(batman_skin_3);
await manager.AddItem(endeavor_skin_1);
}
using (var context = new SQLiteContext(options))
{
var manager = new EFManager(context).SkinsMgr;
context.Database.EnsureCreated();
var nbItems = await manager.GetNbItems();
Assert.Equal(4, nbItems);
Assert.Equal(4, (await manager.GetItems(0, nbItems)).Count());
var items = await manager.GetItemsByName("Batman", 0, nbItems);
Assert.Equal(2, items.Count());
Champion batman = new("Batman", ChampionClass.Assassin);
items = await manager.GetItemsByChampion(batman, 0, nbItems);
Assert.Equal(3, items.Count());
}
}
[Fact]
public async void Test_Update()
{
var connection = new SqliteConnection("DataSource=:memory:");
connection.Open();
var options = new DbContextOptionsBuilder<SQLiteContext>()
.UseSqlite(connection)
.Options;
using (var context = new SQLiteContext(options))
{
var manager = new EFManager(context).SkinsMgr;
var championManager = new EFManager(context).ChampionsMgr;
context.Database.EnsureCreated();
Champion batman = new("Batman", ChampionClass.Assassin);
Champion endeavor = new("Endeavor", ChampionClass.Tank);
await championManager.AddItem(batman);
await championManager.AddItem(endeavor);
Skin batman_skin_1 = new("Batman de glace", batman);
Skin batman_skin_2 = new("Batman gold", batman);
Skin batman_skin_3 = new("L'homme araignée", batman);
Skin endeavor_skin_1 = new("L'abominable Endeavor", endeavor);
await manager.AddItem(batman_skin_1);
await manager.AddItem(batman_skin_2);
await manager.AddItem(batman_skin_3);
await manager.AddItem(endeavor_skin_1);
}
using (var context = new SQLiteContext(options))
{
var manager = new EFManager(context).SkinsMgr;
context.Database.EnsureCreated();
Champion batman = new("Batman", ChampionClass.Assassin);
Champion endeavor = new("Endeavor", ChampionClass.Tank);
var itemsByName = await manager.GetItemsByChampion(batman, 0, 4);
Assert.Equal(3, itemsByName.Count());
Skin batman_skin = new("L'homme araignée", batman);
Skin endeavor_skin = new("L'homme araignée", endeavor);
await manager.UpdateItem(batman_skin, endeavor_skin);
itemsByName = await manager.GetItemsByChampion(batman, 0, 4);
Assert.Equal(2, itemsByName.Count());
context.SaveChanges();
}
}
[Fact]
public async void Test_Delete()
{
var connection = new SqliteConnection("DataSource=:memory:");
connection.Open();
var options = new DbContextOptionsBuilder<SQLiteContext>()
.UseSqlite(connection)
.Options;
using (var context = new SQLiteContext(options))
{
var manager = new EFManager(context).SkinsMgr;
var championManager = new EFManager(context).ChampionsMgr;
context.Database.EnsureCreated();
Champion batman = new("Batman", ChampionClass.Assassin);
Champion endeavor = new("Endeavor", ChampionClass.Tank);
await championManager.AddItem(batman);
await championManager.AddItem(endeavor);
Skin batman_skin_1 = new("Batman de glace", batman);
Skin batman_skin_2 = new("Batman gold", batman);
Skin batman_skin_3 = new("L'homme araignée", batman);
Skin endeavor_skin_1 = new("L'abominable Endeavor", endeavor);
await manager.AddItem(batman_skin_1);
await manager.AddItem(batman_skin_2);
await manager.AddItem(batman_skin_3);
await manager.AddItem(endeavor_skin_1);
}
using (var context = new SQLiteContext(options))
{
var manager = new EFManager(context).SkinsMgr;
context.Database.EnsureCreated();
await manager.DeleteItem((await manager.GetItemsByName("L'", 0, 4)).First());
await manager.DeleteItem((await manager.GetItemsByName("L'", 0, 3)).First());
Assert.Equal(2, await manager.GetNbItems());
Assert.Equal(2, await manager.GetNbItemsByName("Batman"));
Champion batman = new("Batman", ChampionClass.Assassin);
Assert.Equal(2, await manager.GetNbItemsByChampion(batman));
}
}
}
}

@ -14,6 +14,8 @@
<PackageReference Include="MSTest.TestAdapter" Version="2.2.8" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.8" />
<PackageReference Include="coverlet.collector" Version="3.1.2" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.abstractions" Version="2.0.3" />
</ItemGroup>
<ItemGroup>

@ -27,7 +27,6 @@ namespace TestUnitaire
[TestMethod]
public async Task TestGet()
{
//Act
var champions = await controller.Get(new PageRequest());
//Assert

@ -23,5 +23,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Design" Version="1.1.6" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.abstractions" Version="2.0.3" />
</ItemGroup>
</Project>

@ -0,0 +1,33 @@
using Microsoft.AspNetCore.Mvc;
namespace TestsEF.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}
}

@ -0,0 +1,25 @@
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();
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,31 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:59431",
"sslPort": 44385
}
},
"profiles": {
"TestsEF": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7027;http://localhost:5041",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup>
</Project>

@ -0,0 +1,13 @@
namespace TestsEF
{
public class WeatherForecast
{
public DateTime Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string? Summary { get; set; }
}
}

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Loading…
Cancel
Save