ajout des 2 derniers contrôlers (⚠️ ne marche pas (erreur : Unable to resolve service for type 'Microsoft.Extensions.Logging.Logger [WebApi.Controllers.AdministratorController]' while attempting to activate 'WebApi.Controllers.FrontController'.))
continuous-integration/drone/push Build is passing Details

API
Damien NORTIER 1 year ago
parent 90cb29b943
commit f7a8ace007

@ -91,5 +91,10 @@ namespace DataManagers
{
return (await manager.removePlayer(id))?.ToModel();
}
public async Task<Player?> updatePlayer(int id, Player player)
{
return (await manager.updatePlayer(id, player.ToEntity()))?.ToModel();
}
}
}

@ -54,35 +54,22 @@ namespace DataManagers
return await Task.FromResult<Question?>((await manager.getQuestion(id))?.ToModel());
}
public async Task<Question?> getQuestion(string content)
{
return (await manager.getQuestion(content))?.ToModel();
}
public async Task<(int nbPages, IEnumerable<Question>? questions)> getQuestions(int nb, int count, QuestionOrderCriteria orderCriteria = QuestionOrderCriteria.ById)
{
List<Question>? tmp = new List<Question>();
var res = await manager.getQuestions(nb, count, orderCriteria);
if (res.questions == null) tmp = null;
else
{
foreach (var item in res.questions)
{
tmp.Add(item.ToModel());
}
}
return await Task.FromResult<(int nbPages, IEnumerable<Question>? questions)>((res.nbPages, tmp));
return (res.nbPages, res.questions?.Select(q => q.ToModel()));
}
public async Task<(int nbPages, IEnumerable<Question>? questions)?> getQuestionsByChapterAndDifficulty(int idChapter, int difficulty, int nb, int count, QuestionOrderCriteria orderCriteria = QuestionOrderCriteria.ById)
{
List<Question>? tmp = new List<Question>();
var res = await manager.getQuestionsByChapterAndDifficulty(idChapter, difficulty, nb, count, orderCriteria);
if (res == null) return await Task.FromResult<(int nbPages, IEnumerable<Question>? questions)?>(null);
if (res.Value.questions == null) tmp = null;
else
{
foreach (var item in res.Value.questions)
{
tmp.Add(item.ToModel());
}
}
return await Task.FromResult<(int nbPages, IEnumerable<Question>? questions)>((res.Value.nbPages, tmp));
if (res == null) return null;
return (res?.nbPages ?? getNbQuestions()/count, res?.questions?.Select(q => q.ToModel()));
}
public async Task<Question?> removeQuestion(Question question)

@ -99,5 +99,16 @@ namespace EntityManagers
await dbContext.SaveChangesAsync();
return await Task.FromResult<PlayerEntity?>(tmp);
}
public async Task<PlayerEntity?> updatePlayer(int id, PlayerEntity player)
{
if (dbContext.Players.Where(p => p.Nickname == player.Nickname).Count() > 0) return null;
var tmp = await getPlayer(id);
if (tmp == null) return null;
tmp.Nickname = player.Nickname;
tmp.HashedPassword = player.HashedPassword;
await dbContext.SaveChangesAsync();
return tmp;
}
}
}

@ -14,6 +14,8 @@ namespace EntityManagers
{
public class QuestionEntityManager(MyDbContext dbContext) : IQuestionManager<QuestionEntity>
{
private const int secondDifficultyBorn = 50;
private const int thirdDifficultyBorn = 150;
private MyDbContext dbContext = dbContext;
private IQueryable<QuestionEntity> trier(IQueryable<QuestionEntity> query, QuestionOrderCriteria orderCriteria)
@ -36,14 +38,14 @@ namespace EntityManagers
public async Task<QuestionEntity> addQuestion(QuestionEntity question)
{
var tmp = await dbContext.Questions.Where(q => q.Equals(question)).FirstOrDefaultAsync();
var tmp = await getQuestion(question.Content);
if (tmp != null) // <=> he already exist
{
return tmp!;
}
dbContext.Questions.Add(question);
await dbContext.SaveChangesAsync();
return await dbContext.Questions.Where(q => q.Equals(question)).FirstAsync();
return await dbContext.Questions.SingleAsync(q => q.Content == question.Content);
}
public async Task<IEnumerable<QuestionEntity>> addQuestions(IEnumerable<QuestionEntity> questions)
@ -76,29 +78,29 @@ namespace EntityManagers
public async Task<(int nbPages, IEnumerable<QuestionEntity>? questions)?> getQuestionsByChapterAndDifficulty(int idChapter, int difficulty, int nb, int count, QuestionOrderCriteria orderCriteria = QuestionOrderCriteria.ById)
{
if (nb < 0 || count < 0 || difficulty < 1 || difficulty > 3 || !dbContext.Chapters.Where(c => c.Id == idChapter).AnyAsync().Result)
if (nb < 0 || count < 0 || difficulty < 1 || difficulty > 3 || !(await dbContext.Chapters.Where(c => c.Id == idChapter).AnyAsync()))
return await Task.FromResult<(int nbPages, IEnumerable<QuestionEntity>? questions)?>(null);
int nbEl = getNbQuestions();
if (nb > nbEl / count) return await Task.FromResult<(int nbPages, IEnumerable<QuestionEntity>? questions)?>((nbEl / count, null));
var tmp = trier(dbContext.Questions, orderCriteria);
var tmp = trier(dbContext.Questions.Where(q => q.IdChapter == idChapter && q.Difficulty == difficulty), orderCriteria);
return await Task.FromResult<(int nbPages, IEnumerable<QuestionEntity>? questions)?>((nbEl / count, tmp.Skip((nb - 1) * count).Take(count)));
}
public async Task<QuestionEntity?> removeQuestion(QuestionEntity question)
{
var tmp = await dbContext.Questions.Where(q => q.Equals(question)).FirstOrDefaultAsync();
var tmp = await getQuestion(question.Content);
if (tmp == null) return tmp;
dbContext.Questions.Remove(tmp);
await dbContext.SaveChangesAsync();
return tmp;
}
public Task<QuestionEntity?> removeQuestion(int id)
public async Task<QuestionEntity?> removeQuestion(int id)
{
var tmp = getQuestion(id);
if (tmp.Result == null) return tmp;
dbContext.Questions.Remove(tmp.Result);
dbContext.SaveChangesAsync();
var tmp = await getQuestion(id);
if (tmp == null) return tmp;
dbContext.Questions.Remove(tmp);
await dbContext.SaveChangesAsync();
return tmp;
}
@ -121,10 +123,15 @@ namespace EntityManagers
if (tmp.Result == null) return await tmp;
tmp.Result.NbFalls++;
int nbFalls = tmp.Result.NbFalls;
if (nbFalls == 50) tmp.Result.Difficulty = 2;
if (nbFalls == 150) tmp.Result.Difficulty = 3;
if (nbFalls == secondDifficultyBorn) tmp.Result.Difficulty = 2;
if (nbFalls == thirdDifficultyBorn) tmp.Result.Difficulty = 3;
await dbContext.SaveChangesAsync();
return await tmp;
}
public async Task<QuestionEntity?> getQuestion(string content)
{
return await dbContext.Questions.SingleOrDefaultAsync(q => q.Content == content);
}
}
}

@ -115,5 +115,18 @@ namespace ManagerInterfaces
/// or null if the player does not exist
/// </returns>
public Task<int?> getMaxScorePlayer(int id);
/// <summary>
/// update a player
/// </summary>
/// <param name="id">the id of the player to update</param>
/// <param name="player">a player class which contains all properties to changes</param>
/// <returns>
/// the player changed or null
/// if the id doesn't exist or
/// if the player nickname is
/// already used
/// </returns>
public Task<T?> updatePlayer(int id, T player);
}
}

@ -69,6 +69,15 @@ namespace ManagerInterfaces
/// </returns>
public Task<T?> getQuestion(int id);
/// <summary>
/// get a question with a content
/// </summary>
/// <param name="content">the content of the question</param>
/// <returns>
/// the question that corresponde
/// to the content or null if there isn't any
/// </returns>
public Task<T?> getQuestion(string content);
/// <summary>
/// modified a question with an id
/// </summary>
/// <param name="id">the id of the question</param>

@ -86,5 +86,10 @@ namespace ServiceManagers
{
return (await manager.removePlayer(id))?.ToDto();
}
public async Task<PlayerDto?> updatePlayer(int id, PlayerDto player)
{
return (await manager.updatePlayer(id, player.ToModel()))?.ToDto();
}
}
}

@ -51,35 +51,22 @@ namespace ServiceManagers
return await Task.FromResult<QuestionDto?>((await manager.getQuestion(id))?.ToDto());
}
public async Task<QuestionDto?> getQuestion(string content)
{
return (await manager.getQuestion(content))?.ToDto();
}
public async Task<(int nbPages, IEnumerable<QuestionDto>? questions)> getQuestions(int nb, int count, QuestionOrderCriteria orderCriteria = QuestionOrderCriteria.ById)
{
List<QuestionDto>? tmp = new List<QuestionDto>();
var res = await manager.getQuestions(nb, count, orderCriteria);
if (res.questions == null) tmp = null;
else
{
foreach (var item in res.questions)
{
tmp.Add(item.ToDto());
}
}
return await Task.FromResult<(int nbPages, IEnumerable<QuestionDto>? questions)>((res.nbPages, tmp));
return (res.nbPages, res.questions?.Select(q => q.ToDto()));
}
public async Task<(int nbPages, IEnumerable<QuestionDto>? questions)?> getQuestionsByChapterAndDifficulty(int idChapter, int difficulty, int nb, int count, QuestionOrderCriteria orderCriteria = QuestionOrderCriteria.ById)
{
List<QuestionDto>? tmp = new List<QuestionDto>();
var res = await manager.getQuestionsByChapterAndDifficulty(idChapter, difficulty, nb, count, orderCriteria);
if (res == null) return await Task.FromResult<(int nbPages, IEnumerable<QuestionDto>? questions)?>(null);
if (res.Value.questions == null) tmp = null;
else
{
foreach (var item in res.Value.questions)
{
tmp.Add(item.ToDto());
}
}
return await Task.FromResult<(int nbPages, IEnumerable<QuestionDto>? questions)>((res.Value.nbPages, tmp));
if (res == null) return null;
return (res?.nbPages ?? getNbQuestions() / count, res?.questions?.Select(q => q.ToDto()));
}
public async Task<QuestionDto?> removeQuestion(QuestionDto question)

@ -2,15 +2,22 @@
using DbConnectionLibrairie;
using DTOs;
using EntityManagers;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using OrderCriterias;
using ServiceManagers;
using RouteAttribute = Microsoft.AspNetCore.Mvc.RouteAttribute;
namespace WebApi.Controllers
{
[ApiVersion("1.0")]
[Route("api/v{version:apiversion}")]
public class FrontController
{
[Inject]
public MyDbContext dbContext { get; set; }
// all secondary controllers
private AdministratorController administratorController;
private ChapterController chapterController;
@ -19,7 +26,6 @@ namespace WebApi.Controllers
private QuestionController questionController;
public FrontController(
MyDbContext dbContext,
Logger<AdministratorController> logAdmin,
Logger<ChapterController> logChapter,
Logger<LobbyController> logLobby,
@ -38,8 +44,8 @@ namespace WebApi.Controllers
administratorController = new AdministratorController(unity, logAdmin);
chapterController = new ChapterController(unity, logChapter);
lobbyController = new LobbyController(unity, logLobby);
//playerController = new PlayerController(unity, logPlayer);
//questionController = new QuestionController(unity, logQuestion);
playerController = new PlayerController(unity, logPlayer);
questionController = new QuestionController(unity, logQuestion);
}
/// <summary>
@ -357,5 +363,234 @@ namespace WebApi.Controllers
public async Task<IActionResult> GetLobby(int id)
=> await lobbyController.GetLobby(id);
/// <summary>
/// add a player
/// </summary>
/// <param name="player">the player to add</param>
/// <returns>
/// status code :
/// 200 if the player is added
/// 202 if the player is added
/// 208 if the player was already in the database
/// 500 if there was an internal error that doesn't allow to continue
/// return content :
/// no content when status code = 200
/// player added when status code = 202
/// player already in the database that equals the one we wanted to add when status code = 208
/// no content when status code = 500
/// </returns>
[HttpPost("add/player")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status202Accepted)]
[ProducesResponseType(StatusCodes.Status208AlreadyReported)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> PostPlayer([FromBody] PlayerDto player)
=> await playerController.PostPlayer(player);
/// <summary>
/// get a part of all players
/// </summary>
/// <param name="page">the actual page</param>
/// <param name="count">number of T element in a page</param>
/// <param name="orderCriteria">the order criteria</param>
/// <returns>
/// status code :
/// 200 if we got a set
/// 204 if we got an empty set
/// 400 if we got nothing
///
/// return content :
/// a tuple of the number of page and
/// all players in the database for
/// the page nb if status code = 200
/// the number of page for count element if status code = 204
/// nothing if status code = 400
/// </returns>
[HttpGet("all/players")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetSomePlayers([FromQuery] int page, int count = 10, PlayerOrderCriteria orderCriteria = PlayerOrderCriteria.ById)
=> await playerController.GetSomePlayers(page, count, orderCriteria);
/// <summary>
/// delete a player
/// </summary>
/// <param name="id">the id of the player to delete</param>
/// <returns>
/// <returns>
/// status code :
/// 200 if the player is removed
/// 204 if the player is removed
/// 400 if the id is incorrect
/// 500 if there was an internal error that doesn't allow to continue
/// return content :
/// aministrator deleted when status code = 200
/// no content when status code = 204
/// no content when status code = 400
/// no content when status code = 500
/// </returns>
[HttpDelete("delete/player")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> DeletePlayer(int id)
=> await playerController.DeletePlayer(id);
/// <summary>
/// get a player
/// </summary>
/// <param name="id">the id of the player</param>
/// <returns>
/// status code :
/// 200 when we got a player
/// 204 when we got null
///
/// return content :
/// the player that correspond to the id when status code = 200
/// nothing when status code = 204
/// </returns>
[HttpGet("player")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> GetPlayer(int id)
=> await playerController.GetPlayer(id);
/// <summary>
/// update a player
/// </summary>
/// <param name="id">the id of the player</param>
/// <returns>
/// status code :
/// 200 when we got a player
/// 204 when we got null
/// 208 when the nickname is already used
/// return content :
/// the player that correspond to the id when status code = 200
/// nothing when status code = 204
/// the player which have this nickname when status code = 208
/// </returns>
[HttpPut("update/player")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status208AlreadyReported)]
public async Task<IActionResult> PutPlayer([FromQuery] int id, [FromBody] PlayerDto player)
=> await playerController.PutPlayer(id, player);
/// <summary>
/// add a question
/// </summary>
/// <param name="question">the question to add</param>
/// <returns>
/// status code :
/// 200 if the question is added
/// 202 if the question is added
/// 208 if the question was already in the database
/// 500 if there was an internal error that doesn't allow to continue
/// return content :
/// no content when status code = 200
/// question added when status code = 202
/// question already in the database that equals the one we wanted to add when status code = 208
/// no content when status code = 500
/// </returns>
[HttpPost("add/question")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status202Accepted)]
[ProducesResponseType(StatusCodes.Status208AlreadyReported)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> PostQuestion([FromBody] QuestionDto question)
=> await questionController.PostQuestion(question);
/// <summary>
/// get a part of all questions
/// </summary>
/// <param name="page">the actual page</param>
/// <param name="count">number of T element in a page</param>
/// <param name="orderCriteria">the order criteria</param>
/// <returns>
/// status code :
/// 200 if we got a set
/// 204 if we got an empty set
/// 400 if we got nothing
///
/// return content :
/// a tuple of the number of page and
/// all questions in the database for
/// the page nb if status code = 200
/// the number of page for count element if status code = 204
/// nothing if status code = 400
/// </returns>
[HttpGet("questions/all")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> GetSomeQuestions([FromQuery] int page, int count = 10, QuestionOrderCriteria orderCriteria = QuestionOrderCriteria.ById)
=> await questionController.GetSomeQuestions(page, count, orderCriteria);
/// <summary>
/// delete a question
/// </summary>
/// <param name="id">the id of the question to delete</param>
/// <returns>
/// status code :
/// 200 if the question is removed
/// 204 if the question is removed
/// 400 if the id is incorrect
/// 500 if there was an internal error that doesn't allow to continue
/// return content :
/// aministrator deleted when status code = 200
/// no content when status code = 204
/// no content when status code = 400
/// no content when status code = 500
/// </returns>
[HttpDelete("delete/question")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> DeleteQuestion([FromQuery] int id)
=> await questionController.DeleteQuestion(id);
/// <summary>
/// get a question
/// </summary>
/// <param name="id">the id of the question</param>
/// <returns>
/// status code :
/// 200 when we got a question
/// 204 when we got null
///
/// return content :
/// the question that correspond to the id when status code = 200
/// nothing when status code = 204
/// </returns>
[HttpGet("question")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> GetQuestion([FromQuery] int id)
=> await questionController.GetQuestion(id);
/// <summary>
/// update a question
/// </summary>
/// <param name="id">the id of the question</param>
/// <returns>
/// status code :
/// 200 when we got a question
/// 204 when we got null
/// 208 when the nickname is already used
/// return content :
/// the question that correspond to the id when status code = 200
/// nothing when status code = 204
/// the question which have this nickname when status code = 208
/// </returns>
[HttpPut]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status208AlreadyReported)]
public async Task<IActionResult> PutQuestion(int id, QuestionDto question)
=> await questionController.PutQuestion(id, question);
}
}

@ -1,6 +1,247 @@
namespace WebApi.Controllers
using DTOs;
using Microsoft.AspNetCore.Mvc;
using OrderCriterias;
namespace WebApi.Controllers
{
public class PlayerController
public class PlayerController : ControllerBase
{
private Unit unity;
private readonly Logger<PlayerController> logger;
public PlayerController(Unit unit, Logger<PlayerController> logger)
{
this.unity = unit;
this.logger = logger;
}
/// <summary>
/// add a player
/// </summary>
/// <param name="player">the player to add</param>
/// <returns>
/// status code :
/// 200 if the player is added
/// 202 if the player is added
/// 208 if the player was already in the database
/// 500 if there was an internal error that doesn't allow to continue
/// return content :
/// no content when status code = 200
/// player added when status code = 202
/// player already in the database that equals the one we wanted to add when status code = 208
/// no content when status code = 500
/// </returns>
public async Task<IActionResult> PostPlayer(PlayerDto player)
{
int count = unity.getNbPlayers(); // count : number of elements before opperation
var tmp = await unity.addPlayer(player); // tmp : player recieve by the addPlayer method
if (unity.getNbPlayers() == count) // <=> not added
{
if (tmp.Nickname == player.Nickname)
{
// it was already in the database
logger.LogInformation(message: $"want to add a player already in the database : {tmp.ToString()}");
return StatusCode(208, tmp);
}
else
{
// we recieve a player already in the database
// that should be equal to the player that we
// wanted to add but it isn't
logger.LogCritical(message: "controller's add fail (already in the database) but\nplayer" +
$" recieve isn't the same as the one we wanted to add.\n" +
$"Player recieve : {tmp.ToString()}\nplayer to add : {player.ToString()}");
return StatusCode(500);
}
}
// added
if (tmp.Nickname == player.Nickname)
{
logger.LogTrace(message: $"player added : {tmp.ToString()}");
// the player has been added and we recieved him
return StatusCode(202, tmp);
}
else
{
// the player may be added but we do not recieved him
try
{
if (unity.getPlayer(player.Nickname) != null)
{
// he is added
logger.LogError(message: $"player added but not recieved");
return Ok(); // not 202 to make a difference between 2 cases
}
else
{
// he is not added
logger.LogCritical(message: "player that we wanted to add not added\nand we have added another one");
if (unity.getPlayer(player.Nickname) == null) // <=> not added
return StatusCode(500);
}
}
catch (Exception)
{
return StatusCode(500);
}
}
logger.LogError(message: "this case should not append");
return StatusCode(500);
}
/// <summary>
/// get a part of all players
/// </summary>
/// <param name="page">the actual page</param>
/// <param name="count">number of T element in a page</param>
/// <param name="orderCriteria">the order criteria</param>
/// <returns>
/// status code :
/// 200 if we got a set
/// 204 if we got an empty set
/// 400 if we got nothing
///
/// return content :
/// a tuple of the number of page and
/// all players in the database for
/// the page nb if status code = 200
/// the number of page for count element if status code = 204
/// nothing if status code = 400
/// </returns>
public async Task<IActionResult> GetSomePlayers(int page, int count = 10, PlayerOrderCriteria orderCriteria = PlayerOrderCriteria.ById)
{
var tmp = await unity.getPlayers(page, count, orderCriteria);
if (tmp.players == null)
{
logger.LogInformation(message: "get player : bad request (page or/and count incorrect)");
return BadRequest(tmp.nbPages);
}
else if (tmp.players.Count() == 0)
{
logger.LogWarning(message: $"get player : no content. number of element : {unity.getNbPlayers()}, page wanted : {page}, number of elements in a page : {count}");
return NoContent();
}
else
{
logger.LogTrace(message: $"get players : page = {page}, count = {count}, order criteria = {orderCriteria switch
{
PlayerOrderCriteria.ById => "byId",
PlayerOrderCriteria.ByNickname => "byNickname",
_ => "none"
}}");
return Ok(tmp);
}
}
/// <summary>
/// delete a player
/// </summary>
/// <param name="id">the id of the player to delete</param>
/// <returns>
/// <returns>
/// status code :
/// 200 if the player is removed
/// 204 if the player is removed
/// 400 if the id is incorrect
/// 500 if there was an internal error that doesn't allow to continue
/// return content :
/// aministrator deleted when status code = 200
/// no content when status code = 204
/// no content when status code = 400
/// no content when status code = 500
/// </returns>
public async Task<IActionResult> DeletePlayer(int id)
{
if (id < 0)
{
logger.LogError("want to delete a player with an id less than 0");
return BadRequest();
}
int count = unity.getNbPlayers(); // count : number of elements before opperation
var tmp = await unity.removePlayer(id);
if (tmp == null) // we don't recieve the player
{
if (unity.getNbPlayers() == count) // he is not deleted
{
if (unity.getPlayer(id) != null)
{
logger.LogCritical(message: "remove player fail : player not removed and not recieved");
return StatusCode(500);
}
else
{
logger.LogInformation(message: "trying to remove a player with an id who don't exist");
return BadRequest();
}
}
else // he may be deleted
{
if (unity.getPlayer(id) == null) // he must be deleted
{
logger.LogError(message: "player removed but not returned");
return NoContent();
}
else // he is not deleted
{
logger.LogCritical(message: "remove player fail : player to remove not remove\ninstead, anotherone is deleted and we recieved nothing");
return StatusCode(500);
}
}
}
if (unity.getNbPlayers() == count)
{
// <=> we have recieved a player which should be deleted
// but since we have the same number of player than
// before deletion, it isn't deleted
logger.LogCritical(message: $"player \"{tmp.ToString()}\"should be delete but it isn't");
return StatusCode(500);
}
logger.LogTrace(message: $"player removed {tmp.ToString()}");
return Ok(tmp);
}
/// <summary>
/// get a player
/// </summary>
/// <param name="id">the id of the player</param>
/// <returns>
/// status code :
/// 200 when we got a player
/// 204 when we got null
///
/// return content :
/// the player that correspond to the id when status code = 200
/// nothing when status code = 204
/// </returns>
public async Task<IActionResult> GetPlayer(int id)
{
var tmp = await unity.getPlayer(id);
if (tmp == null) return NoContent();
return Ok(tmp);
}
/// <summary>
/// update a player
/// </summary>
/// <param name="id">the id of the player</param>
/// <returns>
/// status code :
/// 200 when we got a player
/// 204 when we got null
/// 208 when the nickname is already used
/// return content :
/// the player that correspond to the id when status code = 200
/// nothing when status code = 204
/// the player which have this nickname when status code = 208
/// </returns>
public async Task<IActionResult> PutPlayer(int id, PlayerDto player)
{
var tmp = await unity.getPlayer(player.Nickname);
if (tmp != null) return StatusCode(208);
tmp = await unity.updatePlayer(id, player);
if (tmp == null) return NoContent();
return Ok(tmp);
}
}
}

@ -1,6 +1,249 @@
namespace WebApi.Controllers
using DTOs;
using Microsoft.AspNetCore.Mvc;
using OrderCriterias;
namespace WebApi.Controllers
{
public class QuestionController
public class QuestionController : ControllerBase
{
private Unit unity;
private readonly Logger<QuestionController> logger;
public QuestionController(Unit unit, Logger<QuestionController> logger)
{
this.unity = unit;
this.logger = logger;
}
/// <summary>
/// add a question
/// </summary>
/// <param name="question">the question to add</param>
/// <returns>
/// status code :
/// 200 if the question is added
/// 202 if the question is added
/// 208 if the question was already in the database
/// 500 if there was an internal error that doesn't allow to continue
/// return content :
/// no content when status code = 200
/// question added when status code = 202
/// question already in the database that equals the one we wanted to add when status code = 208
/// no content when status code = 500
/// </returns>
public async Task<IActionResult> PostQuestion(QuestionDto question)
{
int count = unity.getNbQuestions(); // count : number of elements before opperation
var tmp = await unity.addQuestion(question); // tmp : question recieve by the addQuestion method
if (unity.getNbQuestions() == count) // <=> not added
{
if (tmp.Content == question.Content)
{
// it was already in the database
logger.LogInformation(message: $"want to add a question already in the database : {tmp.ToString()}");
return StatusCode(208, tmp);
}
else
{
// we recieve a question already in the database
// that should be equal to the question that we
// wanted to add but it isn't
logger.LogCritical(message: "controller's add fail (already in the database) but\nquestion" +
$" recieve isn't the same as the one we wanted to add.\n" +
$"Question recieve : {tmp.ToString()}\nquestion to add : {question.ToString()}");
return StatusCode(500);
}
}
// added
if (tmp.Content == question.Content)
{
logger.LogTrace(message: $"question added : {tmp.ToString()}");
// the question has been added and we recieved him
return StatusCode(202, tmp);
}
else
{
// the question may be added but we do not recieved him
try
{
if (unity.getQuestion(question.Content) != null)
{
// he is added
logger.LogError(message: $"question added but not recieved");
return Ok(); // not 202 to make a difference between 2 cases
}
else
{
// he is not added
logger.LogCritical(message: "question that we wanted to add not added\nand we have added another one");
if (unity.getQuestion(question.Content) == null) // <=> not added
return StatusCode(500);
}
}
catch (Exception)
{
return StatusCode(500);
}
}
logger.LogError(message: "this case should not append");
return StatusCode(500);
}
/// <summary>
/// get a part of all questions
/// </summary>
/// <param name="page">the actual page</param>
/// <param name="count">number of T element in a page</param>
/// <param name="orderCriteria">the order criteria</param>
/// <returns>
/// status code :
/// 200 if we got a set
/// 204 if we got an empty set
/// 400 if we got nothing
///
/// return content :
/// a tuple of the number of page and
/// all questions in the database for
/// the page nb if status code = 200
/// the number of page for count element if status code = 204
/// nothing if status code = 400
/// </returns>
public async Task<IActionResult> GetSomeQuestions(int page, int count = 10, QuestionOrderCriteria orderCriteria = QuestionOrderCriteria.ById)
{
var tmp = await unity.getQuestions(page, count, orderCriteria);
if (tmp.questions == null)
{
logger.LogInformation(message: "get question : bad request (page or/and count incorrect)");
return BadRequest(tmp.nbPages);
}
else if (tmp.questions.Count() == 0)
{
logger.LogWarning(message: $"get question : no content. number of element : {unity.getNbQuestions()}, page wanted : {page}, number of elements in a page : {count}");
return NoContent();
}
else
{
logger.LogTrace(message: $"get questions : page = {page}, count = {count}, order criteria = {orderCriteria switch
{
QuestionOrderCriteria.ById => "byId",
QuestionOrderCriteria.ByContent => "byContent",
QuestionOrderCriteria.ByIdChapter => "byIdChapter",
QuestionOrderCriteria.ByNbFalls => "byNbFalls",
QuestionOrderCriteria.ByDifficulty => "byDifficulty",
_ => "none"
}}");
return Ok(tmp);
}
}
/// <summary>
/// delete a question
/// </summary>
/// <param name="id">the id of the question to delete</param>
/// <returns>
/// status code :
/// 200 if the question is removed
/// 204 if the question is removed
/// 400 if the id is incorrect
/// 500 if there was an internal error that doesn't allow to continue
/// return content :
/// aministrator deleted when status code = 200
/// no content when status code = 204
/// no content when status code = 400
/// no content when status code = 500
/// </returns>
public async Task<IActionResult> DeleteQuestion(int id)
{
if (id < 0)
{
logger.LogError("want to delete a question with an id less than 0");
return BadRequest();
}
int count = unity.getNbQuestions(); // count : number of elements before opperation
var tmp = await unity.removeQuestion(id);
if (tmp == null) // we don't recieve the question
{
if (unity.getNbQuestions() == count) // he is not deleted
{
if (unity.getQuestion(id) != null)
{
logger.LogCritical(message: "remove question fail : question not removed and not recieved");
return StatusCode(500);
}
else
{
logger.LogInformation(message: "trying to remove a question with an id who don't exist");
return BadRequest();
}
}
else // he may be deleted
{
if (unity.getQuestion(id) == null) // he must be deleted
{
logger.LogError(message: "question removed but not returned");
return NoContent();
}
else // he is not deleted
{
logger.LogCritical(message: "remove question fail : question to remove not remove\ninstead, anotherone is deleted and we recieved nothing");
return StatusCode(500);
}
}
}
if (unity.getNbQuestions() == count)
{
// <=> we have recieved a question which should be deleted
// but since we have the same number of question than
// before deletion, it isn't deleted
logger.LogCritical(message: $"question \"{tmp.ToString()}\"should be delete but it isn't");
return StatusCode(500);
}
logger.LogTrace(message: $"question removed {tmp.ToString()}");
return Ok(tmp);
}
/// <summary>
/// get a question
/// </summary>
/// <param name="id">the id of the question</param>
/// <returns>
/// status code :
/// 200 when we got a question
/// 204 when we got null
///
/// return content :
/// the question that correspond to the id when status code = 200
/// nothing when status code = 204
/// </returns>
public async Task<IActionResult> GetQuestion(int id)
{
var tmp = await unity.getQuestion(id);
if (tmp == null) return NoContent();
return Ok(tmp);
}
/// <summary>
/// update a question
/// </summary>
/// <param name="id">the id of the question</param>
/// <returns>
/// status code :
/// 200 when we got a question
/// 204 when we got null
/// 208 when the nickname is already used
/// return content :
/// the question that correspond to the id when status code = 200
/// nothing when status code = 204
/// the question which have this nickname when status code = 208
/// </returns>
public async Task<IActionResult> PutQuestion(int id, QuestionDto question)
{
var tmp = await unity.getQuestion(question.Content);
if (tmp != null) return StatusCode(208);
tmp = await unity.updateQuestion(id, question);
if (tmp == null) return NoContent();
return Ok(tmp);
}
}
}

@ -1,3 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
@ -7,6 +9,8 @@ builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddApiVersioning();
var app = builder.Build();
// Configure the HTTP request pipeline.

@ -252,6 +252,11 @@ namespace WebApi
return PlayerManager.getMaxScorePlayer(id);
}
public Task<PlayerDto?> updatePlayer(int id, PlayerDto player)
{
return PlayerManager.updatePlayer(id, player);
}
public int getNbQuestions()
{
return QuestionManager.getNbQuestions();
@ -301,5 +306,10 @@ namespace WebApi
{
return QuestionManager.getQuestionsByChapterAndDifficulty(idChapter, difficulty, nb, count, orderCriteria);
}
public Task<QuestionDto?> getQuestion(string content)
{
return QuestionManager.getQuestion(content);
}
}
}

Loading…
Cancel
Save