Add : Unit tests
continuous-integration/drone/push Build is failing Details

testApp
Thomas Chazot 2 years ago
parent 4ee19fbbf3
commit ce66f1c2cf

@ -4,10 +4,18 @@
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<StartWorkingDirectory>$(MSBuildProjectDirectory)</StartWorkingDirectory>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.4">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="7.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.4" />
</ItemGroup>
<ItemGroup>
@ -28,5 +36,8 @@
<ProjectReference Include="..\StubLib\StubLib.csproj">
<GlobalPropertiesToRemove></GlobalPropertiesToRemove>
</ProjectReference>
<ProjectReference Include="..\DataManagers\DataManagers.csproj">
<GlobalPropertiesToRemove></GlobalPropertiesToRemove>
</ProjectReference>
</ItemGroup>
</Project>

@ -6,6 +6,8 @@ using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Model;
using Microsoft.Extensions.Logging;
using DataManagers;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
@ -16,82 +18,111 @@ namespace ApiLol.Controllers
{
private readonly ILogger<ChampionController> _logger;
private StubData.ChampionsManager championsManager = new StubData.ChampionsManager(new StubData());
private IDataManager dataManager;
public ChampionController(ILogger<ChampionController> logger)
public ChampionController(ILogger<ChampionController> logger, IDataManager manager)
{
_logger = logger;
dataManager = manager;
}
// GET: api/champion
[HttpGet]
public async Task<ActionResult<IEnumerable<ChampionDTO>>> Get()
[HttpGet("GetChampions")]
public async Task<ActionResult<IEnumerable<ChampionDTO>>> GetChampions(int nb = 3)
{
IEnumerable<Champion?> champs = await championsManager.GetItems(0, await championsManager.GetNbItems());
IEnumerable<ChampionDTO> championDTOs = champs.ToDtos();
var champions = await dataManager.ChampionsMgr.GetItems(0, nb);
_logger.Log(LogLevel.Information, $"Les champions ont bien été envoyées");
return Ok(champions.ToDtos());
return Ok(championDTOs);
}
/*
// GET api/champion/5
[HttpGet("{id}")]
public ActionResult<ChampionDTO?> Get(int id)
// GET api/champion/name
[HttpGet("getChampions/{name}")]
public async Task<ActionResult<ChampionDTO?>> GetChampionsByName(string name, int nb =3, int index = 0)
{
ChampionDTO? champion = champions.SingleOrDefault((ChampionEntity arg) => arg.Id == id)?.ToDto();
IEnumerable<Champion?> champion = await dataManager.ChampionsMgr.GetItemsByName(name, index, nb);
if (champion != null)
{
return Ok(champion);
return Ok(champion.ToDtos());
}
return BadRequest();
}
*/
// POST api/champion
[HttpPost]
public ActionResult Post([FromBody]ChampionDTO? champion)
[HttpPost("PostChampion")]
public async Task<ActionResult<ChampionDTO>> PostChampion(ChampionDTO champ)
{
if (champion == null){
return BadRequest();
}
else
var c = await dataManager.ChampionsMgr.AddItem(ChampionMapper.ToPoco(champ));
if (c != null)
{
championsManager.AddItem(champion.ToPoco());
return Ok();
_logger.Log(LogLevel.Information, "Le champion a été ajouté à la base");
return Ok(c);
}
return BadRequest();
}
// PUT api/champion/5
[HttpPut("ChampionDto")]
public ActionResult Put([FromBody] ChampionDTO? champion, ChampionDTO? newChampion)
[HttpPost("PostChampions")]
public async Task<ActionResult<IEnumerable<ChampionDTO>>> PostChampions(List<ChampionDTO> champs)
{
if (champion == null || newChampion == null)
var list = new List<ChampionDTO>();
foreach (ChampionDTO champ in champs)
{
return BadRequest();
var c = await dataManager.ChampionsMgr.AddItem(ChampionMapper.ToPoco(champ));
if ( c != null)
{
list.Add(c.ToDto());
_logger.Log(LogLevel.Information, $"Le champion {champ.Name} a été ajouté à la base");
}
else
{
_logger.Log(LogLevel.Information, $"Le champion {champ.Name} n'a pas été ajouté à la base");
}
}
else
return Ok(list);
}
[HttpPut("PutChampion")]
public async Task<ActionResult<ChampionDTO>> Put(ChampionDTO oldChamp, ChampionDTO champ)
{
var c = await dataManager.ChampionsMgr.UpdateItem(oldChamp.ToPoco(), champ.ToPoco());
if (c!=null)
{
championsManager.UpdateItem(champion.ToPoco(), newChampion.ToPoco());
return Ok();
_logger.Log(LogLevel.Information, $"Le champion {champ.Name} a été modifié ");
return Ok(c);
}
_logger.Log(LogLevel.Information, $"Le champion {champ.Name} n'a pas été modifié");
return BadRequest();
}
// DELETE api/values/5
// DELETE api/values
[HttpDelete("ChampionDto")]
public ActionResult Delete([FromBody] ChampionDTO? champion)
public async Task<ActionResult> DeleteChampion([FromBody] ChampionDTO champion)
{
if (champion == null)
if (await dataManager.ChampionsMgr.DeleteItem(champion.ToPoco()))
{
return BadRequest();
return Ok();
}
else
return BadRequest();
}
[HttpDelete("DeleteChampions")]
public async Task<ActionResult<IEnumerable<ChampionDTO>>> DeleteChampions(List<ChampionDTO> champions, int nb = 10)
{
foreach (ChampionDTO champ in champions)
{
championsManager.DeleteItem(champion.ToPoco());
return Ok();
if (await dataManager.ChampionsMgr.DeleteItem(champ.ToPoco()))
{
_logger.Log(LogLevel.Information, $"Le champion {champ.Name} a été supprimé");
}
else
{
_logger.Log(LogLevel.Information, $"Le champion {champ.Name} n'a pas été supprimé");
}
}
return Ok();
}
}
}

@ -0,0 +1,153 @@
using ApiLol.DTO;
using ApiLol.Mapping;
using Microsoft.AspNetCore.Mvc;
using Model;
using StubLib;
using System.Data;
using System.Text;
namespace API.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class RuneController : Controller
{
private readonly ILogger<RuneController> _logger;
private IDataManager dataManager = new StubData();
public RuneController(ILogger<RuneController> logger)
{
_logger = logger;
}
[HttpGet("GetRune/{name}")]
public async Task<ActionResult<IEnumerable<RuneDTO>>> GetRune(string name, int nb=3, int index = 0)
{
var runes = await dataManager.RunesMgr.GetItemsByName(name, index, nb);
if (!runes.Any())
{
_logger.Log(LogLevel.Warning, $"La rune {name} n'existe pas");
return BadRequest(name);
}
else
{
_logger.Log(LogLevel.Information, $"Les runes avec {name} ont été envoyées");
return Ok(runes.Select(x => x?.ToDto()));
}
}
[HttpGet("GetRunes")]
public async Task<ActionResult<IEnumerable<RuneDTO>>> GetRunes(int nb = 15)
{
var runes = await dataManager.RunesMgr.GetItems(0, nb);
return Ok(runes.Select(x => x?.ToDto()));
}
[HttpPost("PostRune")]
public async Task<ActionResult<RuneDTO?>> PostRune(RuneDTO rune)
{
var r = await dataManager.RunesMgr.AddItem(rune.ToPoco());
if (r != null)
{
_logger.Log(LogLevel.Information, $"La Rune {rune.Name} a été ajouté à la base");
return Ok(r.ToDto());
}
return BadRequest(r);
}
[HttpPost("PostRunes")]
public async Task<ActionResult<IEnumerable<RuneDTO>>> PostRunes(List<RuneDTO> runes)
{
var l = new List<RuneDTO>();
foreach (RuneDTO rune in runes)
{
var r = await dataManager.RunesMgr.AddItem(rune.ToPoco());
if (r != null)
{
l.Add(r.ToDto());
_logger.Log(LogLevel.Information, $"La Rune {rune.Name} a été ajoutée à la base");
}
else
{
_logger.Log(LogLevel.Warning, $"La Rune {rune.Name} recherchée n'existe pas ou il y en a plusieurs avec ce nom");
}
}
return Ok(l);
}
[HttpPut("PutRune")]
public async Task<ActionResult<RuneDTO>> PutRune(RuneDTO rune)
{
var ancienne = await dataManager.RunesMgr.GetItemsByName(rune.Name, 0, 1);
if (ancienne.Count() != 1)
{
_logger.Log(LogLevel.Warning, $"La Rune {rune.Name} recherchée n'existe pas ou il y en a plusieurs avec ce nom");
return BadRequest(rune);
}
else
{
await dataManager.RunesMgr.UpdateItem(ancienne.FirstOrDefault(), rune.ToPoco());
_logger.Log(LogLevel.Information, $"La Rune {rune.Name} a été modifiée de la base");
var r = await dataManager.RunesMgr.GetItemsByName(rune.Name, 0, 1);
return Ok(r.First());
}
}
[HttpPut("PutRunes")]
public async Task<ActionResult<IEnumerable<RuneDTO>>> PutRunes(List<RuneDTO> runes, int nb = 10)
{
foreach (RuneDTO run in runes)
{
var rune = await dataManager.RunesMgr.GetItemsByName(run.Name, 0, 1);
if (!rune.Any())
{
_logger.Log(LogLevel.Warning, $"La Rune {run.Name} recherchée n'existe pas");
BadRequest(run);
}
else
{
await dataManager.RunesMgr.UpdateItem(rune.FirstOrDefault(), run.ToPoco());
_logger.Log(LogLevel.Information, $"La Rune {run.Name} a été modifiée de la base");
}
}
var Runes = await dataManager.RunesMgr.GetItems(0, nb);
return Ok(Runes.Select(x => x?.ToDto()));
}
[HttpDelete("DeleteRune")]
public async Task<ActionResult<Boolean>> DeleteRune(RuneDTO rune)
{
var retour = await dataManager.RunesMgr.DeleteItem(rune.ToPoco());
if (retour) {
_logger.Log(LogLevel.Information, $"La Rune {rune.Name} a été supprimée de la base");
return Ok(retour);
}
_logger.Log(LogLevel.Warning, $"La Rune {rune.Name} recherchée n'existe pas");
return BadRequest(retour);
}
[HttpDelete("DeleteRunes")]
public async Task<ActionResult<Boolean>> DeleteRunes(List<RuneDTO> runes)
{
foreach (RuneDTO run in runes)
{
var retour = await dataManager.RunesMgr.DeleteItem(run.ToPoco());
if (!retour)
{
_logger.Log(LogLevel.Warning, $"La Rune {run.Name} recherchée n'existe pas");
BadRequest(run);
}
else
{
_logger.Log(LogLevel.Information, $"La Rune {run.Name} a été supprimée de la base");
}
}
return Ok(true);
}
}
}

@ -16,11 +16,11 @@ namespace ApiLol
public ChampionClass ChampClass { get; set; }
public LargeImage Image { get; set; }
//public LargeImage Image { get; set; }
public IEnumerable<CharacteristicDTO> Characteristics { get; set; }
public IEnumerable<Skin> Skins { get; set; }
//public IEnumerable<Skin> Skins { get; set; }
}
}

@ -5,17 +5,15 @@ namespace ApiLol.DTO
{
public class RuneDTO
{
public string Nom { get; set; }
public string Description { get; set; }
public string Famille { get; set; }
public RuneFamily Family { get; set; }
public string Icon { get; set; }
public string Name { get; set; }
public LargeImage Image { get; set; }
//public LargeImage Image { get; set; }
}

@ -13,7 +13,7 @@ namespace ApiLol.DTO
public string Icon { get; set; }
public LargeImage Image { get; set; }
//public LargeImage Image { get; set; }
}
}

@ -20,8 +20,8 @@ namespace ApiLol
Bio = champion.Bio,
Icon = champion.Icon,
ChampClass = champion.Class,
Image = champion.Image,
Skins = champion.Skins,
//Image = champion.Image,
//Skins = champion.Skins,
Characteristics = champion.Characteristics.ToDto()
};
}
@ -42,7 +42,7 @@ namespace ApiLol
{
throw new NullReferenceException();
}
return new Champion(name: champion.Name, champClass: champion.ChampClass, icon: champion.Icon, bio: champion.Bio, image: champion.Image.Base64);
return new Champion(name: champion.Name, champClass: champion.ChampClass, icon: champion.Icon, bio: champion.Bio);
}
public static IEnumerable<Champion> ToPocos(this IEnumerable<ChampionDTO> champions)

@ -0,0 +1,38 @@
using System;
using Model;
using static System.Net.Mime.MediaTypeNames;
using System.Xml.Linq;
using ApiLol.DTO;
namespace ApiLol.Mapping
{
public static class RuneMapper
{
public static RuneDTO ToDto(this Rune rune)
{
if (rune == null)
{
throw new NullReferenceException();
}
return new RuneDTO
{
Name = rune.Name,
Description = rune.Description,
Family = rune.Family,
Icon = rune.Icon
};
}
public static Rune ToPoco(this RuneDTO rune) {
if (rune == null)
{
throw new NullReferenceException();
}
return new Rune(rune.Name, rune.Family, rune.Icon, rune.Description);
}
}
}

@ -15,7 +15,7 @@ namespace ApiLol.Mapping
Description = skin.Description,
Price = skin.Price,
Icon = skin.Icon,
Image = skin.Image
//Image = skin.Image
};
}

@ -10,7 +10,4 @@
<ItemGroup>
<None Remove="Microsoft.AspNetCore.Http" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
</ItemGroup>
</Project>

@ -5,8 +5,5 @@ using static System.Net.WebRequestMethods;
HttpClient http = new HttpClient();
//http.BaseAddress = new Uri("https://localhost:7006/");
Console.WriteLine(await http.GetStringAsync("https://localhost:7006/api/Champion"));
Console.WriteLine(await http.GetStringAsync("https://localhost:7006/api/Champion/1"));
//Console.WriteLine(await http.GetStringAsync("https://localhost:7006/api/Champions"));
//Console.WriteLine(await http.GetStringAsync("https://localhost:7006/api/Champion/1"));

@ -19,13 +19,13 @@
<None Remove="Microsoft.EntityFrameworkCore.Tools" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.2">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.4">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.2">
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="7.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.4">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>

@ -7,6 +7,7 @@ Console.WriteLine("Hello, World!");
using (var db = new DbDataManager(new EFLib.LolContext()))
{
await db.Context.Database.EnsureCreatedAsync();
IEnumerable<Champion?> champions = await db.ChampionsMgr.GetItems(0, 10);
foreach (Champion c in champions)

Binary file not shown.

@ -8,7 +8,7 @@ namespace DataManagers
{
public static Champion ToPoco(this ChampionEntity champion)
{
return new Champion(id: champion.Id, name: champion.Name, champClass: champion.ChampClass, icon: champion.Icon, bio: champion.Bio);
return new Champion(id: champion.Id, name: champion.Name, champClass: champion.ChampClass, icon: champion.Icon, bio: champion.Bio, image: champion.LargeImage.Base64, imageId: champion.ImageId);
}
public static ChampionEntity ToEntity(this Champion champion) => new ChampionEntity
@ -18,6 +18,8 @@ namespace DataManagers
Bio = champion.Bio,
Icon = champion.Icon,
ChampClass = champion.Class,
ImageId = champion.Image.Id,
LargeImage = champion.Image.ToEntity()
};

@ -14,31 +14,9 @@ namespace DataManagers
Context = context;
}
private IEnumerable<Champion> SortChampions(IEnumerable<Champion> champs, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
switch (orderingPropertyName?.ToLower())
{
case "bio":
champs = champs.OrderBy(arg => arg.Bio.ToLower()).ToList();
break;
case "class":
champs = champs.OrderBy(arg => arg.Class).ToList();
break;
default:
champs = champs.OrderBy(arg => arg.Name.ToLower()).ToList();
break;
}
if (descending)
{
champs = champs.Reverse().ToList();
}
if (index + count > champs.ToList().Count) return champs.ToList().GetRange(index, champs.ToList().Count - index);
return champs.ToList().GetRange(index, count);
}
public async Task<Champion?> AddItem(Champion? item)
{
if (item != null && Context.Champions.SingleOrDefault((ChampionEntity arg) => arg.Name == item.Name)?.ToPoco() == null)
if (item != null && Context.Champions.SingleOrDefault((ChampionEntity arg) => arg.Id == item.Id || arg.Name == item.Name) == null)
{
await Context.Champions.AddAsync(item.ToEntity());
await Context.SaveChangesAsync();
@ -51,7 +29,7 @@ namespace DataManagers
{
if (item != null)
{
ChampionEntity? entity = await Context.Champions.SingleOrDefaultAsync((ChampionEntity arg) => arg.Name == item.Name);
ChampionEntity? entity = await Context.Champions.SingleOrDefaultAsync((ChampionEntity arg) => arg.Id == item.Id || arg.Name == item.Name);
if (entity != null)
{
Context.Champions.Remove(entity);
@ -64,8 +42,24 @@ namespace DataManagers
public async Task<IEnumerable<Champion?>> GetItems(int index, int count, string? orderingPropertyName = null, bool descending = false)
{
IEnumerable<Champion> champs = await Task.Run(() => Context.Champions.ToList().ToPocos());
return SortChampions(champs, index, count,orderingPropertyName, descending);
IEnumerable<Champion> champs = new List<Champion>();
switch (orderingPropertyName?.ToLower())
{
case "bio":
champs = await Task.Run(() => Context.Champions.OrderBy((arg) => arg.Bio).Skip(index * count).Take(count).ToList().ToPocos());
break;
case "class":
champs = await Task.Run(() => Context.Champions.OrderBy((arg) => arg.ChampClass).Skip(index * count).Take(count).ToList().ToPocos());
break;
default:
champs = await Task.Run(() => Context.Champions.OrderBy((arg) => arg.Name).Skip(index * count).Take(count).ToList().ToPocos());
break;
}
if (descending)
{
champs.Reverse();
}
return champs;
}
public async Task<int> GetNbItems()
@ -81,14 +75,46 @@ namespace DataManagers
public async Task<IEnumerable<Champion?>> GetItemsByClass(ChampionClass championClass, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
IEnumerable<Champion> champs = await Task.Run(() => Context.Champions.ToList().ToPocos().Where(arg => arg.Class == championClass));
return SortChampions(champs, index, count, orderingPropertyName, descending);
IEnumerable<Champion> champs = new List<Champion>();
switch (orderingPropertyName?.ToLower())
{
case "bio":
champs = await Task.Run(() => Context.Champions.Where((arg) => arg.ChampClass == championClass).OrderBy((arg) => arg.Bio).Skip(index * count).Take(count).ToList().ToPocos());
break;
case "class":
champs = await Task.Run(() => Context.Champions.Where((arg) => arg.ChampClass == championClass).OrderBy((arg) => arg.ChampClass).Skip(index * count).Take(count).ToList().ToPocos());
break;
default:
champs = await Task.Run(() => Context.Champions.Where((arg) => arg.ChampClass == championClass).OrderBy((arg) => arg.Name).Skip(index * count).Take(count).ToList().ToPocos());
break;
}
if (descending)
{
champs.Reverse();
}
return champs;
}
public async Task<IEnumerable<Champion?>> GetItemsByName(string substring, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
IEnumerable<Champion> champs = await Task.Run(() => Context.Champions.ToList().ToPocos().Where(arg => arg.Name.Contains(substring)));
return SortChampions(champs, index, count, orderingPropertyName, descending);
IEnumerable<Champion> champs = new List<Champion>();
switch (orderingPropertyName?.ToLower())
{
case "bio":
champs = await Task.Run(() => Context.Champions.Where((arg) => arg.Name.Contains(substring)).OrderBy((arg) => arg.Bio).Skip(index * count).Take(count).ToList().ToPocos());
break;
case "class":
champs = await Task.Run(() => Context.Champions.Where((arg) => arg.Name.Contains(substring)).OrderBy((arg) => arg.ChampClass).Skip(index * count).Take(count).ToList().ToPocos());
break;
default:
champs = await Task.Run(() => Context.Champions.Where((arg) => arg.Name.Contains(substring)).OrderBy((arg) => arg.Name).Skip(index * count).Take(count).ToList().ToPocos());
break;
}
if (descending)
{
champs.Reverse();
}
return champs;
}
public Task<IEnumerable<Champion?>> GetItemsByRunePage(RunePage? runePage, int index, int count, string? orderingPropertyName = null, bool descending = false)

@ -7,7 +7,7 @@ namespace DataManagers
public class DbDataManager : IDataManager
{
private LolContext Context { get; set; }
public LolContext Context { get; set; }
public IChampionsManager ChampionsMgr => new DbChampionManager(Context);
@ -32,6 +32,11 @@ namespace DataManagers
{
Context.Database.EnsureCreated();
}
public async Task EnsureCreatedAsync()
{
await Context.Database.EnsureCreatedAsync();
}
}
}

@ -0,0 +1,42 @@
using System;
using EFLib;
using Model;
namespace DataManagers
{
public static class LargeImageChanger
{
public static LargeImage ToPoco(this LargeImageEntity largeImage)
{
return new LargeImage(largeImage.Id, largeImage.Base64);
}
public static LargeImageEntity ToEntity(this LargeImage largeImage) => new LargeImageEntity
{
Id = largeImage.Id,
Base64 = largeImage.Base64
};
public static IEnumerable<LargeImage> ToPocos(this IEnumerable<LargeImageEntity> largeImages)
{
List<LargeImage> images = new List<LargeImage>();
foreach (LargeImageEntity l in largeImages)
{
images.Add(l.ToPoco());
}
return images;
}
public static IEnumerable<LargeImageEntity> toEntities(this IEnumerable<LargeImage> largeImages)
{
List<LargeImageEntity> images = new List<LargeImageEntity>();
foreach (LargeImage l in largeImages)
{
images.Add(l.ToEntity());
}
return images;
}
}
}

@ -16,6 +16,10 @@ namespace EFLib
public ChampionClass ChampClass { get; set;}
public int ImageId { get; set; }
public LargeImageEntity LargeImage { get; set; }
}
}

@ -1,7 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
@ -15,13 +14,13 @@
<None Remove="Microsoft.EntityFrameworkCore.Tools" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.2">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.4">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.2">
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.4">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>

@ -0,0 +1,13 @@
using System;
namespace EFLib
{
public class LargeImageEntity
{
public int Id { get; set; }
public string Base64 { get; set; }
public ChampionEntity Champion { get; set; }
}
}

@ -1,12 +1,16 @@
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.VisualBasic;
using Model;
namespace EFLib
{
public class LolContext : DbContext, IDisposable
{
public class LolContext : DbContext
{
public DbSet<ChampionEntity> Champions { get; set; }
public DbSet<LargeImageEntity> LargeImages { get; set; }
public LolContext(DbContextOptions<LolContext> options)
: base(options)
{ }
@ -21,6 +25,30 @@ namespace EFLib
optionsBuilder.UseSqlite("Data Source=oiseaux.db");
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<LargeImageEntity>()
.HasOne(e => e.Champion)
.WithOne(z => z.LargeImage)
.HasForeignKey<ChampionEntity>(x => x.ImageId);
var image1 = new LargeImageEntity { Id = 1, Base64 = "test1" };
var image2 = new LargeImageEntity { Id = 2, Base64 = "test2" };
var image3 = new LargeImageEntity { Id = 3, Base64 = "test3" };
modelBuilder.Entity<LargeImageEntity>().HasData(image1, image2, image3);
modelBuilder.Entity<ChampionEntity>().HasData(
new ChampionEntity { Id = 1, Name = "Test1", Bio = "Salut", ChampClass = ChampionClass.Fighter, Icon = "bla", ImageId = 1 },
new ChampionEntity { Id = 2, Name = "Test2", Bio = "hey", ChampClass = ChampionClass.Assassin, Icon = "bla", ImageId = 2 },
new ChampionEntity { Id = 3, Name = "Test3", Bio = "coucou", ChampClass = ChampionClass.Tank, Icon = "bla", ImageId = 3 }
);
}
}
}

@ -1,15 +0,0 @@
// See https://aka.ms/new-console-template for more information
using EFLib;
Console.WriteLine("Hello, World!");
using (var context = new LolContext())
{
context.Champions.Add(new ChampionEntity
{
Name = "Test",
Bio = "Bonjour",
Icon = "Wouhou"
});
context.SaveChanges();
}

Binary file not shown.

@ -23,6 +23,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApi", "ConsoleApi\Co
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{EE69586D-A6A8-40C4-93D7-DBDFEBC6844A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LolApp", "LolApp\LolApp.csproj", "{0C898A04-092A-49AA-BE65-8AE818A2AF50}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ViewModels", "ViewModels\ViewModels.csproj", "{805D142A-2755-4232-A486-2970277FB951}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -65,6 +69,14 @@ Global
{EE69586D-A6A8-40C4-93D7-DBDFEBC6844A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EE69586D-A6A8-40C4-93D7-DBDFEBC6844A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EE69586D-A6A8-40C4-93D7-DBDFEBC6844A}.Release|Any CPU.Build.0 = Release|Any CPU
{0C898A04-092A-49AA-BE65-8AE818A2AF50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0C898A04-092A-49AA-BE65-8AE818A2AF50}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0C898A04-092A-49AA-BE65-8AE818A2AF50}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0C898A04-092A-49AA-BE65-8AE818A2AF50}.Release|Any CPU.Build.0 = Release|Any CPU
{805D142A-2755-4232-A486-2970277FB951}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{805D142A-2755-4232-A486-2970277FB951}.Debug|Any CPU.Build.0 = Debug|Any CPU
{805D142A-2755-4232-A486-2970277FB951}.Release|Any CPU.ActiveCfg = Release|Any CPU
{805D142A-2755-4232-A486-2970277FB951}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

@ -83,6 +83,7 @@
<ProjectReference Include="..\Shared\Shared.csproj" />
<ProjectReference Include="..\StubLib\StubLib.csproj" />
<ProjectReference Include="..\ViewModels\ViewModels.csproj" />
<ProjectReference Include="..\DataManagers\DataManagers.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="CommunityToolkit.Maui" Version="5.0.0" />

@ -6,6 +6,7 @@ using Microsoft.Maui.Platform;
using Model;
using StubLib;
using ViewModels;
using DataManagers;
namespace LolApp;

@ -50,25 +50,25 @@ public class Champion : IEquatable<Champion>
public LargeImage Image { get; set; }
public Champion(int id, string name, ChampionClass champClass = ChampionClass.Unknown, string icon = "", string image = "", string bio = "")
public Champion(int id, string name, ChampionClass champClass = ChampionClass.Unknown, string icon = "", string image = "", int imageId=0,string bio = "")
{
Id = id;
Name = name;
Class = champClass;
Icon = icon;
Image = new LargeImage(image);
Image = new LargeImage(imageId, image);
Bio = bio;
Characteristics = new ReadOnlyDictionary<string, int>(characteristics);
Skins = new ReadOnlyCollection<Skin>(skins);
}
public Champion(string name, ChampionClass champClass = ChampionClass.Unknown, string icon = "", string image = "", string bio = "")
public Champion(string name, ChampionClass champClass = ChampionClass.Unknown, string icon = "", string image = "", int imageId = 0, string bio = "")
{
Id = 0;
Name = name;
Class = champClass;
Icon = icon;
Image = new LargeImage(image);
Image = new LargeImage(imageId, image);
Bio = bio;
Characteristics = new ReadOnlyDictionary<string, int>(characteristics);
Skins = new ReadOnlyCollection<Skin>(skins);

@ -5,13 +5,30 @@ namespace Model
{
public string Base64 { get; set; }
public LargeImage(string base64)
public int Id { get; set; }
public LargeImage(int id, string base64)
{
Base64 = base64;
Id = id;
}
public LargeImage(string base64)
{
Base64 = base64;
Id = 0;
}
public bool Equals(LargeImage? other)
=> other != null && other.Base64.Equals(Base64);
{
if (other == null) return false;
if (Id != 0 && other?.Id != 0)
{
return Id == Id;
}
return Base64 == other?.Base64;
}
public override bool Equals(object? obj)
{

@ -23,15 +23,15 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.2">
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.4">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.2">
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.4">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.4" />
</ItemGroup>
</Project>

@ -13,15 +13,15 @@
<None Remove="Microsoft.EntityFrameworkCore" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.2">
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.4">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.2">
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.4">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.4" />
</ItemGroup>
</Project>

@ -16,15 +16,15 @@
<None Remove="Microsoft.EntityFrameworkCore" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.2">
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.4">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.2">
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.4">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.4" />
</ItemGroup>
</Project>

@ -0,0 +1,49 @@
using System;
using ApiLol;
using ApiLol.Controllers;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using StubLib;
namespace Tests
{
public class ChampionController_UT
{
[Fact]
public async void GetChampionTest()
{
ChampionController controller = new ChampionController(new Logger<ChampionController>(new LoggerFactory()), new StubData());
}
[Fact]
public async void GetChampionByNameTest()
{
ChampionController controller = new ChampionController(new Logger<ChampionController>(new LoggerFactory()), new StubData());
var result = await controller.GetChampionsByName("aa");
var champs = (result.Result as ObjectResult).Value as IEnumerable<ChampionDTO>;
Assert.True(champs.Any());
}
[Fact]
public async void PostChampionTest()
{
ChampionController controller = new ChampionController(new Logger<ChampionController>(new LoggerFactory()), new StubData());
var result = await controller.PostChampion(new ChampionDTO { Name="Test", Bio="test", ChampClass=Model.ChampionClass.Assassin, Icon="sqdz"});
ChampionDTO? champ = (result.Result as ObjectResult).Value as ChampionDTO;
Assert.NotNull(champ);
}
[Fact]
public async void PutChampionTest()
{
ChampionController controller = new ChampionController(new Logger<ChampionController>(new LoggerFactory()), new StubData());
var result = await controller.Put(new ChampionDTO { Name = "Aatrox", Bio = "test", ChampClass = Model.ChampionClass.Assassin, Icon = "sqdz" }, new ChampionDTO { Name = "Test", Bio = "test", ChampClass = Model.ChampionClass.Assassin, Icon = "sqdz" });
var champ = (result.Result as ObjectResult).Value as ChampionDTO;
Assert.NotNull(champ);
var result2 = await controller.Put(new ChampionDTO { Name = "blabla", Bio = "test", ChampClass = Model.ChampionClass.Assassin, Icon = "sqdz" }, new ChampionDTO { Name = "Test", Bio = "test", ChampClass = Model.ChampionClass.Assassin, Icon = "sqdz" });
var champ2 = (result.Result as ObjectResult).Value as ChampionDTO;
Assert.Null(champ2);
}
}
}

@ -1,6 +1,7 @@
namespace Tests;
using System.Threading.Tasks;
using System.Xml.Linq;
using DataManagers;
using EFLib;
using Microsoft.Data.Sqlite;
@ -10,8 +11,11 @@ using Model;
public class DbChampionManager_UT
{
[Fact]
public async Task Add_TestAsync()
[Theory]
[InlineData(true, true, 8, "Aurelien", ChampionClass.Tank, "tro bo le type")]
[InlineData(true, false, 8, "Marche sans ID", ChampionClass.Tank, "tro bo le type")]
[InlineData(false, true, 8, "Marche pas", ChampionClass.Tank, "tro bo le type")]
public async Task Add_TestAsync(bool isValid, bool hasId,int id, string name, ChampionClass championClass, string bio)
{
var connection = new SqliteConnection("DataSource=:memory:");
connection.Open();
@ -23,28 +27,32 @@ public class DbChampionManager_UT
using (var db = new DbDataManager(new EFLib.LolContext(options)))
{
db.EnsureCreated();
Champion champion = new Champion("Aurelien", ChampionClass.Tank, "tro bo le type");
Champion champion2 = new Champion("Croissant", ChampionClass.Assassin, "tro bon le type");
Champion champion3 = new Champion("Mathilde", ChampionClass.Fighter, "Chut mathilde");
await db.ChampionsMgr.AddItem(champion);
await db.ChampionsMgr.AddItem(champion2);
await db.ChampionsMgr.AddItem(champion3);
}
using (var db = new DbDataManager(new EFLib.LolContext(options)))
{
db.EnsureCreated();
Assert.Equal(3, await db.ChampionsMgr.GetNbItems());
Assert.Null(await db.ChampionsMgr.AddItem(new Champion("Aurelien", ChampionClass.Tank, "tro bo le type")));
await db.EnsureCreatedAsync();
Champion champion = new Champion(name, championClass, bio);
if (hasId)
{
champion = new Champion(id, name, championClass, bio);
}
Champion? c = await db.ChampionsMgr.AddItem(champion);
if (isValid)
{
Assert.NotNull(c);
}
else
{
Champion? c1 = await db.ChampionsMgr.AddItem(champion);
Assert.Null(c1);
}
}
}
[Fact]
public async Task Delete_TestAsync()
[Theory]
[InlineData(true, true, 18, "Aurelien", ChampionClass.Tank, "tro bo le type")]
[InlineData(true, false, 19, "Marche sans Id", ChampionClass.Tank, "tro bo le type")]
[InlineData(false, true, 20, "Marche pas", ChampionClass.Tank, "tro bo le type")]
public async Task Delete_TestAsync(bool isValid, bool hasId, int id, string name, ChampionClass championClass, string bio)
{
var connection = new SqliteConnection("DataSource=:memory:");
connection.Open();
@ -55,32 +63,71 @@ public class DbChampionManager_UT
using (var db = new DbDataManager(new EFLib.LolContext(options)))
{
db.EnsureCreated();
Champion champion = new Champion("Aurelien", ChampionClass.Tank, "tro bo le type");
Champion champion2 = new Champion("Croissant", ChampionClass.Assassin, "tro bon le type");
Champion champion3 = new Champion("Mathilde", ChampionClass.Fighter, "Chut mathilde");
await db.ChampionsMgr.AddItem(champion);
await db.ChampionsMgr.AddItem(champion2);
await db.ChampionsMgr.AddItem(champion3);
await db.Context.Database.EnsureCreatedAsync();
Champion champion = new Champion(name, championClass, bio);
if (hasId)
{
champion = new Champion(id, name, championClass, bio);
}
if (isValid)
{
Champion? c = await db.ChampionsMgr.AddItem(champion);
var retour = await db.ChampionsMgr.DeleteItem(champion);
Assert.True(retour);
}
else
{
var retour = await db.ChampionsMgr.DeleteItem(champion);
Assert.False(retour);
}
}
}
using (var db = new DbDataManager(new EFLib.LolContext(options)))
{
db.EnsureCreated();
[Theory]
[InlineData(true, true, 18, "Aurelien", ChampionClass.Tank, "tro bo le type")]
[InlineData(true, false, 19, "Marche sans Id", ChampionClass.Tank, "tro bo le type")]
[InlineData(false, true, 20, "Marche pas", ChampionClass.Tank, "tro bo le type")]
public async Task Modify_TestAsync(bool isValid, bool hasId, int id, string name, ChampionClass championClass, string bio)
{
var connection = new SqliteConnection("DataSource=:memory:");
connection.Open();
string nameToFind = "Croissant";
IEnumerable<Champion> champ = await db.ChampionsMgr.GetItemsByName(nameToFind, 0, 15, "name");
Champion c = champ.First();
Assert.Equal("Croissant", c.Name);
await db.ChampionsMgr.DeleteItem(champ.First());
var options = new DbContextOptionsBuilder<LolContext>()
.UseSqlite(connection)
.Options;
Assert.Equal(2, await db.ChampionsMgr.GetNbItems());
using (var db = new DbDataManager(new EFLib.LolContext(options)))
{
await db.Context.Database.EnsureCreatedAsync();
Champion champion = new Champion(name, championClass, bio);
if (hasId)
{
champion = new Champion(id, name, championClass, bio);
}
if (isValid)
{
Champion? c = await db.ChampionsMgr.AddItem(champion);
var retour = await db.ChampionsMgr.UpdateItem(c, new Champion(champion.Id, champion.Name, bio: "blabla"));
Assert.Equal("blabla", retour.Bio);
}
else
{
var retour = await db.ChampionsMgr.UpdateItem(champion, new Champion(champion.Id, champion.Name, bio: "blabla"));
Assert.Null(retour);
}
}
}
[Fact]
public async Task Modify_TestAsync()
[Theory]
[InlineData("name", false)]
[InlineData("bio", false)]
[InlineData("class", false)]
[InlineData("name", true)]
[InlineData("bio", true)]
[InlineData("class", true)]
public async Task GetItems_TestAsync(string orderingProperty, bool reverse)
{
var connection = new SqliteConnection("DataSource=:memory:");
connection.Open();
@ -91,35 +138,27 @@ public class DbChampionManager_UT
using (var db = new DbDataManager(new EFLib.LolContext(options)))
{
db.EnsureCreated();
await db.Context.Database.EnsureCreatedAsync();
Champion champion = new Champion("test1", ChampionClass.Unknown, "test1");
Champion champion1 = new Champion("test2", ChampionClass.Assassin, "test2");
Champion champion2 = new Champion("test3", ChampionClass.Fighter, "test3");
Champion champion = new Champion("Aurelien", ChampionClass.Tank, "tro bo le type");
Champion champion2 = new Champion("Croissant", ChampionClass.Assassin, "tro bon le type");
Champion champion3 = new Champion("Mathilde", ChampionClass.Fighter, "Chut mathilde");
await db.ChampionsMgr.AddItem(champion);
await db.ChampionsMgr.AddItem(champion1);
await db.ChampionsMgr.AddItem(champion2);
await db.ChampionsMgr.AddItem(champion3);
}
using (var db = new DbDataManager(new EFLib.LolContext(options)))
{
db.EnsureCreated();
string nameToFind = "Croissant";
IEnumerable<Champion> champ = await db.ChampionsMgr.GetItemsByName(nameToFind, 0, 15, "name");
Champion c = champ.First();
Assert.Equal("Croissant", c.Name);
Champion c1 = new Champion("Test", c.Class, c.Icon, bio: c.Bio);
await db.ChampionsMgr.UpdateItem(c, c1);
Assert.Equal(3, await db.ChampionsMgr.GetNbItems());
champ = await db.ChampionsMgr.GetItemsByName("Test", 0, 15, "name");
var list = await db.ChampionsMgr.GetItems(0, 10, orderingProperty, reverse);
Assert.Equal("Test", champ.First().Name);
Assert.Equal(3, list.Count());
//if (reverse) Assert.Equal("test3", list.First().Name);
//else Assert.Equal("test1", list.First().Name);
}
}
[Fact]
public async Task GetItems_TestAsync()
public async Task getNbItems_TestASync()
{
var connection = new SqliteConnection("DataSource=:memory:");
connection.Open();
@ -130,32 +169,9 @@ public class DbChampionManager_UT
using (var db = new DbDataManager(new EFLib.LolContext(options)))
{
db.EnsureCreated();
Champion champion = new Champion("Aurelien", ChampionClass.Tank, "hey bo le type");
Champion champion2 = new Champion("Croissant", ChampionClass.Assassin, "Ztro bon le type");
Champion champion3 = new Champion("Mathilde", ChampionClass.Fighter, "ah mathilde");
await db.ChampionsMgr.AddItem(champion);
await db.ChampionsMgr.AddItem(champion2);
await db.ChampionsMgr.AddItem(champion3);
}
using (var db = new DbDataManager(new EFLib.LolContext(options)))
{
db.EnsureCreated();
var list = await db.ChampionsMgr.GetItems(0, 10, "bio", false);
Assert.Equal(3, list.Count());
list = await db.ChampionsMgr.GetItems(0, 3, "autre", true);
Assert.Equal("Aurelien", list.Last().Name);
list = await db.ChampionsMgr.GetItems(0, 3, "class", true);
Assert.Equal("Aurelien", list.First().Name);
list = await db.ChampionsMgr.GetItemsByClass(ChampionClass.Assassin, 0, 10);
Assert.Equal(1, list.Count());
Assert.Equal("Croissant", list.First().Name);
await db.Context.Database.EnsureCreatedAsync();
Assert.Equal(3, await db.ChampionsMgr.GetNbItems());
}
}
}

@ -9,28 +9,30 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.2">
<PackageReference Include="coverlet.collector" Version="3.2.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.3">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.4">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DataManagers\DataManagers.csproj" />
<ProjectReference Include="..\EFLib\EFLib.csproj" />
<ProjectReference Include="..\Model\Model.csproj" />
<ProjectReference Include="..\ApiLol\ApiLol.csproj" />
<ProjectReference Include="..\StubLib\StubLib.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,101 @@
using System;
using CommunityToolkit.Mvvm.ComponentModel;
using Model;
using Microsoft.Maui.Controls;
using System.Collections.ObjectModel;
namespace ViewModels
{
public partial class ChampionVM : ObservableObject
{
public Champion Model
{
get => model;
set
{
model = value;
OnPropertyChanged(nameof(Name));
OnPropertyChanged(nameof(Bio));
OnPropertyChanged(nameof(Class));
OnPropertyChanged(nameof(Icon));
OnPropertyChanged(nameof(Image));
OnPropertyChanged(nameof(Skills));
OnPropertyChanged(nameof(Characteristics));
}
}
private Champion model;
public ChampionVM(Champion model)
{
Model = model;
foreach(var skill in Model.Skills)
{
Skills.Add(new SkillVM(skill));
}
Skills.CollectionChanged += Skills_CollectionChanged;
}
private void Skills_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
SkillVM vm = e.NewItems?[0] as SkillVM;
switch(e.Action)
{
case System.Collections.Specialized.NotifyCollectionChangedAction.Add:
Model.Skills.Add(new Skill(vm.Name, vm.Type, vm.Description));
break;
case System.Collections.Specialized.NotifyCollectionChangedAction.Remove:
Model.Skills.Remove(vm.Model);
break;
}
}
public string Name => Model.Name;
public ChampionClass Class
{
get => Model.Class;
set => SetProperty(Model.Class, value, newValue => Model.Class = newValue);
}
public string Bio
{
get => Model.Bio;
set => SetProperty(Model.Bio, value, newBio => Model.Bio = newBio);
}
public string Icon
{
get => Model.Icon;
set
{
SetProperty(Model.Icon, value, newIcon =>
{
Model.Icon = newIcon;
});
}
}
public string Image
{
get => Model.Image.Base64;
set
{
SetProperty(Model.Image.Base64, value, newImage =>
{
Model.Image.Base64 = newImage;
});
}
}
[ObservableProperty]
private ObservableCollection<SkillVM> skills = new ObservableCollection<SkillVM>();
public ReadOnlyDictionary<string, int> Characteristics
=> Model.Characteristics;
[ObservableProperty]
private ObservableCollection<SkinVM> skins = new ObservableCollection<SkinVM>();
}
}

@ -0,0 +1,227 @@
using System.Threading.Tasks;
using Model;
using System.Windows.Input;
using CommunityToolkit.Mvvm.ComponentModel;
using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.Input;
using System.Data.SqlTypes;
using System.Reflection;
namespace ViewModels;
public partial class ChampionsMgrVM : ObservableObject
{
internal IDataManager DataMgr { get; set; }
public ChampionsMgrVM(IDataManager dataManager)
{
DataMgr = dataManager;
loadingMethods = new Dictionary<LoadingCriterium, Func<object, Task>>()
{
[LoadingCriterium.None] = async (o) => await LoadChampions(),
[LoadingCriterium.ByName] = async (o) =>
{
string substring = o as string;
if(substring == null) return;
await LoadChampionsByName(substring);
},
[LoadingCriterium.BySkill] = async (o) =>
{
string skillString = o as string;
if(skillString == null) return;
await LoadChampionsBySkill(skillString);
},
[LoadingCriterium.ByCharacteristic] = async (o) =>
{
string characString = o as string;
if(characString == null) return;
await LoadChampionsByCharacteristic(characString);
},
[LoadingCriterium.ByClass] = async (o) =>
{
if(!Enum.IsDefined(typeof(ChampionClass), o)) return;
ChampionClass champClass = (ChampionClass)o;
await LoadChampionsByClass(champClass);
},
};
}
private async Task LoadChampionsFunc(Func<Task<IEnumerable<Champion?>>> loader,
Func<Task<int>> nbReader,
LoadingCriterium criterium,
object parameter = null)
{
Champions.Clear();
var someChampions = (await loader()).Select(c => new ChampionVM(c)).ToList();
foreach (var cvm in someChampions)
{
Champions.Add(cvm);
}
NbChampions = await nbReader();
currentLoadingCriterium = criterium;
currentLoadingParameter = parameter;
}
[RelayCommand]
public async Task LoadChampions()
{
await LoadChampionsFunc(async () => await DataMgr.ChampionsMgr.GetItems(index, count, "Name"),
async () => await DataMgr.ChampionsMgr.GetNbItems(),
LoadingCriterium.None);
}
[RelayCommand(CanExecute =nameof(CanLoadChampionsByName))]
public async Task LoadChampionsByName(string substring)
{
await LoadChampionsFunc(async () => await DataMgr.ChampionsMgr.GetItemsByName(substring, index, count, "Name"),
async () => await DataMgr.ChampionsMgr.GetNbItemsByName(substring),
LoadingCriterium.ByName,
substring);
}
private bool CanLoadChampionsByName(string substring)
=> !string.IsNullOrWhiteSpace(substring);
[RelayCommand(CanExecute =nameof(CanLoadChampionsBySkill))]
public async Task LoadChampionsBySkill(string skill)
{
await LoadChampionsFunc(
async () => await DataMgr.ChampionsMgr.GetItemsBySkill(skill, index, count, "Name"),
async () => await DataMgr.ChampionsMgr.GetNbItemsBySkill(skill),
LoadingCriterium.BySkill,
skill);
}
private bool CanLoadChampionsBySkill(string substring) => !string.IsNullOrWhiteSpace(substring);
[RelayCommand(CanExecute = nameof(CanLoadChampionsByCharacteristic))]
public async Task LoadChampionsByCharacteristic(string characteristic)
{
await LoadChampionsFunc(
async () => await DataMgr.ChampionsMgr.GetItemsByCharacteristic(characteristic, index, count, "Name"),
async () => await DataMgr.ChampionsMgr.GetNbItemsByCharacteristic(characteristic),
LoadingCriterium.ByCharacteristic,
characteristic);
}
private bool CanLoadChampionsByCharacteristic(string characteristic)
=> !string.IsNullOrWhiteSpace(characteristic);
[RelayCommand]
public async Task LoadChampionsByClass(ChampionClass champClass)
{
if(champClass == ChampionClass.Unknown)
{
return;
}
await LoadChampionsFunc(
async () => await DataMgr.ChampionsMgr.GetItemsByClass(champClass, index, count, "Name"),
async () => await DataMgr.ChampionsMgr.GetNbItemsByClass(champClass),
LoadingCriterium.ByClass,
champClass);
}
[RelayCommand(CanExecute =nameof(CanDeleteChampion))]
public async Task<bool> DeleteChampion(object champVM)
{
ChampionVM cvm = champVM as ChampionVM;
if(cvm == null || !Champions.Contains(cvm)) return false;
bool result = await DataMgr.ChampionsMgr.DeleteItem(cvm.Model);
if(result)
{
Champions.Remove(cvm);
await LoadChampions();
}
return result;
}
bool CanDeleteChampion(object cvm)
=> cvm!= null && cvm is ChampionVM && Champions.Contains(cvm);
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(NextPageCommand))]
[NotifyCanExecuteChangedFor(nameof(PreviousPageCommand))]
private int index = 0;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(NbPages))]
[NotifyCanExecuteChangedFor(nameof(NextPageCommand))]
[NotifyCanExecuteChangedFor(nameof(PreviousPageCommand))]
private int count = 5;
public int NbPages
{
get
{
if(Count == 0 || NbChampions == 0)
{
return 0;
}
return (NbChampions-1) / Count + 1;
}
}
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(NbPages))]
[NotifyCanExecuteChangedFor(nameof(NextPageCommand))]
[NotifyCanExecuteChangedFor(nameof(PreviousPageCommand))]
private int nbChampions = 0;
[ObservableProperty]
private ObservableCollection<ChampionVM> champions = new ObservableCollection<ChampionVM>();
[RelayCommand(CanExecute =nameof(CanPreviousPage))]
async Task PreviousPage()
{
if(Index > 0)
{
Index--;
await loadingMethods[currentLoadingCriterium](currentLoadingParameter);
}
}
bool CanPreviousPage() => Index > 0;
[RelayCommand(CanExecute =nameof(CanNextPage))]
async Task NextPage()
{
if(Index < NbPages-1)
{
Index++;
await loadingMethods[currentLoadingCriterium](currentLoadingParameter);
}
}
bool CanNextPage() => Index < NbPages-1;
enum LoadingCriterium
{
None,
ByName,
BySkill,
ByCharacteristic,
ByClass
}
private LoadingCriterium currentLoadingCriterium = LoadingCriterium.None;
private object currentLoadingParameter = null;
private Dictionary<LoadingCriterium, Func<object, Task>> loadingMethods;
public async Task AddChampion(ChampionVM champVM)
{
var added = await DataMgr.ChampionsMgr.AddItem(champVM.Model);
if(added != null)
{
Champions.Add(champVM);
await LoadChampions();
}
}
public async Task EditChampion(ChampionVM oldChampion, ChampionVM newChampion)
{
var edited = await DataMgr.ChampionsMgr.UpdateItem(oldChampion.Model, newChampion.Model);
oldChampion.Model = newChampion.Model;
if(edited != null)
{
await LoadChampions();
}
}
}

@ -0,0 +1,73 @@
using System;
using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Model;
namespace ViewModels
{
[ObservableObject]
public partial class EditableChampionVM
{
public EditableChampionVM()
{ }
public EditableChampionVM(ChampionVM championVM)
{
Name = championVM.Name;
IconBase64 = championVM.Icon;
LargeImageBase64 = championVM.Image;
Bio = championVM.Bio;
ChampionClass = championVM.Class;
foreach(var ch in championVM.Characteristics)
{
AddCharacteristic(ch.Key, ch.Value);
}
foreach(var skill in championVM.Skills)
{
Skills.Add(skill);
}
}
[ObservableProperty]
string name;
[ObservableProperty]
string iconBase64;
[ObservableProperty]
string largeImageBase64;
[ObservableProperty]
string bio;
[ObservableProperty]
ChampionClass championClass;
[ObservableProperty]
ObservableCollection<KeyValuePair<string, int>> characteristics = new ();
public void AddCharacteristic(string description, int value)
=> Characteristics.Add(new KeyValuePair<string, int>(description, value));
public void RemoveCharacteristic(KeyValuePair<string, int> characteristic)
=> Characteristics.Remove(characteristic);
[ObservableProperty]
ObservableCollection<SkillVM> skills = new ObservableCollection<SkillVM>();
public ChampionVM ToChampionVM()
{
var champion = new Champion(name, championClass, iconBase64, largeImageBase64, bio);
champion.AddCharacteristics(characteristics.Select(kvp => Tuple.Create(kvp.Key, kvp.Value)).ToArray());
foreach(var skillVM in Skills)
{
champion.AddSkill(skillVM.Model);
}
return new ChampionVM(champion);
}
}
}

@ -0,0 +1,51 @@
using System;
using System.Reflection.PortableExecutable;
using System.Xml.Linq;
using CommunityToolkit.Mvvm.ComponentModel;
using Model;
namespace ViewModels
{
[ObservableObject]
public partial class EditableSkinVM
{
public EditableSkinVM(ChampionVM championVM)
{
champion = championVM.Model;
}
public EditableSkinVM(SkinVM skinVM)
{
Name = skinVM.Name;
IconBase64 = skinVM.Icon;
LargeImageBase64 = skinVM.Image;
Description = skinVM.Description;
Price = skinVM.Price;
champion = skinVM.Champion;
}
[ObservableProperty]
private string name;
[ObservableProperty]
private string iconBase64;
[ObservableProperty]
private string largeImageBase64;
[ObservableProperty]
private string description;
[ObservableProperty]
private float price;
private Champion champion;
public SkinVM ToSkinVM()
{
var skin = new Skin(name, champion, price, iconBase64, largeImageBase64, description);
return new SkinVM(skin);
}
}
}

@ -0,0 +1,32 @@
using System;
using CommunityToolkit.Mvvm.ComponentModel;
using Model;
namespace ViewModels
{
[ObservableObject]
public partial class SkillVM
{
[ObservableProperty]
private Skill model;
public SkillVM(Skill model)
{
Model = model;
}
public string Name => Model.Name;
public SkillType Type => Model.Type;
public string Description
{
get => Model.Description;
set
{
SetProperty(Model.Description, value, newValue => Model.Description = newValue);
}
}
}
}

@ -0,0 +1,65 @@
using System;
using System.Reflection.PortableExecutable;
using System.Security.Claims;
using CommunityToolkit.Mvvm.ComponentModel;
using Model;
namespace ViewModels
{
[ObservableObject]
public partial class SkinVM
{
public Skin Model
{
get => model;
set
{
model = value;
OnPropertyChanged(nameof(Name));
OnPropertyChanged(nameof(Description));
OnPropertyChanged(nameof(Price));
OnPropertyChanged(nameof(Icon));
OnPropertyChanged(nameof(Image));
}
}
private Skin model;
public SkinVM(Skin model)
=> Model = model;
public string Name => Model.Name;
public string Description
{
get => Model.Description;
set => SetProperty(Model.Description, value, newValue => Model.Description = newValue);
}
public float Price
{
get => Model.Price;
set => SetProperty(Model.Price, value, newValue => Model.Price = newValue);
}
public string Icon
{
get => Model.Icon;
set
{
SetProperty(Model.Icon, value, newIcon => Model.Icon = newIcon);
}
}
public string Image
{
get => Model.Image.Base64;
set
{
SetProperty(Model.Image.Base64, value, newImage => Model.Image.Base64 = newImage);
}
}
public Champion Champion => Model.Champion;
}
}

@ -0,0 +1,135 @@
using System;
using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Model;
namespace ViewModels
{
[ObservableObject]
public partial class SkinsMgrVM
{
internal IDataManager DataMgr { get; set; }
[ObservableProperty]
private ChampionVM champion;
public SkinsMgrVM(IDataManager dataManager)
{
DataMgr = dataManager;
}
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(NextPageCommand))]
[NotifyCanExecuteChangedFor(nameof(PreviousPageCommand))]
private int index = 0;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(NbPages))]
[NotifyCanExecuteChangedFor(nameof(NextPageCommand))]
[NotifyCanExecuteChangedFor(nameof(PreviousPageCommand))]
private int count = 5;
public int NbPages
{
get
{
if(Count == 0 || NbSkins == 0)
{
return 0;
}
return (NbSkins-1) / Count + 1;
}
}
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(NbPages))]
[NotifyCanExecuteChangedFor(nameof(NextPageCommand))]
[NotifyCanExecuteChangedFor(nameof(PreviousPageCommand))]
private int nbSkins = 0;
[ObservableProperty]
private ObservableCollection<SkinVM> skins = new ObservableCollection<SkinVM>();
[RelayCommand]
async Task LoadSkins()
{
Skins.Clear();
IEnumerable<Skin?> skins;
if(Champion != null)
{
skins = await DataMgr.SkinsMgr.GetItemsByChampion(Champion.Model, Index, Count,"Name");
}
else
{
skins = await DataMgr.SkinsMgr.GetItems(Index, Count, "Name");
}
foreach(var skin in skins)
{
if(skin != null)
Skins.Add(new SkinVM(skin));
}
}
[RelayCommand(CanExecute =nameof(CanPreviousPage))]
async Task PreviousPage()
{
if(Index > 0)
{
Index--;
await LoadSkins();
}
}
bool CanPreviousPage() => Index > 0;
[RelayCommand(CanExecute =nameof(CanNextPage))]
async Task NextPage()
{
if(Index < NbPages-1)
{
Index++;
await LoadSkins();
}
}
bool CanNextPage() => Index < NbPages-1;
[RelayCommand(CanExecute =nameof(CanDeleteSkin))]
public async Task<bool> DeleteSkin(object skinVM)
{
SkinVM svm = skinVM as SkinVM;
if(svm == null || !Skins.Contains(svm)) return false;
bool result = await DataMgr.SkinsMgr.DeleteItem(svm.Model);
if(result)
{
Skins.Remove(svm);
await LoadSkins();
}
return result;
}
bool CanDeleteSkin(object svm)
=> svm!= null && svm is SkinVM && Skins.Contains(svm);
public async Task AddSkin(SkinVM skinVM)
{
var added = await DataMgr.SkinsMgr.AddItem(skinVM.Model);
if(added != null)
{
Skins.Add(skinVM);
await LoadSkins();
}
}
public async Task EditSkin(SkinVM oldSkin, SkinVM newSkin)
{
var edited = await DataMgr.SkinsMgr.UpdateItem(oldSkin.Model, newSkin.Model);
oldSkin.Model = newSkin.Model;
if(edited != null)
{
await LoadSkins();
}
}
}
}

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<UseMaui>true</UseMaui>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Model\Model.csproj">
<ReferenceSourceTarget></ReferenceSourceTarget>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.1.0" />
</ItemGroup>
</Project>
Loading…
Cancel
Save