diff --git a/Documentation/Requète pour excécuter et tester l'api ResFull.postman_collection.json b/Documentation/Requète pour excécuter et tester l'api ResFull.postman_collection.json new file mode 100644 index 0000000..c0691a6 --- /dev/null +++ b/Documentation/Requète pour excécuter et tester l'api ResFull.postman_collection.json @@ -0,0 +1,308 @@ +{ + "info": { + "_postman_id": "03cfff4d-c3f5-4b46-af15-385a3b14f51c", + "name": "Requète pour excécuter et tester l'api ResFull", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "19401801" + }, + "item": [ + { + "name": "https://localhost:7097/api/v1/Joueur", + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "" + }, + "url": { + "raw": "https://localhost:7097/api/v1/Joueur", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "7097", + "path": [ + "api", + "v1", + "Joueur" + ] + }, + "description": "# Requète pour excécuter et tester l'api ResFull" + }, + "response": [] + }, + { + "name": "https://localhost:7097/api/v1/Joueur/1/10", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://localhost:7097/api/v1/Joueur/1/10", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "7097", + "path": [ + "api", + "v1", + "Joueur", + "1", + "10" + ] + }, + "description": "**Recuperer les joueurs par pagination** \ntemplate:\n\n```uri \nhttps://localhost:7097/api/v1/Joueur/{page}/{pageSize}\n```" + }, + "response": [] + }, + { + "name": "https://localhost:7097/api/v1/Joueur", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"pseudo\": \"vic\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:7097/api/v1/Joueur", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "7097", + "path": [ + "api", + "v1", + "Joueur" + ] + } + }, + "response": [] + }, + { + "name": "https://localhost:7097/api/v1/Joueur/3", + "request": { + "method": "PUT", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"id\":3,\n \"pseudo\":\"maman\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:7097/api/v1/Joueur/3", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "7097", + "path": [ + "api", + "v1", + "Joueur", + "3" + ] + }, + "description": "**Metre à jour un joueur de la base de donnée**\n```url\nhttps://localhost:7097/api/v1/Joueur/{id}\n```" + }, + "response": [] + }, + { + "name": "https://localhost:7097/api/v2/Joueur/1/10?name=vic", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://localhost:7097/api/v2/Joueur/1/10?name=vic", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "7097", + "path": [ + "api", + "v2", + "Joueur", + "1", + "10" + ], + "query": [ + { + "key": "name", + "value": "vic" + } + ] + }, + "description": "**Recuperer les joueurs par pagination et filtrage de donnée par pseudo**\nTemplate:\n```url\nhttps://localhost:7097/api/v1/Joueur/{page}/{pageSize}?name=\"pseudo\"\n```" + }, + "response": [] + }, + { + "name": "https://localhost:7097/api/v2/Joueur/1/10?name=vic", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://localhost:7097/api/v2/Joueur/vic", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "7097", + "path": [ + "api", + "v2", + "Joueur", + "vic" + ] + }, + "description": "**Get joueur by name**\nTemplate:\n```url\nhttps://localhost:7097/api/v2/Joueur/{name}\n```" + }, + "response": [] + }, + { + "name": "https://localhost:7097/api/v2/Joueur/4", + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "https://localhost:7097/api/v2/Joueur/5", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "7097", + "path": [ + "api", + "v2", + "Joueur", + "5" + ] + }, + "description": "**Supprimer un joueur de la base de donnée**\nTemplate:\n```url\nhttps://localhost:7097/api/v2/Joueur/{id}\n```" + }, + "response": [] + }, + { + "name": "https://localhost:7097/api/v1/Partie", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://localhost:7097/api/v1/Partie", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "7097", + "path": [ + "api", + "v1", + "Partie" + ] + }, + "description": "**Lister toutes les parties jouer**\nTemplate:\n```url\nhttps://localhost:7097/api/v1/Partie\n```" + }, + "response": [] + }, + { + "name": "https://localhost:7097/api/v1/Partie", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"joueur\": {\n \"pseudo\": \"vic\"\n},\n \"score\": 7\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:7097/api/v1/Partie", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "7097", + "path": [ + "api", + "v1", + "Partie" + ] + }, + "description": "**Crée une partie**\n" + }, + "response": [] + }, + { + "name": "https://localhost:7097/api/v1/Partie/8", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://localhost:7097/api/v1/Partie/8", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "7097", + "path": [ + "api", + "v1", + "Partie", + "8" + ] + }, + "description": "**Get partie by id**" + }, + "response": [] + }, + { + "name": "https://localhost:7097/api/v1/Partie/8", + "request": { + "method": "PUT", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"id\": 8,\n \"joueur\": {\n \"pseudo\": \"vic\"\n },\n \"score\": 48\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:7097/api/v1/Partie/8", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "7097", + "path": [ + "api", + "v1", + "Partie", + "8" + ] + } + }, + "response": [] + } + ] +} \ No newline at end of file diff --git a/README.md b/README.md index 38551b1..c600956 100644 --- a/README.md +++ b/README.md @@ -57,13 +57,65 @@ $ dotnet tool install --global dotnet-ef ### Setup * Ouvrir le projet dans Visual Studio. + +#### pour l'API Gateway * Configurer l'exécution de l'application en mode "Multiple startup projects" et sélectionner les projets suivants : - * BowlingApi + * BowlingApi: RestFull * Bowling Api Gateway - * GraphQL Project + * GraphQL Project: GraphQL +* Build le projet. +* L'application est prête à être utilisée. + +#### pour l'API RestFull +* Configurer l'exécution de l'application en mode "Multiple startup projects" et sélectionner les projets suivants : + * BowlingApi: Https * Build le projet. * L'application est prête à être utilisée. +#### pour l'API GraphQL +* Configurer l'exécution de l'application en mode "Multiple startup projects" et sélectionner les projets suivants : + * GraphQL Project: GraphQL +* Build le projet. +* L'application est prête à être utilisée. + +## Requêtes GraphQL +url: +```shell +https://localhost:7197/graphql/ +``` + +### Créer un joueur + +```graphql +mutation Addjoueur{ + addjoueur (input: { + pseudo:"dadada" + }){ + joueur { + pseudo + } + } +} +``` + +### Récupérer tous les joueurs + +```graphql + query GetJoueur{ + joueurs{ + id + pseudo + } +} +``` + +## Requêtes RestFull + +Client RestFull utilisé : Postman +lien de la collection : https://codefirst.iut.uca.fr/git/victor_perez.ngounou/ApiBowlingProject/-/blob/master/Documentation/RestFull%20API%20Bowling.postman_collection.json + + + ## Usage * Open the solution in Visual Studio 2022 diff --git a/Sources/BowlingApi/Controllers/PartieController.cs b/Sources/BowlingApi/Controllers/PartieController.cs index 58b4961..c8ccbe9 100644 --- a/Sources/BowlingApi/Controllers/PartieController.cs +++ b/Sources/BowlingApi/Controllers/PartieController.cs @@ -14,8 +14,8 @@ using Microsoft.AspNetCore.Mvc; namespace BowlingApi.Controllers { - - [Route("api/[controller]")] + [ApiVersion("1")] + [Route("api/v{version:apiVersion}/[controller]")] [ApiController] public class PartieController : ControllerBase { @@ -148,7 +148,7 @@ namespace BowlingApi.Controllers return BadRequest("La partie est obligatoire"); var updatepartie = _partieService.Update(partie); - if (updatepartie.Result == null) + if (updatepartie.Result == false) { return NotFound(); } diff --git a/Sources/BowlingApi/bowling.db b/Sources/BowlingApi/bowling.db index 3a3942f..fef204f 100644 Binary files a/Sources/BowlingApi/bowling.db and b/Sources/BowlingApi/bowling.db differ diff --git a/Sources/BowlingRepository/Interface/IpartieRepository.cs b/Sources/BowlingRepository/Interface/IpartieRepository.cs index a1d2df6..747745f 100644 --- a/Sources/BowlingRepository/Interface/IpartieRepository.cs +++ b/Sources/BowlingRepository/Interface/IpartieRepository.cs @@ -10,7 +10,7 @@ namespace BowlingRepository.Interface public Task Update(PartieEntity _partie); public Task> GetAll(); public Task> GetAllWithDate(DateTime date); - public Task GetDataWithId(int id); + public Task GetDataWithId(long id); } } diff --git a/Sources/BowlingRepository/JoueurRepository.cs b/Sources/BowlingRepository/JoueurRepository.cs index 3211214..e80245a 100644 --- a/Sources/BowlingRepository/JoueurRepository.cs +++ b/Sources/BowlingRepository/JoueurRepository.cs @@ -40,10 +40,19 @@ public class JoueurRepository:IJoueurRepository public async Task Delete(long id) { JoueurEntity entity = _context.Joueurs.Find(id); + if (entity == null) + { + return false; + } _context.Joueurs.Remove(entity); return await _context.SaveChangesAsync() > 0; } - + + /// + /// Methode pour mettre à jour un joueur de la base de données + /// + /// + /// public async Task Update(JoueurEntity joueur) { return await _context.SaveChangesAsync() > 0; diff --git a/Sources/BowlingRepository/Interface/PartieRepository.cs b/Sources/BowlingRepository/PartieRepository.cs similarity index 96% rename from Sources/BowlingRepository/Interface/PartieRepository.cs rename to Sources/BowlingRepository/PartieRepository.cs index 9cd4a1d..e5a6390 100644 --- a/Sources/BowlingRepository/Interface/PartieRepository.cs +++ b/Sources/BowlingRepository/PartieRepository.cs @@ -48,7 +48,7 @@ namespace BowlingRepository.Interface throw new NotImplementedException(); } - public async Task GetDataWithId(int id) + public async Task GetDataWithId(long id) { var data = await _context.Parties.FirstOrDefaultAsync(n => n.Id == id); return data; diff --git a/Sources/BowlingService/Interfaces/IPartieService.cs b/Sources/BowlingService/Interfaces/IPartieService.cs index 29e47ab..e1a76eb 100644 --- a/Sources/BowlingService/Interfaces/IPartieService.cs +++ b/Sources/BowlingService/Interfaces/IPartieService.cs @@ -11,7 +11,7 @@ namespace BowlingService.Interfaces public Task Update(PartieDTO _partie); public Task> GetAll(); public Task> GetAllWithDate(DateTime date); - public Task GetDataWithId(int id); + public Task GetDataWithId(long id); } } diff --git a/Sources/BowlingService/JoueurService.cs b/Sources/BowlingService/JoueurService.cs index 01eae6a..3421360 100644 --- a/Sources/BowlingService/JoueurService.cs +++ b/Sources/BowlingService/JoueurService.cs @@ -69,7 +69,12 @@ namespace BowlingService try { result = await _joueurRepository.Delete(_joueurId); - _logger.LogInformation("A player was deleted : {player}", _joueurId); + + if (result) + _logger.LogInformation("A player was deleted : {player}", _joueurId); + else + _logger.LogWarning("A player not found : {player}", _joueurId); + } catch (Exception ex) { diff --git a/Sources/BowlingService/Interfaces/PartieService.cs b/Sources/BowlingService/PartieService.cs similarity index 85% rename from Sources/BowlingService/Interfaces/PartieService.cs rename to Sources/BowlingService/PartieService.cs index 9ba6d33..b805d02 100644 --- a/Sources/BowlingService/Interfaces/PartieService.cs +++ b/Sources/BowlingService/PartieService.cs @@ -104,7 +104,7 @@ public async Task Add(PartieDTO _partie) throw new NotImplementedException(); } - public async Task GetDataWithId(int id) + public async Task GetDataWithId(long id) { PartieDTO _partie = null; @@ -129,19 +129,29 @@ public async Task Add(PartieDTO _partie) { bool result = false; - using (var context = new BowlingContext()) + try { - PartieEntity entity = _mapper.Map(_partie); + PartieEntity entity=await _IpartieRepository.GetDataWithId(_partie.Id); entity.Date = _partie.Date; entity.Score = _partie.Score; - result = _IpartieRepository.Update(entity).Result; - + result = await _IpartieRepository.Update(entity); + if (result) + { + _logger.LogInformation("partie was updated : {partie}", _partie.Id); + } + else + { + _logger.LogInformation("partie was not updated : {partie}", _partie.Id); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Error while updating player : {player}", _partie.Id); + throw; } return result; } - - } } diff --git a/Sources/GraphQL Project/bowling.db b/Sources/GraphQL Project/bowling.db index 67440ac..af739cf 100644 Binary files a/Sources/GraphQL Project/bowling.db and b/Sources/GraphQL Project/bowling.db differ diff --git a/Sources/Tests/BowlingAPITest/TestPartiControlleur.cs b/Sources/Tests/BowlingAPITest/TestPartiControlleur.cs index 59b8455..30b951b 100644 --- a/Sources/Tests/BowlingAPITest/TestPartiControlleur.cs +++ b/Sources/Tests/BowlingAPITest/TestPartiControlleur.cs @@ -53,21 +53,7 @@ namespace BowlingAPITest testItems.Add(new PartieDTO { Score = 2 }); return testItems; } - //[Fact] - //public async Task Get_With_Invalid_id_Should_Return_BadRequest() - //{ - // // Arrange - // var PartieController = new PartieController(null); - - // // Act - // var result = await PartieController.Get(0); - - // // Assert - // result.Should().BeOfType(); - // var badRequestResult = result as BadRequestObjectResult; - // badRequestResult.Value.Should().Be("Le id de la partie est obligatoire"); - //} - + [Fact] public async Task Get_With_Valid_id_Should_Return_Ok_With_partie() { @@ -141,22 +127,7 @@ namespace BowlingAPITest result.Should().BeOfType(); } - //[Fact] - //public async Task Get_White_id_ShouldReturnNotFound() - //{ - // // Arrange - - // var partie1 = new PartieDTO { Score = 1 }; - // var mockService = new Mock(); - // mockService.Setup(service => service.GetDataWithId(2)).ReturnsAsync(partie1); - // var controller = new PartieController(mockService.Object); - - // // Act - // var result = await controller.Get(2); - - // // Assert - // result.Should().BeOfType(); - //} + [Fact] public async Task Get_ShouldReturnInternalServerError() { @@ -172,24 +143,8 @@ namespace BowlingAPITest result.Should().BeOfType(); result.StatusCode.Should().Be(500); } - //TEST POST - //[Fact] - //public async Task Post_With_Invalid_parti_Should_Return_BadRequest() - //{ - // // Arrange - // var PartieController = new PartieController(null); - - // // Act - // var result = await PartieController.Post(null); - - // // Assert - // result.Should().BeOfType>(); - // var actionResult = result as ActionResult; - // actionResult.Result.Should().BeOfType(); - // var badRequestResult = actionResult.Result as BadRequestObjectResult; - // badRequestResult.Value.Should().Be("La partie est obligatoire"); - //} - + + [Fact] void test()