master
Louison PARANT 2 years ago
commit 954a5beaf4

@ -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,93 @@
# 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.
## Archutecture
![](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
...
## 5 - Mappage des classes métier en tables
...
## 6 - Lien avec base de données SQLlite
...
## :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>

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

@ -15,8 +15,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()),
};
}

@ -0,0 +1,23 @@
using DTO;
using Model;
namespace APILOL.Mapper
{
public static class SkillMapper
{
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; }
}
}

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

@ -8,169 +8,5 @@ class Program
{
static void Main(string[] args)
{
using (var context = new SQLiteContext()) {
if (context.Champion.Count() > 0)
{
foreach (var c in context.Champion.ToArray())
{
context.Champion.Remove(c);
}
}
if (context.Rune.Count() > 0)
{
foreach (var r in context.Rune.ToArray())
{
context.Rune.Remove(r);
}
}
if (context.Skin.Count() > 0)
{
foreach (var s in context.Skin.ToArray())
{
context.Skin.Remove(s);
}
}
if (context.Skill.Count() > 0)
{
foreach (var s in context.Skill.ToArray())
{
context.Skill.Remove(s);
}
}
if (context.RunePage.Count() > 0)
{
foreach (var rp in context.RunePage.ToArray())
{
context.RunePage.Remove(rp);
}
}
if (context.ChampionClass.Count() > 0)
{
foreach (var cc in context.ChampionClass.ToArray())
{
context.ChampionClass.Remove(cc);
}
}
if (context.RuneFamily.Count() > 0)
{
foreach (var rf in context.RuneFamily.ToArray())
{
context.RuneFamily.Remove(rf);
}
}
if (context.SkillType.Count() > 0)
{
foreach (var st in context.SkillType.ToArray())
{
context.SkillType.Remove(st);
}
}
if (context.Image.Count() > 0)
{
foreach (var i in context.Image.ToArray())
{
context.Image.Remove(i);
}
}
context.SaveChanges();
}
ChampionEntity akali = new ChampionEntity { Name = "Akali", Bio = "" };
ChampionEntity aatrox = new ChampionEntity { Name = "Aatrox", Bio = "" };
ChampionEntity ahri = new ChampionEntity { Name = "Ahri", Bio = "" };
ChampionEntity bard = new ChampionEntity { Name = "Bard", Bio = "" };
ChampionEntity alistar = new ChampionEntity { Name = "Alistar", Bio = "" };
ChampionEntity akshan = new ChampionEntity { Name = "Akshan", Bio = "" };
using (var context = new SQLiteContext())
{
// Crée des champions et les insère dans la base
Console.WriteLine("Creates and inserts new Champions");
context.AddRange(new ChampionEntity[] { akali, aatrox, ahri, bard, alistar, akshan });
/*context.Add(akali);
context.Add(aatrox);
context.Add(ahri);
context.Add(bard);
context.Add(alistar);
context.Add(akshan);*/
context.SaveChanges();
Console.WriteLine("Creates and executes a query retrieving the first Champion of the database whose name starts with an \"A\":");
var aChampion = context.Champion
.Where(c => c.Name.StartsWith("A"))
.First();
Console.WriteLine($"{aChampion.Name} (with bio : \"{aChampion.Bio}\")");
}
RuneEntity conqueror = new RuneEntity { Name = "Conqueror", Description = "" };
RuneEntity thriumph = new RuneEntity { Name = "Thriumph", Description = "" };
RuneEntity alacrity = new RuneEntity { Name = "Legend : Alacrity", Description = "" };
RuneEntity tenacity = new RuneEntity { Name = "Legend : Tenacity", Description = "" };
RuneEntity laststand = new RuneEntity { Name = "Last Stand", Description = "" };
RuneEntity laststand2 = new RuneEntity { Name = "Last Stand 2", Description = "" };
using (var context = new SQLiteContext())
{
// Crée des Runes et les insère dans la base
Console.WriteLine("Creates and inserts new Runes");
context.AddRange(new RuneEntity[] { conqueror, thriumph, alacrity, tenacity, laststand, laststand2 });
/*context.Add(conqueror);
context.Add(thriumph);
context.Add(alacrity);
context.Add(tenacity);
context.Add(laststand);
context.Add(laststand2);*/
context.SaveChanges();
Console.WriteLine("Creates and executes a query retrieving the first Runes of the database whose name starts with an \"L\":");
var lRune = context.Rune
.Where(r => r.Name.StartsWith("L"))
.First();
Console.WriteLine($"{lRune.Name} (with Description : \"{lRune.Description}\")");
}
SkinEntity stinger = new SkinEntity { Name = "Stinger", Description = "" };
SkinEntity infernal = new SkinEntity { Name = "Infernal", Description = "" };
SkinEntity allStar = new SkinEntity { Name = "All-Star", Description = "" };
SkinEntity justicar = new SkinEntity { Name = "Justicar", Description = "" };
SkinEntity mecha = new SkinEntity { Name = "Mecha", Description = "" };
SkinEntity seaHunter = new SkinEntity { Name = "Sea Hunter", Description = "" };
using (var context = new SQLiteContext())
{
// Crée des Skins et les insère dans la base
Console.WriteLine("Creates and inserts new Skins");
context.AddRange(new SkinEntity[] { stinger, infernal, allStar, justicar, mecha, seaHunter });
/*context.Add(stinger);
context.Add(infernal);
context.Add(allStar);
context.Add(justicar);
context.Add(mecha);
context.Add(seaHunter);*/
context.SaveChanges();
Console.WriteLine("Creates and executes a query retrieving the first Skins of the database whose name starts with an \"I\":");
var iSkin = context.Skin
.Where(s => s.Name.StartsWith("I"))
.First();
Console.WriteLine($"{iSkin.Name} (with Description : \"{iSkin.Description}\")");
Console.WriteLine("Updates the name of the Infernal Skin");
iSkin.Description = "Hella Infernal (Wallah)";
context.SaveChanges();
Console.WriteLine($"{iSkin.Name} (with Description : \"{iSkin.Description}\")");
Console.WriteLine("Deletes one item from the database");
var droid = context.Skin
.SingleOrDefault(s => s.Name.Equals("Infernal"));
context.Remove(droid);
context.SaveChanges();
}
using (var context = new SQLiteContext())
{
foreach (var c in context.Champion)
{
c.Bio = $"{c.Name}";
Console.WriteLine($"{c.Name} - {c.Bio}");
}
context.SaveChanges();
}
}
}

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

Loading…
Cancel
Save