From a263050ab6c96595e3adcfafbc7bfcaca5567ab1 Mon Sep 17 00:00:00 2001 From: kekentin Date: Wed, 2 Apr 2025 14:56:47 +0200 Subject: [PATCH 1/2] fininalisation Route Quote --- WF_EF_Api/Contextlib/DbCharacterManager.cs | 7 +--- WF_EF_Api/Contextlib/DbImagesManager.cs | 2 +- WF_EF_Api/Contextlib/DbQuoteManager.cs | 39 ++++++++++++++++++- WF_EF_Api/Contextlib/DbSourceManager.cs | 14 +------ WF_EF_Api/ServicesApi/QuoteService.cs | 4 +- WF_EF_Api/ServicesApi/SourceService.cs | 8 ++-- WF_EF_Api/Shared/IQuoteService.cs | 2 +- WF_EF_Api/StubApi/QuoteServiceStub.cs | 3 +- .../WfApi/Controllers/QuotesController.cs | 2 +- WF_EF_Api/XUnitTest/ApiUnitTest.cs | 2 +- 10 files changed, 53 insertions(+), 30 deletions(-) diff --git a/WF_EF_Api/Contextlib/DbCharacterManager.cs b/WF_EF_Api/Contextlib/DbCharacterManager.cs index e81dc1d..7d01f7f 100644 --- a/WF_EF_Api/Contextlib/DbCharacterManager.cs +++ b/WF_EF_Api/Contextlib/DbCharacterManager.cs @@ -68,15 +68,10 @@ namespace Contextlib /// The name of the character to retrieve. /// A task that represents the asynchronous operation, with a as its result. /// Thrown when no character is found with the given name. - public async Task GetCharByName(string name) + public async Task GetCharByName(string name) { var character = _repo.GetItems(item => item.Name == name,0,1, [nameof(Character.Images)]).FirstOrDefault(); - if (character == null) - { - throw new KeyNotFoundException($"Error : No character found with the name: {name}."); - } - return character; } diff --git a/WF_EF_Api/Contextlib/DbImagesManager.cs b/WF_EF_Api/Contextlib/DbImagesManager.cs index 6afd953..e549cf9 100644 --- a/WF_EF_Api/Contextlib/DbImagesManager.cs +++ b/WF_EF_Api/Contextlib/DbImagesManager.cs @@ -33,7 +33,7 @@ namespace Contextlib return new PaginationResult(await CountImage(), 0, await CountImage(), _repository.GetItems(0, await CountImage()).ToList()); } - public async Task GetImageById(int id) + public async Task GetImageById(int id) { return _repository.GetById(id); } diff --git a/WF_EF_Api/Contextlib/DbQuoteManager.cs b/WF_EF_Api/Contextlib/DbQuoteManager.cs index 4287574..0a4236a 100644 --- a/WF_EF_Api/Contextlib/DbQuoteManager.cs +++ b/WF_EF_Api/Contextlib/DbQuoteManager.cs @@ -31,24 +31,37 @@ namespace Contextlib } - public async Task AddQuote(Quote quote) + public async Task AddQuote(Quote quote) { if (quote == null) { throw new ArgumentNullException(nameof(quote), "quote cannot be null."); } + //Character var c = await _dbC.GetCharByName(quote.Character.Name); if (c != null) { quote.IdCharacter = c.Id; quote.Character = c; } - //Image + var i = await _dbI.GetImageByPath(quote.Character.Images.ImgPath); + if (i != null) + { + quote.Character.IdImage = i.Id; + quote.Character.Images = i; + } //Source + var s = await _dbS.GetSourceByTitle(quote.Source.Title); + if (s != null) + { + quote.IdSource = s.Id; + quote.Source = s; + } _repo.Insert(quote); await _context.SaveChangesAsync(); + return quote; } public async Task> GetAllQuote() @@ -197,6 +210,28 @@ namespace Contextlib public async Task UpdateQuote(int quoteId, Quote quote) { + //Character + var c = await _dbC.GetCharByName(quote.Character.Name); + if (c != null) + { + quote.IdCharacter = c.Id; + quote.Character = c; + } + //Image + var i = await _dbI.GetImageByPath(quote.Character.Images.ImgPath); + if (c != null) + { + quote.Character.IdImage = i.Id; + quote.Character.Images = i; + } + //Source + var s = await _dbS.GetSourceByTitle(quote.Source.Title); + if (c != null) + { + quote.IdSource = s.Id; + quote.Source = s; + } + Quote? q = _repo.GetById(quoteId); if (q != null) { diff --git a/WF_EF_Api/Contextlib/DbSourceManager.cs b/WF_EF_Api/Contextlib/DbSourceManager.cs index 707a0bf..c40f04e 100644 --- a/WF_EF_Api/Contextlib/DbSourceManager.cs +++ b/WF_EF_Api/Contextlib/DbSourceManager.cs @@ -58,27 +58,17 @@ namespace Contextlib return source; } - public async Task GetSourceByTitle(string title) + public async Task GetSourceByTitle(string title) { var source = _repo.GetItems(item => item.Title == title, 0, 1, []).FirstOrDefault(); - if (source == null) - { - throw new KeyNotFoundException($"Error : No source found with the title: {title}."); - } - return source; } - public async Task GetSourceByType(int type) + public async Task GetSourceByType(int type) { var source = _repo.GetItems(item => item.TypeSrc == (TypeSrcEnum)type, 0, 1, []).FirstOrDefault(); - if (source == null) - { - throw new KeyNotFoundException($"Error : No source found with the type: {(TypeSrcEnum)type}."); - } - return source; } diff --git a/WF_EF_Api/ServicesApi/QuoteService.cs b/WF_EF_Api/ServicesApi/QuoteService.cs index cdf66a2..7538781 100644 --- a/WF_EF_Api/ServicesApi/QuoteService.cs +++ b/WF_EF_Api/ServicesApi/QuoteService.cs @@ -20,9 +20,9 @@ namespace ServicesApi quoteService = quote; } - public async Task AddQuote(QuoteDTO quote) + public async Task AddQuote(QuoteDTO quote) { - await quoteService.AddQuote(quote.ToEntity()); + return (await quoteService.AddQuote(quote.ToEntity())).ToDto(); } public async Task> GetAllQuote() diff --git a/WF_EF_Api/ServicesApi/SourceService.cs b/WF_EF_Api/ServicesApi/SourceService.cs index f767fdc..4a7c8fc 100644 --- a/WF_EF_Api/ServicesApi/SourceService.cs +++ b/WF_EF_Api/ServicesApi/SourceService.cs @@ -36,9 +36,11 @@ namespace ServicesApi return await srcService.GetLastSourceId(); } - public async Task GetSourceByDate(string date) + public async Task> GetSourceByDate(int date) { - return srcService.GetSourceByDate(date).Result.ToDto(); + var sources = ( await srcService.GetSourceByDate(date)).items; + return new PaginationResult(sources.Count(), 0, 10, sources.ToDto()); + } public async Task GetSourceById(int id) @@ -51,7 +53,7 @@ namespace ServicesApi return srcService.GetSourceByTitle(title).Result.ToDto(); } - public async Task GetSourceByType(string type) + public async Task GetSourceByType(int type) { return srcService.GetSourceByType(type).Result.ToDto(); } diff --git a/WF_EF_Api/Shared/IQuoteService.cs b/WF_EF_Api/Shared/IQuoteService.cs index c37fb5a..4632463 100644 --- a/WF_EF_Api/Shared/IQuoteService.cs +++ b/WF_EF_Api/Shared/IQuoteService.cs @@ -76,7 +76,7 @@ namespace Shared // Adds a new quote. // 'quote' is the quote object that will be added. - Task AddQuote(TQuote quote); + Task AddQuote(TQuote quote); // Updates an existing quote identified by 'quoteId' with new details. // 'quoteId' is the ID of the quote to be updated diff --git a/WF_EF_Api/StubApi/QuoteServiceStub.cs b/WF_EF_Api/StubApi/QuoteServiceStub.cs index f0521b3..f06a6e1 100644 --- a/WF_EF_Api/StubApi/QuoteServiceStub.cs +++ b/WF_EF_Api/StubApi/QuoteServiceStub.cs @@ -39,9 +39,10 @@ namespace StubApi }; } - public async Task AddQuote(QuoteDTO quote) + public async Task AddQuote(QuoteDTO quote) { _quotes.Add(quote); + return quote; } public async Task> GetAllQuote() diff --git a/WF_EF_Api/WfApi/Controllers/QuotesController.cs b/WF_EF_Api/WfApi/Controllers/QuotesController.cs index 1eda2f1..a43866b 100644 --- a/WF_EF_Api/WfApi/Controllers/QuotesController.cs +++ b/WF_EF_Api/WfApi/Controllers/QuotesController.cs @@ -272,7 +272,7 @@ namespace WfApi.Controllers return Conflict(new { message = "Une quote avec cet ID existe déjà." }); } newQuote.IsValide=false; - var quote=_quote.AddQuote(newQuote); + var quote=await _quote.AddQuote(newQuote); return CreatedAtAction(nameof(CreateQuote), new { id = newQuote.Id }, quote); } diff --git a/WF_EF_Api/XUnitTest/ApiUnitTest.cs b/WF_EF_Api/XUnitTest/ApiUnitTest.cs index 6ab3df3..7591909 100644 --- a/WF_EF_Api/XUnitTest/ApiUnitTest.cs +++ b/WF_EF_Api/XUnitTest/ApiUnitTest.cs @@ -268,7 +268,7 @@ namespace XUnitTest _mockUserService.Setup(service => service.GetUserById(id)).ReturnsAsync(existingPlayer); - _mockUserService.Setup(service => service.RemoveUser(existingPlayer)).Verifiable(); + _mockUserService.Setup(service => service.RemoveUser(existingPlayer.Id)).Verifiable(); // Act var result = await _userController.DeletePlayer(id); From ff3a1a0efa367c9ca0de4506d9fc70daca269ec4 Mon Sep 17 00:00:00 2001 From: kekentin Date: Wed, 2 Apr 2025 16:04:21 +0200 Subject: [PATCH 2/2] mise a jour route --- WF_EF_Api/Contextlib/DbSourceManager.cs | 2 +- WF_EF_Api/Shared/IFavoriteService.cs | 6 +- .../Migrations/StubWTFContextModelSnapshot.cs | 28 ++-- .../WfApi/Controllers/FavoriteControleur.cs | 125 ++++++++++++++++++ WF_EF_Api/WfApi/Program.cs | 4 +- 5 files changed, 148 insertions(+), 17 deletions(-) create mode 100644 WF_EF_Api/WfApi/Controllers/FavoriteControleur.cs diff --git a/WF_EF_Api/Contextlib/DbSourceManager.cs b/WF_EF_Api/Contextlib/DbSourceManager.cs index c40f04e..6f470f7 100644 --- a/WF_EF_Api/Contextlib/DbSourceManager.cs +++ b/WF_EF_Api/Contextlib/DbSourceManager.cs @@ -8,7 +8,7 @@ using Shared; namespace Contextlib { - internal class DbSourceManager : ISourceService + public class DbSourceManager : ISourceService { private WTFContext _context; private GenericRepository _repo; diff --git a/WF_EF_Api/Shared/IFavoriteService.cs b/WF_EF_Api/Shared/IFavoriteService.cs index 3b2de7f..08a32de 100644 --- a/WF_EF_Api/Shared/IFavoriteService.cs +++ b/WF_EF_Api/Shared/IFavoriteService.cs @@ -1,12 +1,13 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Text; using System.Threading.Tasks; namespace Shared { - public interface IFavoriteService + public interface IFavoriteService { // Adds a quote to a user's list of favorites. // 'quoteid' is the unique identifier of the quote to be added to favorites. @@ -25,5 +26,8 @@ namespace Shared // Removes a specific quote from the favorite lists of all users. // 'quoteId' is the unique identifier of the quote to be removed from all users' favorites. Task RemoveAllFavoriteForQuote(int quoteId); + + Task> GetFavoriteByIdUser(int userId, int index, int count); + Task GetFavorite(int userId, int idQuote); } } diff --git a/WF_EF_Api/StubbedContextLib/Migrations/StubWTFContextModelSnapshot.cs b/WF_EF_Api/StubbedContextLib/Migrations/StubWTFContextModelSnapshot.cs index 37b2e66..08ef8a9 100644 --- a/WF_EF_Api/StubbedContextLib/Migrations/StubWTFContextModelSnapshot.cs +++ b/WF_EF_Api/StubbedContextLib/Migrations/StubWTFContextModelSnapshot.cs @@ -127,11 +127,11 @@ namespace StubbedContextLib.Migrations modelBuilder.Entity("Entity.Commentary", b => { - b.Property("IdUser") + b.Property("Id") + .ValueGeneratedOnAdd() .HasColumnType("int"); - b.Property("IdQuote") - .HasColumnType("int"); + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); b.Property("Comment") .IsRequired() @@ -142,34 +142,36 @@ namespace StubbedContextLib.Migrations .HasColumnType("date") .HasColumnName("DateCommentary"); - b.Property("Id") - .ValueGeneratedOnAdd() + b.Property("IdQuote") .HasColumnType("int"); - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + b.Property("IdUser") + .HasColumnType("int"); - b.HasKey("IdUser", "IdQuote"); + b.HasKey("Id"); b.HasIndex("IdQuote"); + b.HasIndex("IdUser"); + b.ToTable("comments"); b.HasData( new { - IdUser = 2, - IdQuote = 1, + Id = 1, Comment = "Ce film est le meilleur", DateCommentary = new DateTime(2025, 2, 3, 0, 0, 0, 0, DateTimeKind.Unspecified), - Id = 1 + IdQuote = 1, + IdUser = 2 }, new { - IdUser = 3, - IdQuote = 1, + Id = 2, Comment = "Very good", DateCommentary = new DateTime(2025, 3, 11, 0, 0, 0, 0, DateTimeKind.Unspecified), - Id = 2 + IdQuote = 1, + IdUser = 3 }); }); diff --git a/WF_EF_Api/WfApi/Controllers/FavoriteControleur.cs b/WF_EF_Api/WfApi/Controllers/FavoriteControleur.cs new file mode 100644 index 0000000..2529717 --- /dev/null +++ b/WF_EF_Api/WfApi/Controllers/FavoriteControleur.cs @@ -0,0 +1,125 @@ +using System.Net; +using DTO; +using Entity; +using Microsoft.AspNetCore.Mvc; +using ServicesApi; +using Shared; + +namespace WfApi.Controllers +{ + [ApiController] + [Route("api/v1/favorite")] //Version API + public class FavoriteControleur : ControllerBase + { + private readonly IFavoriteService _favorite; + + private readonly ILogger _logger; + public FavoriteControleur(IFavoriteService favoriteService, ILogger logger) + { + _favorite = favoriteService; + _logger = logger; + } + + + + [HttpGet("{id}")] // Indiquer que l'id est dans l'URL + public async Task GetFavoriteByIdUser(int id, int index = 0, int count = 10) + { + try + { + var result = await _favorite.GetFavoriteByIdUser(id, index, count); + + if (result != null) + { + return await Task.FromResult(Ok(result)); + } + else + { + return NoContent(); + } + } + catch (Exception) + { + return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" }); + } + } + + [HttpPost] + [ProducesResponseType(StatusCodes.Status201Created)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status409Conflict)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task CreateFavorite(int idUser , int idQuote) + { + try + { + + var existingFavorite = _favorite.GetFavorite(idUser,idQuote).Result; + if (existingFavorite != null) + { + return Conflict(new { message = "A favorite with this ID already exists." }); + } + + await _favorite.AddFavorite(idUser, idQuote); + var fav = new Favorite(); + fav.IdQuote = idQuote; + fav.IdUsers = idUser; + return CreatedAtAction(nameof(GetFavoriteByIdUser), new { id = idUser }, fav); + } + catch (Exception) + { + return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Erreur interne du serveur." }); + } + } + + + [HttpDelete] // /api/v1/commentary?id=51 + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task DeleteFavorite([FromQuery] int idUser, [FromQuery] int idQuote) + { + try + { + + var existingFavorite = await _favorite.GetFavorite(idUser, idQuote); + if (existingFavorite == null) + { + return NotFound(new { message = "Commentary not found." }); + } + + await _favorite.RemoveFavorite(idUser, idQuote); + + return Ok(new { message = $"Favorite from user {idUser} and quote {idQuote} deleted successfully." }); + } + catch (Exception) + { + return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal server error." }); + } + } + [HttpDelete] // /api/v1/commentary?id=51 + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task DeleteFavorite([FromQuery] int idUser, [FromQuery] int idQuote) + { + try + { + + var existingFavorite = await _favorite.GetFavorite(idUser, idQuote); + if (existingFavorite == null) + { + return NotFound(new { message = "Commentary not found." }); + } + + await _favorite.RemoveFavorite(idUser, idQuote); + + return Ok(new { message = $"Favorite from user {idUser} and quote {idQuote} deleted successfully." }); + } + catch (Exception) + { + return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal server error." }); + } + } + } +} diff --git a/WF_EF_Api/WfApi/Program.cs b/WF_EF_Api/WfApi/Program.cs index f4dd552..6d308be 100644 --- a/WF_EF_Api/WfApi/Program.cs +++ b/WF_EF_Api/WfApi/Program.cs @@ -15,7 +15,7 @@ builder.Services.AddScoped, QuoteService>(); builder.Services.AddScoped, CommentaryService>(); builder.Services.AddScoped, CharacterService>(); builder.Services.AddScoped, ImageService>(); -//builder.Services.AddScoped, SourceService>(); +builder.Services.AddScoped, SourceService>(); builder.Services.AddScoped, QuestionService>(); @@ -28,7 +28,7 @@ builder.Services.AddScoped, DbQuoteManager>(); builder.Services.AddScoped, DbCommentaryManager>(); builder.Services.AddScoped, DbCharacterManager>(); builder.Services.AddScoped, DbImagesManager>(); -//builder.Services.AddScoped, DbSourceManager>(); +builder.Services.AddScoped, DbSourceManager>(); builder.Services.AddScoped, DbQuestionManager>(); //...