master
Louison PARANT 2 years ago
commit 954a5beaf4

@ -26,25 +26,24 @@ steps:
- dotnet test LeagueOfLegends.sln --no-restore - dotnet test LeagueOfLegends.sln --no-restore
depends_on: [build] depends_on: [build]
#- name: code-analysis - name: code-analysis
#image: hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-dronesonarplugin-dotnet6 image: hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-dronesonarplugin-dotnet6
#commands: commands:
#- cd Sources/ - cd Sources/
#- dotnet restore LeagueOfLegends.sln - 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 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 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" - 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" - reportgenerator -reports:"**/coverage.cobertura.xml" -reporttypes:SonarQube -targetdir:"coveragereport"
#- dotnet publish LeagueOfLegends.sln -c Release --no-restore -o CI_PROJECT_DIR/build/release - dotnet publish LeagueOfLegends.sln -c Release --no-restore -o CI_PROJECT_DIR/build/release
#- dotnet sonarscanner end /d:sonar.login=$${PLUGIN_SONAR_TOKEN} - dotnet sonarscanner end /d:sonar.login=$${PLUGIN_SONAR_TOKEN}
#secrets: [ SECRET_SONAR_LOGIN ] secrets: [ SONAR_TOKEN ]
# settings: settings:
# accessible en ligne de commande par ${PLUGIN_SONAR_HOST} sonar_host: https://codefirst.iut.uca.fr/sonar/
#sonar_host: https://codefirst.iut.uca.fr/sonar/ sonar_token:
# accessible en ligne de commande par ${PLUGIN_SONAR_TOKEN} from_secret: SONAR_TOKEN
#sonar_token: depends_on: [tests]
#from_secret: SECRET_SONAR_LOGIN
#depends_on: [tests]
- name: generate-and-deploy-docs - name: generate-and-deploy-docs
image: hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-docdeployer 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 image: hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-dockerproxy-clientdrone:latest
environment: environment:
IMAGENAME: hub.codefirst.iut.uca.fr/lucas.delanier/lolproject:latest IMAGENAME: hub.codefirst.iut.uca.fr/lucas.delanier/lolproject:latest
CONTAINERNAME: container_lol CONTAINERNAME: containerlol
COMMAND: create COMMAND: create
OVERWRITE: true OVERWRITE: true
volumes: 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
## LOLProject
## Diagramme de classes du modèle
```mermaid
classDiagram
class LargeImage{
+/Base64 : string **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
}
class Champion{ Merci de noter la v1 de l'api qui est tenu a jour la v2 sert uniquement a montrer que nous pouvons versionner.
+/Name : string
+/Bio : string ## :floppy_disk: FEATURES
+/Icon : string
+/Characteristics : Dictionary~string, int~ - L'API dispose des principales requêtes CRUD sur les champions, skills, skins, runes, runepages aussi consultables sur le swagger UI.
~ AddSkin(skin : Skin) bool - L'ORM réalisé avec EntityFramework afin d'enregistrer dans une base de données SQLite
~ RemoveSkin(skin: Skin) bool - L'application MAUI pour faire des requêtes depuis un client et les afficher.
+ AddSkill(skill: Skill) bool
+ RemoveSkill(skill: Skill) bool
+ AddCharacteristics(someCharacteristics : params Tuple~string, int~[]) ![](https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png)
+ RemoveCharacteristics(label : string) bool
+ this~label : string~ : int? ## :dizzy: Getting Started
}
Champion --> "1" LargeImage : Image 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.
class ChampionClass{
<<enumeration>>
Unknown, ## Archutecture
Assassin,
Fighter, ![](https://codefirst.iut.uca.fr/git/lucas.delanier/LOLProject/raw/branch/master/Documentations/Schema_architecture.png)
Mage, Ce schéma d'architecure globale permet de comprendre la composition interne de la solution.
Marksman,
Support, 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.
Tank, 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.
}
Champion --> "1" ChampionClass : Class ## 1 - La déserialization
class Skin{ 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#.
+/Name : string
+/Description : string ![](https://codefirst.iut.uca.fr/git/lucas.delanier/LOLProject/raw/branch/master/Documentations/Capture%20d%27%C3%A9cran%202023-03-26%20111526.png)
+/Icon : string
+/Price : float
} ## 2 - La communication Client - Api
Skin --> "1" LargeImage : Image 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.
Champion "1" -- "*" Skin
class Skill{ "codefirst.iut.uca.fr/containers/lucasdelanier-containerlol/api/v{version}/{controller}"
+/Name : string
+/Description : string 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.
}
class SkillType{ ![](https://codefirst.iut.uca.fr/git/lucas.delanier/LOLProject/raw/branch/master/Documentations/Capture%20d%27%C3%A9cran%202023-03-26%20113439.png)
<<enumeration>>
Unknown, 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()
Basic,
Passive, ![](https://codefirst.iut.uca.fr/git/lucas.delanier/LOLProject/raw/branch/master/Documentations/Capture%20d%27%C3%A9cran%202023-03-26%20113710.png)
Ultimate,
} ## 3 - L'utilisation du stub dans l'API
Skill --> "1" SkillType : Type 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).
Champion --> "*" Skill
class Rune{ ![](https://codefirst.iut.uca.fr/git/lucas.delanier/LOLProject/raw/branch/master/Documentations/Capture%20d%27%C3%A9cran%202023-03-26%20114811.png)
+/Name : string
+/Description : string
} ## 4 - Lien entre API et Entityframework
Rune --> "1" LargeImage : Image ...
class RuneFamily{
<<enumeration>>
Unknown, ## 5 - Mappage des classes métier en tables
Precision, ...
Domination
} ## 6 - Lien avec base de données SQLlite
Rune --> "1" RuneFamily : Family ...
class Category{
<<enumeration>>
Major, ## :wrench: SUPPORT
Minor1, En cas de problème lors de l'utilisation de l'application, vous pouvez nous contacter aux adresses suivantes :
Minor2,
Minor3,
OtherMinor1, Lucas Delanier : **Lucas.DELANIER@etu.uca.fr** </br>
OtherMinor2 Louison Parant : **Louison.PARANT@etu.uca.fr**
} ![](https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png)
class RunePage{
+/Name : string
+/this[category : Category] : Rune?
- CheckRunes(newRuneCategory : Category) ## ✨ Contributors
- CheckFamilies(cat1 : Category, cat2 : Category) bool?
- UpdateMajorFamily(minor : Category, expectedValue : bool) <a href = "https://codefirst.iut.uca.fr/git/lucas.delanier">
} <img src ="https://codefirst.iut.uca.fr/git/avatars/6a3835d734392fccff3949f7c82a63b9?size=870" height="50px">
RunePage --> "*" Rune : Dictionary~Category,Rune~ </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">
## Diagramme de classes des interfaces de gestion de l'accès aux données </a>
```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
```

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

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

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

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

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

@ -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 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; } public string Description { get; set; }
} }
} }

@ -8,169 +8,5 @@ class Program
{ {
static void Main(string[] args) 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] [TestMethod]
public async Task TestGet() public async Task TestGet()
{ {
//Act
var champions = await controller.Get(new PageRequest()); var champions = await controller.Get(new PageRequest());
//Assert //Assert

Loading…
Cancel
Save