diff --git a/EntityFramework_LoL/Sources/API_LoL_Project/Controllers/version2/ChampionsController.cs b/EntityFramework_LoL/Sources/API_LoL_Project/Controllers/version2/ChampionsController.cs index d922a9a..0092dd4 100644 --- a/EntityFramework_LoL/Sources/API_LoL_Project/Controllers/version2/ChampionsController.cs +++ b/EntityFramework_LoL/Sources/API_LoL_Project/Controllers/version2/ChampionsController.cs @@ -142,7 +142,7 @@ namespace API_LoL_Project.Controllers.version2 // GET api/champions/name [HttpGet("{name}")] - public async Task>> GetChampionsByName(string name) + public async Task>>> GetChampionsByName(string name) { if (name == null || name == "") { @@ -157,7 +157,7 @@ namespace API_LoL_Project.Controllers.version2 if (totalcount <= 0) { _logger.LogError("No chamions found with this name {name} in the dataContext", name); ; - return BadRequest("No chamions found with this name: " + name + "in the dataContext"); + return NotFound("No chamions found with this name: " + name + "in the dataContext"); } var champion = await dataManager.GetItemsByName(name, 0, totalcount); _logger.LogInformation($"========================= {champion} ================================================"); ; @@ -282,6 +282,7 @@ namespace API_LoL_Project.Controllers.version2 // should change for id cause model implementation use filteringbyName to getItemByNAme and it use substring // PUT api//5 [HttpPut("{name}")] + // should be champions full Dto public async Task Put(string name, [FromBody] ChampionDTO value) { try @@ -295,8 +296,15 @@ namespace API_LoL_Project.Controllers.version2 return NotFound(); } - await dataManager.UpdateItem(champion.First(), value.ToModel()); - return Ok(); + var savedUpdatedChampions = await dataManager.UpdateItem(champion.First(), value.ToModel()); + if(savedUpdatedChampions == null) + { + + _logger.LogWarning("The updated champions not returned {name}", name); ; + return BadRequest(); + + } + return Ok(savedUpdatedChampions); } catch (Exception e) { @@ -319,7 +327,12 @@ namespace API_LoL_Project.Controllers.version2 _logger.LogWarning(message + nameof(ChampionsController)); ; return BadRequest(message); } - + var totalcount = await dataManager.GetNbItemsByName(name); + if (totalcount <= 0) + { + _logger.LogError("No chamions found with this name {name} in the dataContext cannot delete", name); + return NotFound($"No chamions found with {name} cannot delete"); + } var champion = await dataManager .GetItemsByName(name, 0, await dataManager.GetNbItems()); diff --git a/EntityFramework_LoL/Sources/API_LoL_Project/Entities.LolDatabase.db-shm b/EntityFramework_LoL/Sources/API_LoL_Project/Entities.LolDatabase.db-shm index e06efcc..359b8ba 100644 Binary files a/EntityFramework_LoL/Sources/API_LoL_Project/Entities.LolDatabase.db-shm and b/EntityFramework_LoL/Sources/API_LoL_Project/Entities.LolDatabase.db-shm differ diff --git a/EntityFramework_LoL/Sources/API_LoL_Project/Entities.LolDatabase.db-wal b/EntityFramework_LoL/Sources/API_LoL_Project/Entities.LolDatabase.db-wal index ed5971c..63690b5 100644 Binary files a/EntityFramework_LoL/Sources/API_LoL_Project/Entities.LolDatabase.db-wal and b/EntityFramework_LoL/Sources/API_LoL_Project/Entities.LolDatabase.db-wal differ diff --git a/EntityFramework_LoL/Sources/ApiLib/ChampionsManager.cs b/EntityFramework_LoL/Sources/ApiLib/ChampionsManager.cs index f56b0f0..bcb83a8 100644 --- a/EntityFramework_LoL/Sources/ApiLib/ChampionsManager.cs +++ b/EntityFramework_LoL/Sources/ApiLib/ChampionsManager.cs @@ -25,6 +25,7 @@ namespace ApiLib public ChampionsManager(ApiManager parent) => this.parent = parent; + private const string urlChampion = "/champions"; public async Task AddItem(Champion? item) { @@ -32,7 +33,7 @@ namespace ApiLib { if (item == null) throw new ArgumentNullException("Champions is null cannot add empty"); - var response = await parent.HttpClient.PostAsJsonAsync("/champions", item.toFullDTO()); + var response = await parent.HttpClient.PostAsJsonAsync(urlChampion, item.toFullDTO()); if (response.IsSuccessStatusCode || response.StatusCode == HttpStatusCode.Created)// mayby changer to check the status code is more secure i think { @@ -119,7 +120,7 @@ namespace ApiLib } } - var response = await parent.HttpClient.GetAsync($"/champions{queryString}"); + var response = await parent.HttpClient.GetAsync($"{urlChampion}{queryString}"); if (response.IsSuccessStatusCode) { @@ -156,7 +157,7 @@ namespace ApiLib { try { - HttpResponseMessage response = await parent.HttpClient.GetAsync($"/champions/characteristic/{charName}?index={index}&count={count}&orderingPropertyName={orderingPropertyName}&descending={descending}"); + HttpResponseMessage response = await parent.HttpClient.GetAsync($"{urlChampion}/characteristic/{charName}?index={index}&count={count}&orderingPropertyName={orderingPropertyName}&descending={descending}"); if (response.IsSuccessStatusCode) { @@ -203,7 +204,7 @@ namespace ApiLib queryString.Append($"&Descending={descending}"); } - var uri = new UriBuilder("/champions/") + var uri = new UriBuilder(urlChampion) { Query = queryString.ToString() }.Uri; @@ -258,7 +259,7 @@ namespace ApiLib } }*/ - Uri uri = new Uri($"/champions/{substring}"); + Uri uri = new Uri($"{urlChampion}/{substring}"); var response = await parent.HttpClient.GetAsync(uri); if (response.IsSuccessStatusCode) @@ -323,7 +324,7 @@ namespace ApiLib queryString += $"&{runePageQueryString}"; } } - Uri uri = new Uri($"/champions/runePage{queryString}"); + Uri uri = new Uri($"{urlChampion}/runePage{queryString}"); var response = await parent.HttpClient.GetAsync(uri); @@ -372,7 +373,7 @@ namespace ApiLib int count = 0; try { - var response = await parent.HttpClient.GetAsync("/champions/count"); + var response = await parent.HttpClient.GetAsync($"{urlChampion}/count"); if (response.IsSuccessStatusCode) { @@ -397,7 +398,7 @@ namespace ApiLib try { - var response = await parent.HttpClient.GetAsync($"/champions/count/characteristic/{charName}"); + var response = await parent.HttpClient.GetAsync($"{urlChampion}/count/characteristic/{charName}"); if (response.IsSuccessStatusCode) { string responseBody = await response.Content.ReadAsStringAsync(); @@ -429,7 +430,7 @@ namespace ApiLib try { - var response = await parent.HttpClient.GetAsync($"/champions/count/class/{championClass}"); + var response = await parent.HttpClient.GetAsync($"{urlChampion}/count/class/{championClass}"); if (response.IsSuccessStatusCode) { string responseBody = await response.Content.ReadAsStringAsync(); @@ -494,7 +495,7 @@ namespace ApiLib try { - string requestUri = "/champions/count/runePage"; + string requestUri = $"{urlChampion}/count/runePage"; if (runePage != null) { @@ -556,7 +557,7 @@ namespace ApiLib } try { - var response = await parent.HttpClient.PutAsJsonAsync($"/champions/{oldItem.Name}", newItem); + var response = await parent.HttpClient.PutAsJsonAsync($"{urlChampion}/{oldItem.Name}", newItem); if (response.IsSuccessStatusCode) { var updatedChampion = await response.Content.ReadFromJsonAsync(); diff --git a/EntityFramework_LoL/Sources/ApiMappeur/SkinMapper.cs b/EntityFramework_LoL/Sources/ApiMappeur/SkinMapper.cs index e9d1c3f..88c1cd4 100644 --- a/EntityFramework_LoL/Sources/ApiMappeur/SkinMapper.cs +++ b/EntityFramework_LoL/Sources/ApiMappeur/SkinMapper.cs @@ -22,7 +22,6 @@ namespace ApiMappeur Description = item.Description, Icon = item.Icon, Price = item.Price, - Champion = item.Champion.Name }; } diff --git a/EntityFramework_LoL/Sources/DTO/SkillDto.cs b/EntityFramework_LoL/Sources/DTO/SkillDto.cs index 2b7f006..6babc14 100644 --- a/EntityFramework_LoL/Sources/DTO/SkillDto.cs +++ b/EntityFramework_LoL/Sources/DTO/SkillDto.cs @@ -8,7 +8,9 @@ namespace DTO { public class SkillDto { - public string Name { get; set; } +/* public SkillDtoType type { get; set; } +*/ public string Name { get; set; } public string Description { get; set; } + } } diff --git a/EntityFramework_LoL/Sources/DTO/SkillDtoType.cs b/EntityFramework_LoL/Sources/DTO/SkillDtoType.cs new file mode 100644 index 0000000..6719005 --- /dev/null +++ b/EntityFramework_LoL/Sources/DTO/SkillDtoType.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DTO +{ + public class SkillDtoType + { + } +} diff --git a/EntityFramework_LoL/Sources/DTO/SkinDto.cs b/EntityFramework_LoL/Sources/DTO/SkinDto.cs index c4ae667..601cf2a 100644 --- a/EntityFramework_LoL/Sources/DTO/SkinDto.cs +++ b/EntityFramework_LoL/Sources/DTO/SkinDto.cs @@ -8,8 +8,8 @@ namespace DTO { public class SkinDto { - public string Champion { get; set; } - public string Name { get; set; } +/* public string Champion { get; set; } +*/ public string Name { get; set; } public string Description { get; set; } public string Icon { get; set; } public float Price { get; set; } diff --git a/EntityFramework_LoL/Sources/Test_Api/ChampionControllerTest.cs b/EntityFramework_LoL/Sources/Test_Api/ChampionControllerTest.cs index 7e274ba..de92c82 100644 --- a/EntityFramework_LoL/Sources/Test_Api/ChampionControllerTest.cs +++ b/EntityFramework_LoL/Sources/Test_Api/ChampionControllerTest.cs @@ -2,15 +2,19 @@ using API_LoL_Project.Controllers; using API_LoL_Project.Controllers.Request; using API_LoL_Project.Controllers.Response; using API_LoL_Project.Controllers.version2; +using API_LoL_Project.Middleware; using DTO; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Model; using Shared; using StubLib; +using System.Collections.ObjectModel; using System.Net; +using System.Xml.Linq; namespace Test_Api { @@ -29,7 +33,7 @@ namespace Test_Api } [TestMethod] - public async Task TestGetChampions() + public async Task TestGetSuccesChampions() { var totalcountTest = await stubMgr.ChampionsMgr.GetNbItems(); @@ -147,79 +151,249 @@ namespace Test_Api Assert.AreEqual("To many object is asked the max is : 0", badRequestResult.Value); } - + [TestMethod] + public async Task TestGetChampionByName_ExistingName() + { + // Arrange + var championName = "lopalinda"; + var champion = new Champion(championName, ChampionClass.Assassin); + await stubMgr.ChampionsMgr.AddItem(champion); + // Act + var getResult = await championCtrl.GetChampionsByName(championName); - /* - [TestMethod] - public async Task TestPostChampions() - { + // Assert + /* Assert.IsInstanceOfType(getResult, typeof(OkObjectResult)); + var objectRes = getResult.Result as OkObjectResult; + Assert.AreEqual(200, objectRes.StatusCode); + Assert.IsInstanceOfType(okResult.Value, typeof(IEnumerable>)); + Assert.IsNotNull(objectRes);*/ - var getResult = await championCtrl.Get(); - Console.WriteLine(getResult); - var objectRes = getResult as OkObjectResult; - Assert.AreEqual(200, objectRes.StatusCode); + Assert.IsInstanceOfType(getResult.Result, typeof(OkObjectResult)); + var okResult = getResult.Result as OkObjectResult; + Assert.IsInstanceOfType(okResult.Value, typeof(IEnumerable>)); + var responseList = okResult.Value as IEnumerable>; + Assert.AreEqual(1, responseList.Count()); + var response = responseList.First(); + Assert.AreEqual(champion.Name, response.Data.Name); + } + + + [TestMethod] + public async Task TestGetChampionsByName_ReturnsBadRequest_WhenNameIsEmpty() + { + // Arrange + var name = ""; - Assert.IsNotNull(objectRes); + // Act + var result = await championCtrl.GetChampionsByName(name); - var champions = objectRes?.Value as IEnumerable; + // Assert + Assert.IsInstanceOfType(result.Result, typeof(BadRequestObjectResult)); + var badRequestResult = result.Result as BadRequestObjectResult; + Assert.AreEqual("Can not get champions without the name (is empty)", badRequestResult.Value); + } + [TestMethod] + public async Task TestGetChampionsByName_ReturnsBadRequest_WhenNoChampionsFound() + { + // Arrange + var name = "NonExistentChampionName"; + + // Act + var result = await championCtrl.GetChampionsByName(name); - Assert.IsNotNull(champions); + // Assert + Assert.IsInstanceOfType(result.Result, typeof(NotFoundObjectResult)); + var badRequestResult = result.Result as NotFoundObjectResult; + Assert.AreEqual("No chamions found with this name: NonExistentChampionNamein the dataContext", badRequestResult.Value); + } - } + /*[TestMethod] + public async Task TestPostChampionsSucess() + { + var championName = "bhbhb"; + var expectedChampion = new ChampionFullDTO() + { + Characteristics = new ReadOnlyDictionary(new Dictionary() { + { "health", 500 }, + { "attack damage", 60 }, + { "ability power", 0 } + }), + Name = championName, + Bio = "Garen is a strong and noble warrior, the pride of Demacia.", + Class = ChampionClass.Fighter, + Icon = "https://example.com/garen-icon.png", + LargeImage = new ImageDTO() { base64 = "xyz" }, + Skins = new List() { + new SkinDto() { + Name = "Classic Garen", + Description = "The default skin for Garen.", + Icon = "https://example.com/garen-classic-icon.png", + Price = 1350, + LargeImage = new ImageDTO() { base64 = "xyz" } + }, + new SkinDto() { + Name = "God-King Garen", + Description = "Garen as a divine being.", + Icon = "https://example.com/garen-god-king-icon.png", + Price = 1820, + LargeImage = new ImageDTO() { base64 = "xyz" } + } + }, + Skills = new List() { + new Skill("Decisive Strike", SkillType.Basic, "Garen's next attack strikes a vital area of his foe, dealing bonus damage and silencing them."), + new Skill("Courage", SkillType.Basic, "Garen passively increases his armor and magic resistance by killing enemies. He may also activate this ability to gain additional defensive statistics."), + new Skill("Judgment", SkillType.Basic, "Garen rapidly spins his sword around his body, dealing physical damage to nearby enemies and reducing the duration of all incoming crowd control effects."), + new Skill("Demacian Justice", SkillType.Ultimate, "Garen calls upon the might of Demacia to deal a finishing blow to an enemy champion, dealing massive damage based on their missing health.") + } + }; + var rep = await championCtrl.Post(expectedChampion); + + - [TestMethod] - public async Task TestUpdateChampions() - { + Assert.AreEqual(200, objectRes.StatusCode); - var getResult = await championCtrl.Get(); - Console.WriteLine(getResult); - var objectRes = getResult as OkObjectResult; + Assert.IsNotNull(objectRes); - Assert.AreEqual(200, objectRes.StatusCode); + var champions = objectRes?.Value as IEnumerable; - Assert.IsNotNull(objectRes); + Assert.IsNotNull(champions); - var champions = objectRes?.Value as IEnumerable; - Assert.IsNotNull(champions); + } + */ + [TestMethod] + public async Task TestPost_ReturnsCreatedAndSavedChampion() + { + // Arrange + var expectedChampion = new ChampionFullDTO() + { + Characteristics = new ReadOnlyDictionary(new Dictionary() { + { "health", 500 }, + { "attack damage", 60 }, + { "ability power", 0 } + }), + Name = "iuhbbhs", + Bio = "Garen is a strong and noble warrior, the pride of Demacia.", + Class = ChampionClass.Fighter, + Icon = "https://example.com/garen-icon.png", + LargeImage = new ImageDTO() { base64 = "xyz" }, + Skins = new List() { + new SkinDto() { + Name = "Classic Garen", + Description = "The default skin for Garen.", + Icon = "https://example.com/garen-classic-icon.png", + Price = 1350, + LargeImage = new ImageDTO() { base64 = "xyz" } + }, + new SkinDto() { + Name = "God-King Garen", + Description = "Garen as a divine being.", + Icon = "https://example.com/garen-god-king-icon.png", + Price = 1820, + LargeImage = new ImageDTO() { base64 = "xyz" } + } + }, + Skills = new List() { + new Skill("Decisive Strike", SkillType.Basic, "Garen's next attack strikes a vital area of his foe, dealing bonus damage and silencing them."), + new Skill("Courage", SkillType.Basic, "Garen passively increases his armor and magic resistance by killing enemies. He may also activate this ability to gain additional defensive statistics."), + new Skill("Judgment", SkillType.Basic, "Garen rapidly spins his sword around his body, dealing physical damage to nearby enemies and reducing the duration of all incoming crowd control effects."), + new Skill("Demacian Justice", SkillType.Ultimate, "Garen calls upon the might of Demacia to deal a finishing blow to an enemy champion, dealing massive damage based on their missing health.") + } + }; + // Act + var postResult = await championCtrl.Post(expectedChampion); - } + // Assert + Assert.IsInstanceOfType(postResult, typeof(CreatedAtActionResult)); + var objectRes = postResult as CreatedAtActionResult; + Assert.AreEqual(201, objectRes.StatusCode); + Assert.IsNotNull(objectRes); + Assert.AreEqual(nameof(championCtrl.Get), objectRes.ActionName); + var createdChampion = objectRes.Value as ChampionDTO; + Assert.IsNotNull(createdChampion); + Assert.AreEqual(expectedChampion.Name, createdChampion.Name); + Assert.AreEqual(expectedChampion.Class, createdChampion.Class); + } - [TestMethod] - public async Task TestDeleteChampions() - { + [TestMethod] + public async Task TestPutChampion() + { + // Arrange + var championName = "kakarot"; + var updatedChampion = new ChampionDTO + { + Name = championName, + Class = ChampionClass.Mage, + Icon = "dsodm", + Bio = "totto", + }; - var getResult = await championCtrl.Get(); - Console.WriteLine(getResult); - var objectRes = getResult as OkObjectResult; + await stubMgr.ChampionsMgr.AddItem(new Champion(championName, ChampionClass.Assassin)); + // Act + var result = await championCtrl.Put(championName, updatedChampion); - Assert.AreEqual(200, objectRes.StatusCode); + // Assert + Assert.IsInstanceOfType(result, typeof(OkObjectResult)); + var champion = await stubMgr.ChampionsMgr.GetItemsByName(championName, 0, 1); + Assert.AreEqual(updatedChampion.Name, champion.First().Name); + Assert.AreEqual(updatedChampion.Class, champion.First().Class); + Assert.AreEqual(updatedChampion.Bio, champion.First().Bio); + } - Assert.IsNotNull(objectRes); + [TestMethod] + public async Task TestDeleteChampion() + { + // Arrange + var championToDelete = new Champion("Yasuo", ChampionClass.Fighter); + await stubMgr.ChampionsMgr.AddItem(championToDelete); - var champions = objectRes?.Value as IEnumerable; + // Act + var result = await championCtrl.Delete(championToDelete.Name); - Assert.IsNotNull(champions); + // Assert + Assert.IsInstanceOfType(result, typeof(OkResult)); + Assert.AreEqual(200, (result as OkResult).StatusCode); + var championsAfterDelete = await stubMgr.ChampionsMgr.GetItems(0, await stubMgr.ChampionsMgr.GetNbItems()); + Assert.IsFalse(championsAfterDelete.Any(c => c.Name == championToDelete.Name)); + } - } - + [TestMethod] + public async Task TestDeleteChampionWithInvalidName() + { + // Arrange + var invalidName = "Invalid Name"; - + // Act + var result = await championCtrl.Delete(invalidName); - + // Assert + Assert.IsInstanceOfType(result, typeof(NotFoundObjectResult)); + Assert.AreEqual(404, (result as NotFoundObjectResult).StatusCode); + Assert.AreEqual($"No chamions found with {invalidName} cannot delete", (result as NotFoundObjectResult).Value); + } - + [TestMethod] + public async Task TestDeleteChampionWithEmptyName() + { + // Arrange + var emptyName = string.Empty; + // Act + var result = await championCtrl.Delete(emptyName); + // Assert + Assert.IsInstanceOfType(result, typeof(BadRequestObjectResult)); + Assert.AreEqual(400, (result as BadRequestObjectResult).StatusCode); + Assert.AreEqual("Can not delelte champions without the name (is empty)", (result as BadRequestObjectResult).Value); + } - */ } } \ No newline at end of file