From 074892b3a7546ebada4e353241794172cbb729b1 Mon Sep 17 00:00:00 2001 From: Emre Date: Sat, 4 Mar 2023 20:24:38 +0100 Subject: [PATCH] Changed program.cs for versioning in the swagger, also fixed uniqueness issues and created 3 versions of the ChampionController :white_check_mark: --- .../Sources/ApiLol/ApiLol.csproj | 2 + .../ApiLol/Controllers/SkinsController.cs | 73 ++ .../Controllers/v1/ChampionsController.cs | 84 +++ .../{ => v2}/ChampionsController.cs | 382 +++++----- .../Sources/ApiLol/Mapper/SkinMapper.cs | 14 + .../Sources/ApiLol/Program.cs | 33 +- .../Sources/Client/ChampionHttpClient.cs | 8 +- .../Sources/DTO/RuneDto.cs | 5 +- .../Sources/DTO/SkinDtoC.cs | 20 + .../Sources/DTO/enums/RuneFamilyDto.cs | 15 + .../Sources/StubLib/StubData.Champions.cs | 2 +- .../Tests/ApiTests/ChampionsControllerTest.cs | 2 +- .../Sources/Tests/ConsoleTests/Program.cs | 672 +++++++++--------- 13 files changed, 789 insertions(+), 523 deletions(-) create mode 100644 src/EntityFramework_LoL/Sources/ApiLol/Controllers/SkinsController.cs create mode 100644 src/EntityFramework_LoL/Sources/ApiLol/Controllers/v1/ChampionsController.cs rename src/EntityFramework_LoL/Sources/ApiLol/Controllers/{ => v2}/ChampionsController.cs (77%) create mode 100644 src/EntityFramework_LoL/Sources/DTO/SkinDtoC.cs create mode 100644 src/EntityFramework_LoL/Sources/DTO/enums/RuneFamilyDto.cs diff --git a/src/EntityFramework_LoL/Sources/ApiLol/ApiLol.csproj b/src/EntityFramework_LoL/Sources/ApiLol/ApiLol.csproj index 57d85a9..f765ca4 100644 --- a/src/EntityFramework_LoL/Sources/ApiLol/ApiLol.csproj +++ b/src/EntityFramework_LoL/Sources/ApiLol/ApiLol.csproj @@ -9,6 +9,8 @@ + + diff --git a/src/EntityFramework_LoL/Sources/ApiLol/Controllers/SkinsController.cs b/src/EntityFramework_LoL/Sources/ApiLol/Controllers/SkinsController.cs new file mode 100644 index 0000000..ac1cc2d --- /dev/null +++ b/src/EntityFramework_LoL/Sources/ApiLol/Controllers/SkinsController.cs @@ -0,0 +1,73 @@ +using ApiLol.Mapper; +using DTO; +using Microsoft.AspNetCore.Mvc; +using Model; + +// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 + +namespace ApiLol.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class SkinsController : ControllerBase + { + private readonly IDataManager _manager; + private readonly ILogger _logger; + + public SkinsController(IDataManager dataManager, ILogger logger) + { + _logger = logger; + this._manager = dataManager; + } + + // GET: api/ + [HttpGet] + public async Task Get([FromQuery] PageRequest pageRequest) + { + try + { + int nbTotal = await _manager.ChampionsMgr.GetNbItems(); + if (pageRequest.count + pageRequest.index > nbTotal) + { + _logger.LogWarning($"too many, maximum {nbTotal}"); + return BadRequest($"Champion limit exceed, max {nbTotal}"); + } + + _logger.LogInformation($"method Get call"); + IEnumerable dtos = (await _manager.SkinsMgr.GetItems(pageRequest.index, pageRequest.count)) + .Select(x => x.ToDtoC()); + return Ok(dtos); + + } + catch (Exception e) + { + return BadRequest(e.Message); + } + } + + // GET api//5 + [HttpGet("{name}")] + public async Task Get(string name) + { + return Ok(); + } + + // POST api/ + [HttpPost] + public async void Post([FromBody] string value) + { + } + + // PUT api//5 + [HttpPut("{name}")] + public async void Put(int id, [FromBody] string value) + { + } + + // DELETE api//5 + [HttpDelete("{name}")] + public async void Delete(string name) + { + } + } +} diff --git a/src/EntityFramework_LoL/Sources/ApiLol/Controllers/v1/ChampionsController.cs b/src/EntityFramework_LoL/Sources/ApiLol/Controllers/v1/ChampionsController.cs new file mode 100644 index 0000000..96ecf2b --- /dev/null +++ b/src/EntityFramework_LoL/Sources/ApiLol/Controllers/v1/ChampionsController.cs @@ -0,0 +1,84 @@ +using ApiLol.Mapper; +using DTO; +using Microsoft.AspNetCore.Mvc; +using Microsoft.IdentityModel.Tokens; +using Model; + +// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 + +namespace ApiLol.Controllers.v1 +{ + [ApiVersion("1.0")] + [Route("api/v{version:apiVersion}/[controller]")] + [ApiController] + public class ChampionsController : ControllerBase + { + private readonly IDataManager _manager; + private readonly ILogger _logger; + public ChampionsController(IDataManager dataManager, ILogger logger) + { + _logger = logger; + this._manager = dataManager; + } + + // GET: api/ + [HttpGet] + public async Task Get([FromQuery] PageRequest pageRequest) + { + + int nbTotal = await _manager.ChampionsMgr.GetNbItems(); + + _logger.LogInformation($"method Get call"); + IEnumerable dtos = (await _manager.ChampionsMgr.GetItems(pageRequest.index, pageRequest.count)) + .Select(x => x.ToDto()); + return Ok(dtos); + } + + // GET api//5 + [HttpGet("{name}")] + public async Task Get(string name) + { + _logger.LogInformation($"method GetByName call with {name}"); + var dtos = (await _manager.ChampionsMgr.GetItemsByName(name, 0, await _manager.ChampionsMgr.GetNbItems())) + .Select(x => x.ToDto()); + + return Ok(dtos); + + } + + // POST api/ + [HttpPost] + public async Task Post([FromBody] ChampionDto champion) + { + + _logger.LogInformation($"method Post call"); + return CreatedAtAction(nameof(Get), + (await _manager.ChampionsMgr.AddItem(champion.ToModel())).ToDto()); + + } + + // PUT api//5 + [HttpPut("{name}")] + public async Task Put(string name, [FromBody] ChampionDto champion) + { + + _logger.LogInformation($"method Put call with {name}"); + var dtos = (await _manager.ChampionsMgr.GetItemsByName(name, 0, await _manager.ChampionsMgr.GetNbItems())); + + return Ok(await _manager.ChampionsMgr.UpdateItem(dtos.First(), champion.ToModel())); + + } + + // DELETE api//5 + [HttpDelete("{name}")] + public async Task Delete(string name) + { + + _logger.LogInformation($"method Delete call with {name}"); + var dtos = (await _manager.ChampionsMgr.GetItemsByName(name, 0, await _manager.ChampionsMgr.GetNbItems())); + + return Ok(await _manager.ChampionsMgr.DeleteItem(dtos.First())); + + } + } +} \ No newline at end of file diff --git a/src/EntityFramework_LoL/Sources/ApiLol/Controllers/ChampionsController.cs b/src/EntityFramework_LoL/Sources/ApiLol/Controllers/v2/ChampionsController.cs similarity index 77% rename from src/EntityFramework_LoL/Sources/ApiLol/Controllers/ChampionsController.cs rename to src/EntityFramework_LoL/Sources/ApiLol/Controllers/v2/ChampionsController.cs index 2acbc49..1715b6a 100644 --- a/src/EntityFramework_LoL/Sources/ApiLol/Controllers/ChampionsController.cs +++ b/src/EntityFramework_LoL/Sources/ApiLol/Controllers/v2/ChampionsController.cs @@ -1,179 +1,205 @@ -using ApiLol.Mapper; -using DTO; -using Microsoft.AspNetCore.Mvc; -using Microsoft.IdentityModel.Tokens; -using Model; - -// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 - -namespace ApiLol.Controllers -{ - [Route("api/[controller]")] - [ApiController] - public class ChampionsController : ControllerBase - { - private readonly IDataManager _manager; - public readonly ILogger _logger; - public ChampionsController(IDataManager dataManager, ILogger logger) - { - _logger = logger; - this._manager = dataManager; - } - - // GET: api/ - [HttpGet] - public async Task Get([FromQuery] PageRequest pageRequest) - { - try - { - int nbTotal = await _manager.ChampionsMgr.GetNbItems(); - if (pageRequest.count + pageRequest.index > nbTotal) - { - _logger.LogWarning($"too many, maximum {nbTotal}"); - return BadRequest($"Champion limit exceed, max {nbTotal}"); - } - - _logger.LogInformation($"method Get call"); - IEnumerable dtos = (await _manager.ChampionsMgr.GetItems(pageRequest.index, pageRequest.count)) - .Select(x => x.ToDto()); - return Ok(dtos); - } - catch (Exception e) - { - return BadRequest(e.Message); - - } - } - - // GET api//5 - [HttpGet("{name}")] - public async Task Get(string name) - { - try - { - _logger.LogInformation($"method GetByName call with {name}"); - var dtos = (await _manager.ChampionsMgr.GetItemsByName(name, 0, await _manager.ChampionsMgr.GetNbItems())) - .Select(x => x.ToDto()); - if (dtos.IsNullOrEmpty()) - { - _logger.LogWarning($"{name} was not found"); - return NotFound(); - } - return Ok(dtos); - } - catch (Exception e) - { - return BadRequest(e.Message); - - } - } - - // POST api/ - [HttpPost] - public async Task Post([FromBody] ChampionDto champion) - { - try - { - _logger.LogInformation($"method Post call"); - var dtos = (await _manager.ChampionsMgr.GetItemsByName(champion.Name, 0, await _manager.ChampionsMgr.GetNbItems())); - if (!dtos.IsNullOrEmpty()) - { - return BadRequest("Name is already exist"); - } - return CreatedAtAction(nameof(Get), - (await _manager.ChampionsMgr.AddItem(champion.ToModel())).ToDto()); - } - catch (Exception e) - { - return BadRequest(e.Message); - - } - } - - // PUT api//5 - [HttpPut("{name}")] - public async Task Put(string name, [FromBody] ChampionDto champion) - { - try - { - _logger.LogInformation($"method Put call with {name}"); - var dtos = (await _manager.ChampionsMgr.GetItemsByName(name, 0, await _manager.ChampionsMgr.GetNbItems())); - if (dtos.IsNullOrEmpty()) - { - return BadRequest("Name not exist"); - } - // Checks if the new name exists - if (name != champion.Name) - { - var dtos2 = (await _manager.ChampionsMgr.GetItemsByName(champion.Name, 0, await _manager.ChampionsMgr.GetNbItems())); - if (!dtos.IsNullOrEmpty()) - { - return BadRequest("Name is already exist"); - } - } - return Ok(await _manager.ChampionsMgr.UpdateItem(dtos.First(), champion.ToModel())); - } - catch (Exception e) - { - return BadRequest(e.Message); - - } - } - - [HttpGet("/{name}/skins")] - public async Task> GetChampionsSkins(string name) - { - try - { - var champions = await _manager.ChampionsMgr.GetItemsByName(name, 0, await _manager.ChampionsMgr.GetNbItems()); - //skinsDTO - IEnumerable res = champions.First().Skins.Select(e => e.ToDto()); - - return Ok(res); - } - catch (Exception e) - { - return BadRequest(e.Message); - - } - } - - [HttpGet("/{name}/skills")] - public async Task> GetChampionsSkills(string name) - { - try - { - var champions = await _manager.ChampionsMgr.GetItemsByName(name, 0, await _manager.ChampionsMgr.GetNbItems()); - //SkillDTO - IEnumerable res = champions.First().Skills.Select(e => e.ToDto()); - - return Ok(res); - } - catch (Exception e) - { - return BadRequest(e.Message); - } - } - - // DELETE api//5 - [HttpDelete("{name}")] - public async Task Delete(string name) - { - try - { - _logger.LogInformation($"method Delete call with {name}"); - var dtos = (await _manager.ChampionsMgr.GetItemsByName(name, 0, await _manager.ChampionsMgr.GetNbItems())); - if (dtos.IsNullOrEmpty()) - { - _logger.LogWarning($"{name} was not found"); - return BadRequest(); - } - return Ok(await _manager.ChampionsMgr.DeleteItem(dtos.First())); - } - catch (Exception e) - { - return BadRequest(e.Message); - } - } - } +using ApiLol.Mapper; +using DTO; +using Microsoft.AspNetCore.Mvc; +using Microsoft.IdentityModel.Tokens; +using Model; + +// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 + +namespace ApiLol.Controllers.v2 +{ + [ApiVersion("2.0")] + [ApiVersion("3.0")] + [Route("api/v{version:apiVersion}/[controller]")] + [ApiController] + public class ChampionsController : ControllerBase + { + private readonly IDataManager _manager; + private readonly ILogger _logger; + public ChampionsController(IDataManager dataManager, ILogger logger) + { + _logger = logger; + this._manager = dataManager; + } + + // GET: api/ + [HttpGet] + public async Task Get([FromQuery] PageRequest pageRequest) + { + try + { + int nbTotal = await _manager.ChampionsMgr.GetNbItems(); + if (pageRequest.count * pageRequest.index >= nbTotal) + { + _logger.LogWarning($"too many, maximum {nbTotal}"); + return BadRequest($"Champion limit exceed, max {nbTotal}"); + } + + _logger.LogInformation($"method Get call"); + IEnumerable dtos = (await _manager.ChampionsMgr.GetItems(pageRequest.index, pageRequest.count)) + .Select(x => x.ToDto()); + return Ok(dtos); + } + catch (Exception e) + { + return BadRequest(e.Message); + } + } + + // GET: api/ + [HttpGet, MapToApiVersion("3.0")] + public async Task GetV3([FromQuery] PageRequest pageRequest) + { + try + { + int nbTotal = await _manager.ChampionsMgr.GetNbItems(); + if (pageRequest == null) + { + pageRequest.index = 0; + pageRequest.count = nbTotal; + } + else if (pageRequest.count * pageRequest.index >= nbTotal) + { + _logger.LogWarning($"too many, maximum {nbTotal}"); + return BadRequest($"Champion limit exceed, max {nbTotal}"); + } + + _logger.LogInformation($"method Get call"); + IEnumerable dtos = (await _manager.ChampionsMgr.GetItems(pageRequest.index, pageRequest.count)) + .Select(x => x.ToDto()); + return Ok(dtos); + } + catch (Exception e) + { + return BadRequest(e.Message); + } + } + + // GET api//5 + [HttpGet("{name}")] + public async Task Get(string name) + { + try + { + _logger.LogInformation($"method GetByName call with {name}"); + var dtos = (await _manager.ChampionsMgr.GetItemsByName(name, 0, await _manager.ChampionsMgr.GetNbItems())) + .Select(x => x.ToDto()); + if (dtos.IsNullOrEmpty()) + { + _logger.LogWarning($"{name} was not found"); + return NotFound(); + } + return Ok(dtos); + } + catch (Exception e) + { + return BadRequest(e.Message); + } + } + + // POST api/ + [HttpPost] + public async Task Post([FromBody] ChampionDto champion) + { + try + { + _logger.LogInformation($"method Post call"); + var dtos = (await _manager.ChampionsMgr.GetItemsByName(champion.Name, 0, await _manager.ChampionsMgr.GetNbItems())); + if (!dtos.IsNullOrEmpty()) + { + return BadRequest("Name is already exist"); + } + return CreatedAtAction(nameof(Get), + (await _manager.ChampionsMgr.AddItem(champion.ToModel())).ToDto()); + } + catch (Exception e) + { + return BadRequest(e.Message); + } + } + + // PUT api//5 + [HttpPut("{name}")] + public async Task Put(string name, [FromBody] ChampionDto champion) + { + try + { + _logger.LogInformation($"method Put call with {name}"); + var dtos = (await _manager.ChampionsMgr.GetItemsByName(name, 0, await _manager.ChampionsMgr.GetNbItems())); + if (dtos.IsNullOrEmpty()) + { + return NotFound("Name not exist"); + } + // Checks if the new name exists + if (name != champion.Name) + { + var dtos2 = (await _manager.ChampionsMgr.GetItemsByName(champion.Name, 0, await _manager.ChampionsMgr.GetNbItems())); + if (dtos.IsNullOrEmpty() || dtos2.Count() > 0) + { + return BadRequest("Name is already exist"); + } + } + return Ok(await _manager.ChampionsMgr.UpdateItem(dtos.First(), champion.ToModel())); + } + catch (Exception e) + { + return BadRequest(e.Message); + } + } + + [HttpGet("/{name}/skins")] + public async Task> GetChampionsSkins(string name) + { + try + { + var champions = await _manager.ChampionsMgr.GetItemsByName(name, 0, await _manager.ChampionsMgr.GetNbItems()); + //skinsDTO + IEnumerable res = champions.First().Skins.Select(e => e.ToDto()); + + return Ok(res); + } + catch (Exception e) + { + return BadRequest(e.Message); + } + } + + [HttpGet("/{name}/skills")] + public async Task> GetChampionsSkills(string name) + { + try + { + var champions = await _manager.ChampionsMgr.GetItemsByName(name, 0, await _manager.ChampionsMgr.GetNbItems()); + //SkillDTO + IEnumerable res = champions.First().Skills.Select(e => e.ToDto()); + + return Ok(res); + } + catch (Exception e) + { + return BadRequest(e.Message); + } + } + + // DELETE api//5 + [HttpDelete("{name}")] + public async Task Delete(string name) + { + try + { + _logger.LogInformation($"method Delete call with {name}"); + var dtos = (await _manager.ChampionsMgr.GetItemsByName(name, 0, await _manager.ChampionsMgr.GetNbItems())); + if (dtos.IsNullOrEmpty()) + { + _logger.LogWarning($"{name} was not found"); + return BadRequest(); + } + return Ok(await _manager.ChampionsMgr.DeleteItem(dtos.First())); + } + catch (Exception e) + { + return BadRequest(e.Message); + } + } + } } \ No newline at end of file diff --git a/src/EntityFramework_LoL/Sources/ApiLol/Mapper/SkinMapper.cs b/src/EntityFramework_LoL/Sources/ApiLol/Mapper/SkinMapper.cs index 9925eac..7104d37 100644 --- a/src/EntityFramework_LoL/Sources/ApiLol/Mapper/SkinMapper.cs +++ b/src/EntityFramework_LoL/Sources/ApiLol/Mapper/SkinMapper.cs @@ -17,9 +17,23 @@ namespace ApiLol.Mapper }; } + public static SkinDtoC ToDtoC(this Skin skin) + { + return new SkinDtoC() + { + Name = skin.Name, + Description = skin.Description, + Icon = skin.Icon, + Image = skin.Image.ToDto(), + Price = skin.Price, + ChampionName = skin.Champion.Name + }; + } + public static Skin ToModel(this SkinDto skinDto) { return new Skin(skinDto.Name, null, skinDto.Price, skinDto.Icon, skinDto.Image.Base64, skinDto.Description); } + } } \ No newline at end of file diff --git a/src/EntityFramework_LoL/Sources/ApiLol/Program.cs b/src/EntityFramework_LoL/Sources/ApiLol/Program.cs index 0e7a608..98e6f6c 100644 --- a/src/EntityFramework_LoL/Sources/ApiLol/Program.cs +++ b/src/EntityFramework_LoL/Sources/ApiLol/Program.cs @@ -1,3 +1,5 @@ +using Microsoft.AspNetCore.Mvc.ApiExplorer; +using Microsoft.AspNetCore.Mvc.Versioning; using Model; using StubLib; @@ -9,14 +11,41 @@ builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); + + +builder.Services.AddApiVersioning(opt => + { + opt.DefaultApiVersion = new Microsoft.AspNetCore.Mvc.ApiVersion(1, 0); + opt.AssumeDefaultVersionWhenUnspecified = true; + opt.ReportApiVersions = true; + opt.ApiVersionReader = ApiVersionReader.Combine(new UrlSegmentApiVersionReader(), + new HeaderApiVersionReader("x-api-version"), + new MediaTypeApiVersionReader("x-api-version")); + }); +// Add ApiExplorer to discover versions +builder.Services.AddVersionedApiExplorer(setup => +{ + setup.GroupNameFormat = "'v'VVV"; + setup.SubstituteApiVersionInUrl = true; +}); + builder.Services.AddSingleton(); var app = builder.Build(); // Configure the HTTP request pipeline. -app.UseSwagger(); -app.UseSwaggerUI(); +var apiVersionDescriptionProvider = app.Services.GetRequiredService(); +// Configure the HTTP request pipeline. +app.UseSwagger(); +app.UseSwaggerUI(options => +{ + foreach (var description in apiVersionDescriptionProvider.ApiVersionDescriptions) + { + options.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", + description.GroupName.ToUpperInvariant()); + } +}); app.UseHttpsRedirection(); diff --git a/src/EntityFramework_LoL/Sources/Client/ChampionHttpClient.cs b/src/EntityFramework_LoL/Sources/Client/ChampionHttpClient.cs index d62b80c..deae099 100644 --- a/src/EntityFramework_LoL/Sources/Client/ChampionHttpClient.cs +++ b/src/EntityFramework_LoL/Sources/Client/ChampionHttpClient.cs @@ -23,12 +23,12 @@ namespace Client var url = $"{ApiChampions}?index={index}&count={count}"; return await _httpClient.GetFromJsonAsync>(url); } - public async void Add(ChampionDto champion) +/* public async void Add(ChampionDto champion) { await _httpClient.PostAsJsonAsync(ApiChampions, champion); - } + }*/ - public async void Delete(ChampionDto champion) +/* public async void Delete(ChampionDto champion) { await _httpClient.DeleteAsync(champion.Name); } @@ -36,7 +36,7 @@ namespace Client public async void Update(ChampionDto champion) { await _httpClient.PutAsJsonAsync(ApiChampions, champion); - } + }*/ } } diff --git a/src/EntityFramework_LoL/Sources/DTO/RuneDto.cs b/src/EntityFramework_LoL/Sources/DTO/RuneDto.cs index f5afb80..5f463b6 100644 --- a/src/EntityFramework_LoL/Sources/DTO/RuneDto.cs +++ b/src/EntityFramework_LoL/Sources/DTO/RuneDto.cs @@ -1,4 +1,5 @@ -using System; +using DTO.enums; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -10,6 +11,8 @@ namespace DTO { public string Name { get; set; } public string Description { get; set; } + public RuneFamilyDto Family { get; set; } + public LargeImageDto Image { get; set; } } } diff --git a/src/EntityFramework_LoL/Sources/DTO/SkinDtoC.cs b/src/EntityFramework_LoL/Sources/DTO/SkinDtoC.cs new file mode 100644 index 0000000..656fb33 --- /dev/null +++ b/src/EntityFramework_LoL/Sources/DTO/SkinDtoC.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DTO +{ + public class SkinDtoC + { + public string Name { get; set; } + public string Description { get; set; } + public string Icon { get; set; } + public LargeImageDto Image { get; set; } + public float Price { get; set; } + public string ChampionName { get; set; } + + + } +} diff --git a/src/EntityFramework_LoL/Sources/DTO/enums/RuneFamilyDto.cs b/src/EntityFramework_LoL/Sources/DTO/enums/RuneFamilyDto.cs new file mode 100644 index 0000000..053249c --- /dev/null +++ b/src/EntityFramework_LoL/Sources/DTO/enums/RuneFamilyDto.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DTO.enums +{ + public enum RuneFamilyDto + { + Unknown, + Precision, + Domination + } +} diff --git a/src/EntityFramework_LoL/Sources/StubLib/StubData.Champions.cs b/src/EntityFramework_LoL/Sources/StubLib/StubData.Champions.cs index ad19275..c487e45 100644 --- a/src/EntityFramework_LoL/Sources/StubLib/StubData.Champions.cs +++ b/src/EntityFramework_LoL/Sources/StubLib/StubData.Champions.cs @@ -84,7 +84,7 @@ namespace StubLib .Select(tuple => tuple.Item1) .Skip(index*count).Take(count)); - private Func filterByName = (champ, substring) => champ.Name.Contains(substring, StringComparison.InvariantCultureIgnoreCase); + private Func filterByName = (champ, substring) => champ.Name.Equals(substring, StringComparison.InvariantCultureIgnoreCase); public Task GetNbItemsByName(string substring) => parent.champions.GetNbItemsWithFilter(champ => filterByName(champ, substring)); diff --git a/src/EntityFramework_LoL/Sources/Tests/ApiTests/ChampionsControllerTest.cs b/src/EntityFramework_LoL/Sources/Tests/ApiTests/ChampionsControllerTest.cs index 61a75a5..021b773 100644 --- a/src/EntityFramework_LoL/Sources/Tests/ApiTests/ChampionsControllerTest.cs +++ b/src/EntityFramework_LoL/Sources/Tests/ApiTests/ChampionsControllerTest.cs @@ -1,4 +1,5 @@ using ApiLol.Controllers; +using ApiLol.Controllers.v2; using DTO; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; @@ -50,7 +51,6 @@ namespace ApiTests Icon = "", Image = new LargeImageDto() { Base64 = "" }, Skins = new List() - }; //Act diff --git a/src/EntityFramework_LoL/Sources/Tests/ConsoleTests/Program.cs b/src/EntityFramework_LoL/Sources/Tests/ConsoleTests/Program.cs index 28dc26b..80c9d9f 100644 --- a/src/EntityFramework_LoL/Sources/Tests/ConsoleTests/Program.cs +++ b/src/EntityFramework_LoL/Sources/Tests/ConsoleTests/Program.cs @@ -1,338 +1,338 @@ using System.Collections.Immutable; -using System.Diagnostics; -using Microsoft.Extensions.DependencyInjection; -using Model; -using StubLib; -using static System.Console; - -namespace ConsoleTests -{ - static class Program - { - static IDataManager dataManager = null!; - - static async Task Main(string[] args) - { - try - { - using var servicesProvider = new ServiceCollection() - .AddSingleton() - .BuildServiceProvider(); - - dataManager = servicesProvider.GetRequiredService(); - - await DisplayMainMenu(); - - Console.ReadLine(); - } - catch (Exception ex) - { - Debug.WriteLine(ex, "Stopped program because of exception"); - throw; - } - } - - public static async Task DisplayMainMenu() - { - Dictionary choices = new Dictionary() - { - [1] = "1- Manage Champions", - [2] = "2- Manage Skins", - [3] = "3- Manage Runes", - [4] = "4- Manage Rune Pages", - [99] = "99- Quit" - }; - - while(true) - { - int input = DisplayAMenu(choices); - - switch(input) - { - case 1: - await DisplayChampionsMenu(); - break; - case 2: - break; - case 3: - break; - case 4: - break; - case 99: - WriteLine("Bye bye!"); - return; - default: - break; - } - } - } - - private static int DisplayAMenu(Dictionary choices) - { - int input=-1; - while(true) - { - WriteLine("What is your choice?"); - WriteLine("--------------------"); - foreach(var choice in choices.OrderBy(kvp => kvp.Key).Select(kvp => kvp.Value)) - { - WriteLine(choice); - } - if(!int.TryParse(ReadLine(), out input) || input == -1) - { - WriteLine("I do not understand what your choice is. Please try again."); - continue; - } - break; - } - WriteLine($"You have chosen: {choices[input]}"); - WriteLine(); - return input; - } - - public static async Task DisplayChampionsMenu() - { - Dictionary choices = new Dictionary() - { - [0] = "0- Get number of champions", - [1] = "1- Get champions", - [2] = "2- Find champions by name", - [3] = "3- Find champions by characteristic", - [4] = "4- Find champions by class", - [5] = "5- Find champions by skill", - [6] = "6- Add new champion", - [7] = "7- Delete a champion", - [8] = "8- Update a champion", - }; - - int input = DisplayAMenu(choices); - - switch(input) - { - case 0: - int nb = await dataManager.ChampionsMgr.GetNbItems(); - WriteLine($"There are {nb} champions"); - WriteLine("**********************"); - break; - case 1: - { - int index = ReadAnInt("Please enter the page index"); - int count = ReadAnInt("Please enter the number of elements to display"); - WriteLine($"{count} champions of page {index+1}"); - var champions = await dataManager.ChampionsMgr.GetItems(index, count, nameof(Champion.Name)); - foreach(var champion in champions) - { - WriteLine($"\t{champion}"); - } - WriteLine("**********************"); - } - break; - case 2: - { - string substring = ReadAString("Please enter the substring to look for in the name of a champion"); - int index = ReadAnInt("Please enter the page index"); - int count = ReadAnInt("Please enter the number of elements to display"); - var champions = await dataManager.ChampionsMgr.GetItemsByName(substring, index, count, nameof(Champion.Name)); - foreach(var champion in champions) - { - WriteLine($"\t{champion}"); - } - WriteLine("**********************"); - } - break; - case 3: - { - string substring = ReadAString("Please enter the substring to look for in the characteristics of champions"); - int index = ReadAnInt("Please enter the page index"); - int count = ReadAnInt("Please enter the number of elements to display"); - var champions = await dataManager.ChampionsMgr.GetItemsByCharacteristic(substring, index, count, nameof(Champion.Name)); - foreach(var champion in champions) - { - WriteLine($"\t{champion}"); - } - WriteLine("**********************"); - } - break; - case 4: - { - ChampionClass championClass = ReadAnEnum($"Please enter the champion class (possible values are: {Enum.GetNames().Aggregate("", (name, chaine) => $"{chaine} {name}")}):"); - int index = ReadAnInt("Please enter the page index"); - int count = ReadAnInt("Please enter the number of elements to display"); - var champions = await dataManager.ChampionsMgr.GetItemsByClass(championClass, index, count, nameof(Champion.Name)); - foreach(var champion in champions) - { - WriteLine($"\t{champion}"); - } - WriteLine("**********************"); - } - break; - case 5: - { - string substring = ReadAString("Please enter the substring to look for in the skills of champions"); - int index = ReadAnInt("Please enter the page index"); - int count = ReadAnInt("Please enter the number of elements to display"); - var champions = await dataManager.ChampionsMgr.GetItemsBySkill(substring, index, count, nameof(Champion.Name)); - foreach(var champion in champions) - { - WriteLine($"\t{champion}"); - } - WriteLine("**********************"); - } - break; - case 6: - { - WriteLine("You are going to create a new champion."); - string name = ReadAString("Please enter the champion name:"); - ChampionClass championClass = ReadAnEnum($"Please enter the champion class (possible values are: {Enum.GetNames().Aggregate("", (name, chaine) => $"{chaine} {name}")}):"); - string bio = ReadAString("Please enter the champion bio:"); - Champion champion = new Champion(name, championClass, bio: bio); - DisplayCreationChampionMenu(champion); - _ = await dataManager.ChampionsMgr.AddItem(champion); - } - break; - case 7: - { - WriteLine("You are going to delete a champion."); - string name = ReadAString("Please enter the champion name:"); - var somechampions = await dataManager.ChampionsMgr.GetItemsByName(name, 0, 10, nameof(Champion.Name)); - var someChampionNames = somechampions.Select(c => c!.Name); - var someChampionNamesAsOneString = someChampionNames.Aggregate("", (name, chaine) => $"{chaine} {name}"); - string champName = ReadAStringAmongPossibleValues($"Who do you want to delete among these champions? (type \"Cancel\" to ... cancel) {someChampionNamesAsOneString}", - someChampionNames.ToArray()); - if(champName != "Cancel") - { - await dataManager.ChampionsMgr.DeleteItem(somechampions.Single(c => c!.Name == champName)); - } - } - break; - case 8: - { - WriteLine("You are going to update a champion."); - string name = ReadAString("Please enter the champion name:"); - var somechampions = await dataManager.ChampionsMgr.GetItemsByName(name, 0, 10, nameof(Champion.Name)); - var someChampionNames = somechampions.Select(c => c!.Name); - var someChampionNamesAsOneString = someChampionNames.Aggregate("", (name, chaine) => $"{chaine} {name}"); - string champName = ReadAStringAmongPossibleValues($"Who do you want to update among these champions? (type \"Cancel\" to ... cancel) {someChampionNamesAsOneString}", - someChampionNames.ToArray()); - if(champName == "Cancel") break; - ChampionClass championClass = ReadAnEnum($"Please enter the champion class (possible values are: {Enum.GetNames().Aggregate("", (name, chaine) => $"{chaine} {name}")}):"); - string bio = ReadAString("Please enter the champion bio:"); - Champion champion = new Champion(champName, championClass, bio: bio); - DisplayCreationChampionMenu(champion); - await dataManager.ChampionsMgr.UpdateItem(somechampions.Single(c => c!.Name == champName), champion); - } - break; - default: - break; - } - - } - - public static void DisplayCreationChampionMenu(Champion champion) - { - Dictionary choices = new Dictionary() - { - [1] = "1- Add a skill", - [2] = "2- Add a skin", - [3] = "3- Add a characteristic", - [99] = "99- Finish" - }; - - while(true) - { - int input = DisplayAMenu(choices); - - switch(input) - { - case 1: - string skillName = ReadAString("Please enter the skill name:"); - SkillType skillType = ReadAnEnum($"Please enter the skill type (possible values are: {Enum.GetNames().Aggregate("", (name, chaine) => $"{chaine} {name}")}):"); - string skillDescription = ReadAString("Please enter the skill description:"); - Skill skill = new Skill(skillName, skillType, skillDescription); - champion.AddSkill(skill); - break; - case 2: - string skinName = ReadAString("Please enter the skin name:"); - string skinDescription = ReadAString("Please enter the skin description:"); - float skinPrice = ReadAFloat("Please enter the price of this skin:"); - Skin skin = new Skin(skinName, champion, skinPrice, description: skinDescription); - break; - case 3: - string characteristic = ReadAString("Please enter the characteristic:"); - int value = ReadAnInt("Please enter the value associated to this characteristic:"); - champion.AddCharacteristics(Tuple.Create(characteristic, value)); - break; - case 99: - return; - default: - break; - } - } - } - - private static int ReadAnInt(string message) - { - while(true) - { - WriteLine(message); - if(!int.TryParse(ReadLine(), out int result)) - { - continue; - } - return result; - } - } - - private static float ReadAFloat(string message) - { - while(true) - { - WriteLine(message); - if(!float.TryParse(ReadLine(), out float result)) - { - continue; - } - return result; - } - } - - private static string ReadAString(string message) - { - while(true) - { - WriteLine(message); - string? line = ReadLine(); - if(line == null) - { - continue; - } - return line!; - } - } - - private static TEnum ReadAnEnum(string message) where TEnum :struct - { - while(true) - { - WriteLine(message); - if(!Enum.TryParse(ReadLine(), out TEnum result)) - { - continue; - } - return result; - } - } - - private static string ReadAStringAmongPossibleValues(string message, params string[] possibleValues) - { - while(true) - { - WriteLine(message); - string? result = ReadLine(); - if(result == null) continue; - if(result != "Cancel" && !possibleValues.Contains(result!)) continue; - return result!; - } - } - } +using System.Diagnostics; +using Microsoft.Extensions.DependencyInjection; +using Model; +using StubLib; +using static System.Console; + +namespace ConsoleTests +{ + static class Program + { + static IDataManager dataManager = null!; + + static async Task Main(string[] args) + { + try + { + using var servicesProvider = new ServiceCollection() + .AddSingleton() + .BuildServiceProvider(); + + dataManager = servicesProvider.GetRequiredService(); + + await DisplayMainMenu(); + + Console.ReadLine(); + } + catch (Exception ex) + { + Debug.WriteLine(ex, "Stopped program because of exception"); + throw; + } + } + + public static async Task DisplayMainMenu() + { + Dictionary choices = new Dictionary() + { + [1] = "1- Manage Champions", + [2] = "2- Manage Skins", + [3] = "3- Manage Runes", + [4] = "4- Manage Rune Pages", + [99] = "99- Quit" + }; + + while(true) + { + int input = DisplayAMenu(choices); + + switch(input) + { + case 1: + await DisplayChampionsMenu(); + break; + case 2: + break; + case 3: + break; + case 4: + break; + case 99: + WriteLine("Bye bye!"); + return; + default: + break; + } + } + } + + private static int DisplayAMenu(Dictionary choices) + { + int input=-1; + while(true) + { + WriteLine("What is your choice?"); + WriteLine("--------------------"); + foreach(var choice in choices.OrderBy(kvp => kvp.Key).Select(kvp => kvp.Value)) + { + WriteLine(choice); + } + if(!int.TryParse(ReadLine(), out input) || input == -1) + { + WriteLine("I do not understand what your choice is. Please try again."); + continue; + } + break; + } + WriteLine($"You have chosen: {choices[input]}"); + WriteLine(); + return input; + } + + public static async Task DisplayChampionsMenu() + { + Dictionary choices = new Dictionary() + { + [0] = "0- Get number of champions", + [1] = "1- Get champions", + [2] = "2- Find champions by name", + [3] = "3- Find champions by characteristic", + [4] = "4- Find champions by class", + [5] = "5- Find champions by skill", + [6] = "6- Add new champion", + [7] = "7- Delete a champion", + [8] = "8- Update a champion", + }; + + int input = DisplayAMenu(choices); + + switch(input) + { + case 0: + int nb = await dataManager.ChampionsMgr.GetNbItems(); + WriteLine($"There are {nb} champions"); + WriteLine("**********************"); + break; + case 1: + { + int index = ReadAnInt("Please enter the page index"); + int count = ReadAnInt("Please enter the number of elements to display"); + WriteLine($"{count} champions of page {index+1}"); + var champions = await dataManager.ChampionsMgr.GetItems(index, count, nameof(Champion.Name)); + foreach(var champion in champions) + { + WriteLine($"\t{champion}"); + } + WriteLine("**********************"); + } + break; + case 2: + { + string substring = ReadAString("Please enter the substring to look for in the name of a champion"); + int index = ReadAnInt("Please enter the page index"); + int count = ReadAnInt("Please enter the number of elements to display"); + var champions = await dataManager.ChampionsMgr.GetItemsByName(substring, index, count, nameof(Champion.Name)); + foreach(var champion in champions) + { + WriteLine($"\t{champion}"); + } + WriteLine("**********************"); + } + break; + case 3: + { + string substring = ReadAString("Please enter the substring to look for in the characteristics of champions"); + int index = ReadAnInt("Please enter the page index"); + int count = ReadAnInt("Please enter the number of elements to display"); + var champions = await dataManager.ChampionsMgr.GetItemsByCharacteristic(substring, index, count, nameof(Champion.Name)); + foreach(var champion in champions) + { + WriteLine($"\t{champion}"); + } + WriteLine("**********************"); + } + break; + case 4: + { + ChampionClass championClass = ReadAnEnum($"Please enter the champion class (possible values are: {Enum.GetNames().Aggregate("", (name, chaine) => $"{chaine} {name}")}):"); + int index = ReadAnInt("Please enter the page index"); + int count = ReadAnInt("Please enter the number of elements to display"); + var champions = await dataManager.ChampionsMgr.GetItemsByClass(championClass, index, count, nameof(Champion.Name)); + foreach(var champion in champions) + { + WriteLine($"\t{champion}"); + } + WriteLine("**********************"); + } + break; + case 5: + { + string substring = ReadAString("Please enter the substring to look for in the skills of champions"); + int index = ReadAnInt("Please enter the page index"); + int count = ReadAnInt("Please enter the number of elements to display"); + var champions = await dataManager.ChampionsMgr.GetItemsBySkill(substring, index, count, nameof(Champion.Name)); + foreach(var champion in champions) + { + WriteLine($"\t{champion}"); + } + WriteLine("**********************"); + } + break; + case 6: + { + WriteLine("You are going to create a new champion."); + string name = ReadAString("Please enter the champion name:"); + ChampionClass championClass = ReadAnEnum($"Please enter the champion class (possible values are: {Enum.GetNames().Aggregate("", (name, chaine) => $"{chaine} {name}")}):"); + string bio = ReadAString("Please enter the champion bio:"); + Champion champion = new Champion(name, championClass, bio: bio); + DisplayCreationChampionMenu(champion); + _ = await dataManager.ChampionsMgr.AddItem(champion); + } + break; + case 7: + { + WriteLine("You are going to delete a champion."); + string name = ReadAString("Please enter the champion name:"); + var somechampions = await dataManager.ChampionsMgr.GetItemsByName(name, 0, 10, nameof(Champion.Name)); + var someChampionNames = somechampions.Select(c => c!.Name); + var someChampionNamesAsOneString = someChampionNames.Aggregate("", (name, chaine) => $"{chaine} {name}"); + string champName = ReadAStringAmongPossibleValues($"Who do you want to delete among these champions? (type \"Cancel\" to ... cancel) {someChampionNamesAsOneString}", + someChampionNames.ToArray()); + if(champName != "Cancel") + { + await dataManager.ChampionsMgr.DeleteItem(somechampions.Single(c => c!.Name == champName)); + } + } + break; + case 8: + { + WriteLine("You are going to update a champion."); + string name = ReadAString("Please enter the champion name:"); + var somechampions = await dataManager.ChampionsMgr.GetItemsByName(name, 0, 10, nameof(Champion.Name)); + var someChampionNames = somechampions.Select(c => c!.Name); + var someChampionNamesAsOneString = someChampionNames.Aggregate("", (name, chaine) => $"{chaine} {name}"); + string champName = ReadAStringAmongPossibleValues($"Who do you want to update among these champions? (type \"Cancel\" to ... cancel) {someChampionNamesAsOneString}", + someChampionNames.ToArray()); + if(champName == "Cancel") break; + ChampionClass championClass = ReadAnEnum($"Please enter the champion class (possible values are: {Enum.GetNames().Aggregate("", (name, chaine) => $"{chaine} {name}")}):"); + string bio = ReadAString("Please enter the champion bio:"); + Champion champion = new Champion(champName, championClass, bio: bio); + DisplayCreationChampionMenu(champion); + await dataManager.ChampionsMgr.UpdateItem(somechampions.Single(c => c!.Name == champName), champion); + } + break; + default: + break; + } + + } + + public static void DisplayCreationChampionMenu(Champion champion) + { + Dictionary choices = new Dictionary() + { + [1] = "1- Add a skill", + [2] = "2- Add a skin", + [3] = "3- Add a characteristic", + [99] = "99- Finish" + }; + + while(true) + { + int input = DisplayAMenu(choices); + + switch(input) + { + case 1: + string skillName = ReadAString("Please enter the skill name:"); + SkillType skillType = ReadAnEnum($"Please enter the skill type (possible values are: {Enum.GetNames().Aggregate("", (name, chaine) => $"{chaine} {name}")}):"); + string skillDescription = ReadAString("Please enter the skill description:"); + Skill skill = new Skill(skillName, skillType, skillDescription); + champion.AddSkill(skill); + break; + case 2: + string skinName = ReadAString("Please enter the skin name:"); + string skinDescription = ReadAString("Please enter the skin description:"); + float skinPrice = ReadAFloat("Please enter the price of this skin:"); + Skin skin = new Skin(skinName, champion, skinPrice, description: skinDescription); + break; + case 3: + string characteristic = ReadAString("Please enter the characteristic:"); + int value = ReadAnInt("Please enter the value associated to this characteristic:"); + champion.AddCharacteristics(Tuple.Create(characteristic, value)); + break; + case 99: + return; + default: + break; + } + } + } + + private static int ReadAnInt(string message) + { + while(true) + { + WriteLine(message); + if(!int.TryParse(ReadLine(), out int result)) + { + continue; + } + return result; + } + } + + private static float ReadAFloat(string message) + { + while(true) + { + WriteLine(message); + if(!float.TryParse(ReadLine(), out float result)) + { + continue; + } + return result; + } + } + + private static string ReadAString(string message) + { + while(true) + { + WriteLine(message); + string? line = ReadLine(); + if(line == null) + { + continue; + } + return line!; + } + } + + private static TEnum ReadAnEnum(string message) where TEnum :struct + { + while(true) + { + WriteLine(message); + if(!Enum.TryParse(ReadLine(), out TEnum result)) + { + continue; + } + return result; + } + } + + private static string ReadAStringAmongPossibleValues(string message, params string[] possibleValues) + { + while(true) + { + WriteLine(message); + string? result = ReadLine(); + if(result == null) continue; + if(result != "Cancel" && !possibleValues.Contains(result!)) continue; + return result!; + } + } + } } \ No newline at end of file