Compare commits

...

180 Commits

Author SHA1 Message Date
Kentin BRONGNIART 1338a073fd correction PaginationResult
continuous-integration/drone/push Build is passing Details
2 weeks ago
Kentin BRONGNIART 3510f8219d Merge branch 'master' of https://codefirst.iut.uca.fr/git/WhatTheFantasy/WF-PmAPI
continuous-integration/drone/push Build is passing Details
2 weeks ago
Kentin BRONGNIART fceef665af correction probleme route quote
2 weeks ago
Leni BEAULATON 887b43a8a9 Mise à jour de 'README.md'
continuous-integration/drone/push Build is passing Details
2 weeks ago
Kentin BRONGNIART b28632ca27 Route update Lang + correction update lang
continuous-integration/drone/push Build is passing Details
2 weeks ago
Kentin BRONGNIART 092b53fe89 Mise a jour User Lang
continuous-integration/drone/push Build is passing Details
2 weeks ago
Leni BEAULATON eb950fe801 Merge branch 'master' of https://codefirst.iut.uca.fr/git/WhatTheFantasy/WF-PmAPI
continuous-integration/drone/push Build is passing Details
2 weeks ago
Leni BEAULATON d51225cf23 Bdd21 PGSQL
2 weeks ago
Leni BEAULATON 326141ebea Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
2 weeks ago
Leni BEAULATON 5153564054 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build encountered an error Details
2 weeks ago
Leni BEAULATON 1f6dfeefc4 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
2 weeks ago
Leni BEAULATON 7660456667 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
2 weeks ago
Leni BEAULATON 738880a055 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
2 weeks ago
Leni BEAULATON 42b791d630 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
2 weeks ago
Leni BEAULATON b695a0c3a9 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
2 weeks ago
Leni BEAULATON 8f60990194 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
2 weeks ago
Leni BEAULATON 6d8db552c7 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
2 weeks ago
Leni BEAULATON 5634943a6d Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
2 weeks ago
Leni BEAULATON 552e18702c Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
2 weeks ago
Leni BEAULATON 0c62d8ed3b Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
2 weeks ago
Leni BEAULATON 571f2f0967 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
2 weeks ago
Leni BEAULATON f96b0650bd Bdd2 PGSQL
continuous-integration/drone/push Build is failing Details
2 weeks ago
Leni BEAULATON dd5461e3e4 Bdd1 PGSQL
continuous-integration/drone/push Build is failing Details
2 weeks ago
Leni BEAULATON f1e5399674 Bdd12 SQLite
continuous-integration/drone/push Build is failing Details
2 weeks ago
Leni BEAULATON ff0129aba2 Bdd11 SQLite
continuous-integration/drone/push Build is passing Details
2 weeks ago
Leni BEAULATON d6b7d5cc10 Bdd10 SQLite
continuous-integration/drone/push Build is passing Details
2 weeks ago
Leni BEAULATON 0f02cc0563 Merge branch 'master' of https://codefirst.iut.uca.fr/git/WhatTheFantasy/WF-PmAPI
continuous-integration/drone/push Build is passing Details
2 weeks ago
Leni BEAULATON e9db38a673 Bdd9 SQLite
2 weeks ago
Leni BEAULATON 344c2b8a61 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
2 weeks ago
Leni BEAULATON da6534249f Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
2 weeks ago
Leni BEAULATON ba1429e8d0 Merge branch 'master' of https://codefirst.iut.uca.fr/git/WhatTheFantasy/WF-PmAPI
continuous-integration/drone/push Build is passing Details
2 weeks ago
Leni BEAULATON f125ebc9fd Bdd8 SQLite
2 weeks ago
Leni BEAULATON 8e24f3bd4d Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
2 weeks ago
Leni BEAULATON 11e9f528b0 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
2 weeks ago
Leni BEAULATON 197251908c Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
2 weeks ago
Leni BEAULATON 8383532f79 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
2 weeks ago
Leni BEAULATON ddc7bd482a Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
2 weeks ago
Leni BEAULATON d0765e9194 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
2 weeks ago
Leni BEAULATON dac0c7a433 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
2 weeks ago
Leni BEAULATON ed87c0a42b Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
2 weeks ago
Leni BEAULATON 26e2aaa75c Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
2 weeks ago
Leni BEAULATON 1bffdcd1ca Mise à jour de '.drone.yml'
continuous-integration/drone/push Build was killed Details
2 weeks ago
Leni BEAULATON 3c94e8900d Mise à jour de '.drone.yml'
continuous-integration/drone/push Build encountered an error Details
2 weeks ago
Leni BEAULATON feda8ddd81 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build encountered an error Details
2 weeks ago
Leni BEAULATON d1f802a002 Bdd7 SQLite
continuous-integration/drone/push Build is passing Details
2 weeks ago
Leni BEAULATON f578dffd53 Bdd6 SQLite
continuous-integration/drone/push Build is passing Details
2 weeks ago
Leni BEAULATON c6bb4053f6 Bdd5 SQLite
continuous-integration/drone/push Build is passing Details
2 weeks ago
Leni BEAULATON 5f35563be6 Bdd5
continuous-integration/drone/push Build is passing Details
2 weeks ago
Leni BEAULATON a1eddae208 Merge branch 'master' of https://codefirst.iut.uca.fr/git/WhatTheFantasy/WF-PmAPI
continuous-integration/drone/push Build is passing Details
2 weeks ago
Leni BEAULATON e369fb398b bdd4
2 weeks ago
Leni BEAULATON d452ae3047 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
2 weeks ago
Leni BEAULATON c5d0339496 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
2 weeks ago
Leni BEAULATON 725bfe0587 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
2 weeks ago
Leni BEAULATON e3654aa81c Bdd2
continuous-integration/drone/push Build is passing Details
2 weeks ago
Leni BEAULATON 6066064815 Connexion bdd
continuous-integration/drone/push Build is passing Details
2 weeks ago
Kentin BRONGNIART 865ad2448d Mise à jour de 'WF_EF_Api/StubbedContextLib/StubWTFContext.cs'
continuous-integration/drone/push Build is passing Details
3 weeks ago
Kentin BRONGNIART c93119742b Mise à jour de '.drone.yml'
continuous-integration/drone/push Build was killed Details
3 weeks ago
Kentin BRONGNIART a474728dae Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
3 weeks ago
Kentin BRONGNIART 3ff914a543 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Kentin BRONGNIART 6f6d154542 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Kentin BRONGNIART 0169d251a4 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Kentin BRONGNIART 017e298fe5 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Kentin BRONGNIART e1de173450 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Kentin BRONGNIART e20adb2c8f Mise à jour de 'WF_EF_Api/WfApi/Dockerfile'
continuous-integration/drone/push Build was killed Details
3 weeks ago
Kentin BRONGNIART e9f08492b8 Mise à jour de 'WF_EF_Api/WfApi/Dockerfile'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Kentin BRONGNIART 24be82306c Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Kentin BRONGNIART 7b37013f73 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Kentin BRONGNIART d2fd7db0ab Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Kentin BRONGNIART 1b39853556 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Kevin MONDEJAR 8674879e75 Merge pull request 'Merge_API_EF' (#8) from Merge_API_EF into master
continuous-integration/drone/push Build is failing Details
3 weeks ago
Kevin MONDEJAR 81e18d872e Merge branch 'master' into Merge_API_EF
continuous-integration/drone/push Build is passing Details
3 weeks ago
Kevin MONDEJAR d952cb6bf0 micro modif controleur
continuous-integration/drone/push Build is passing Details
3 weeks ago
Kentin BRONGNIART 3e7ae2af12 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Kentin BRONGNIART 3a30c7972b Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Kentin BRONGNIART 75fe8de4d3 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Kevin MONDEJAR 46f60e9fae Merge branch 'Merge_API_EF' of https://codefirst.iut.uca.fr/git/WhatTheFantasy/WF-PmAPI into Merge_API_EF
continuous-integration/drone/push Build is passing Details
3 weeks ago
Kevin MONDEJAR 4d5b895fd8 ajout controleur image
3 weeks ago
Kentin BRONGNIART 5759828aba Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Kentin BRONGNIART 6016183450 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Kentin BRONGNIART ccb8b0295b Mise à jour de '.drone.yml'
continuous-integration/drone/push Build encountered an error Details
3 weeks ago
Leni BEAULATON 4506406e46 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build encountered an error Details
3 weeks ago
Kentin BRONGNIART 100c31b5ff Mise à jour de '.drone.yml'
continuous-integration/drone/push Build encountered an error Details
3 weeks ago
Leni BEAULATON e0fad88de1 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
3 weeks ago
Leni BEAULATON 79bec0a5d8 Maj NSwag.Generation.AspNetCore
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON 6947bc017a Maj Yam
continuous-integration/drone/push Build is failing Details
3 weeks ago
Kevin MONDEJAR 30337d1ed7 route character
3 weeks ago
Leni BEAULATON dd31aa6a64 Merge pull request 'Merge_API_EF' (#7) from Merge_API_EF into master
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON b4b785f20b Merge branch 'Merge_API_EF' of https://codefirst.iut.uca.fr/git/WhatTheFantasy/WF-PmAPI into Merge_API_EF
continuous-integration/drone/push Build is passing Details
3 weeks ago
Leni BEAULATON 8c90ba2721 Mise à jour Swager
3 weeks ago
Leni BEAULATON 24e18ae401 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON 811ec76c49 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON 34d6307b4e Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
3 weeks ago
Leni BEAULATON 2015173411 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
3 weeks ago
Leni BEAULATON 4520ecbe0d Mise à jour de '.drone.yml'
continuous-integration/drone/push Build encountered an error Details
3 weeks ago
Leni BEAULATON 9437cc9fdd Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON 1468acc9f9 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON 510bcecf3c Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
3 weeks ago
Leni BEAULATON 6565c15294 Mise à jour de 'README.md'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Kentin BRONGNIART dde5e1f09a Merge pull request 'Merge_API_EF' (#6) from Merge_API_EF into master
continuous-integration/drone/push Build is failing Details
3 weeks ago
kekentin c13a864252 Merge branch 'Merge_API_EF' of https://codefirst.iut.uca.fr/git/WhatTheFantasy/WF-PmAPI into Merge_API_EF
continuous-integration/drone/push Build is passing Details
3 weeks ago
kekentin ed678b67eb Finition route favorite
3 weeks ago
kekentin eb0af16e6a Route Favorite Remove A finir (supr favorite de la liste dans Quote et User)
3 weeks ago
Leni BEAULATON cfe199a64d Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
3 weeks ago
Leni BEAULATON d872246561 DroneTest
continuous-integration/drone/push Build is failing Details
3 weeks ago
Kevin MONDEJAR da9b4a9b83 Merge branch 'Merge_API_EF' of https://codefirst.iut.uca.fr/git/WhatTheFantasy/WF-PmAPI into Merge_API_EF
continuous-integration/drone/push Build is failing Details
3 weeks ago
Kevin MONDEJAR 3da9d718e7 Fin route Source
3 weeks ago
Leni BEAULATON 18e311da9f drone2
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON 0cacb3a3ed Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Kevin MONDEJAR f52bd3aced Merge branch 'Merge_API_EF' of https://codefirst.iut.uca.fr/git/WhatTheFantasy/WF-PmAPI into Merge_API_EF
3 weeks ago
kekentin 831a65f244 correction erreur favorite
continuous-integration/drone/push Build is failing Details
3 weeks ago
Kevin MONDEJAR 7e1805126e help meeeeeeeee
3 weeks ago
Kevin MONDEJAR 6e1825f6ff fin route comment + debut Source
3 weeks ago
kekentin ff3a1a0efa mise a jour route
continuous-integration/drone/push Build is failing Details
3 weeks ago
kekentin a263050ab6 fininalisation Route Quote
continuous-integration/drone/push Build is failing Details
3 weeks ago
kekentin 0d29cc0626 Merge branch 'Merge_API_EF' of https://codefirst.iut.uca.fr/git/WhatTheFantasy/WF-PmAPI into Merge_API_EF
continuous-integration/drone/push Build is failing Details
3 weeks ago
kekentin e3c668428e Debut correction route Quote
3 weeks ago
Kevin MONDEJAR 48c12241d8 Route user entièrement fonctionnelles
continuous-integration/drone/push Build is failing Details
3 weeks ago
Kevin MONDEJAR f53718694e conflict resolution
continuous-integration/drone/push Build is failing Details
3 weeks ago
Kevin MONDEJAR 019ea01797 correction routes users
3 weeks ago
kekentin 1734512b0b correction route Quote
continuous-integration/drone/push Build is failing Details
3 weeks ago
Kentin BRONGNIART 48a15425c3 Mise à jour de 'README.md'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Kevin MONDEJAR 03312f3978 correction merge
continuous-integration/drone/push Build is failing Details
3 weeks ago
Kevin MONDEJAR 42face1ba2 mise en fonction de certaine routes
3 weeks ago
kekentin 8471e6cfd5 Correction Lien Quote Controlleur
continuous-integration/drone/push Build is failing Details
3 weeks ago
kekentin 5b01d086ad Merge branch 'Merge_API_EF' of https://codefirst.iut.uca.fr/git/WhatTheFantasy/WF-PmAPI into Merge_API_EF
continuous-integration/drone/push Build is failing Details
3 weeks ago
kekentin e51db914c2 Correction Quote avec les ThenInclude qui marche pas dans le GenericRepository
3 weeks ago
Leni BEAULATON b9503cbab4 Implémentation des service quasi finie
continuous-integration/drone/push Build is failing Details
3 weeks ago
kekentin 5ecf9e768f correction Include
continuous-integration/drone/push Build is failing Details
3 weeks ago
kekentin 3015ac873a Merge branch 'Merge_API_EF' of https://codefirst.iut.uca.fr/git/WhatTheFantasy/WF-PmAPI into Merge_API_EF
continuous-integration/drone/push Build is failing Details
3 weeks ago
kekentin b7a0800b08 Avancement DbQuoteManager
3 weeks ago
Leni BEAULATON ad8d0023b6 Test des commentaires dans api
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON 4b1edf0e16 Service des citations
continuous-integration/drone/push Build is failing Details
3 weeks ago
kekentin 69716c4f9b finition route pour Quote
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON f7f0be36e5 Préparation dans program des services
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON fee5b07fac Quote Services
continuous-integration/drone/push Build is failing Details
3 weeks ago
kekentin 50fb9d8d68 Finition ToDto / ToEntity avec des lists
continuous-integration/drone/push Build is failing Details
3 weeks ago
kekentin 63f7da729a Merge branch 'Merge_API_EF' of https://codefirst.iut.uca.fr/git/WhatTheFantasy/WF-PmAPI into Merge_API_EF
3 weeks ago
kekentin aa8cb64d6f Debut rajoue ToDto / ToEntity avec des list
3 weeks ago
Leni BEAULATON 3029f097bc Normalement ça marche, j'ai juste un pb de commande dotnet qui n'est pas reconnu sur la machine
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON 4d2985f73f Services API
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON 09372a4b3e Merge branch 'Merge_API_EF' of https://codefirst.iut.uca.fr/git/WhatTheFantasy/WF-PmAPI into Merge_API_EF
3 weeks ago
Leni BEAULATON af4f9c8ba0 Services API
3 weeks ago
kekentin 0aeb05fa88 Finition des ToEntity
continuous-integration/drone/push Build is failing Details
3 weeks ago
kekentin 1056339f26 finition DbUsersManager
continuous-integration/drone/push Build is failing Details
3 weeks ago
kekentin 960a966f06 Création DbUsersManager pour débuter relation User de API à EF
continuous-integration/drone/push Build is failing Details
4 weeks ago
Kentin BRONGNIART 0b1c5b0208 initialisation merge
continuous-integration/drone/push Build is failing Details
4 weeks ago
Kevin MONDEJAR a5b6fac9a6 debut CI (a finir mais pas touche, j'ai un modèle complet et fonctionnel entre les main)
4 weeks ago
Kevin MONDEJAR 1599968013 Mise à jour de 'README.md'
4 weeks ago
Kevin MONDEJAR d8c91fd73e GenericRepository + Modification DbManager + Mapper
4 weeks ago
Kevin MONDEJAR 48a5f9856e Merge branch 'Relation_EF' of https://codefirst.iut.uca.fr/git/WhatTheFantasy/WF-PmAPI into Relation_EF
4 weeks ago
Kevin MONDEJAR b6e78e4950 Generic mappers (to use in extention methode)
4 weeks ago
Kevin MONDEJAR 57e2af4a45 Mise à jour de 'README.md'
4 weeks ago
Kevin MONDEJAR ddbbf3a361 Merge pull request 'TestManyToMany_Favorite_QuizQuestion' (#5) from TestManyToMany_Favorite_QuizQuestion into Relation_EF
4 weeks ago
kekentin 6584bf6caf merge
1 month ago
kekentin b3ef9f3a4a Merge
1 month ago
kekentin ec34797b76 Création de nouvelle route pour l'API
1 month ago
Kevin MONDEJAR 96f55a3532 suite test console (fin image + character)
1 month ago
Leni BEAULATON 9ff0dc316c Mise à jour de 'README.md'
1 month ago
Leni BEAULATON dc010f74cc Correction fichier de test
1 month ago
Leni BEAULATON a6fdb3242e Mise à jour de 'WF_EF_Api/XUnitTest/UnitTest1.cs'
1 month ago
Kevin MONDEJAR 2738d52fa0 Merge branch 'TestManyToMany_Favorite_QuizQuestion' of https://codefirst.iut.uca.fr/git/WhatTheFantasy/WF-PmAPI into TestManyToMany_Favorite_QuizQuestion
1 month ago
Kevin MONDEJAR d0c0519ca0 ajout console test + continuation dbmanager + injection fournisseur
1 month ago
Kevin MONDEJAR d3bfd171cd ajout suivi des étape readme
1 month ago
kekentin 2c2e09704d Merge branch 'API_init' of https://codefirst.iut.uca.fr/git/WhatTheFantasy/WF-PmAPI into API_init
1 month ago
kekentin 2ec1bc76a4 Avancement Service Quote
1 month ago
Leni BEAULATON 925592aa81 drone.yml
1 month ago
Leni BEAULATON f726c7c745 REST API + Documentation
1 month ago
Leni BEAULATON eb71b3aba1 Ajout et suppression user API
1 month ago
Kevin MONDEJAR 61fa6f89d7 db manager
1 month ago
Kevin MONDEJAR 4b4b0495fa ajout methodes extentions ToDto()
1 month ago
kekentin 8ccde0b125 Build qui marche , verifier que la supretion / insertion / deplacement marche entre :
1 month ago
lebeaulato 6eaa80172b Controller de quote
1 month ago
lebeaulato fdcf26413c routes api fait, ne sauvegardent pas encore
1 month ago
lebeaulato 0a91cae33c API instanciée + route GET
1 month ago
Kevin MONDEJAR d8f941f8ec J'y suis presque (et bah non)
1 month ago
Kevin MONDEJAR 502eba2552 J'y suis presque
1 month ago
Kevin MONDEJAR 7694c94feb test many to many non fonctionel
1 month ago
Kevin MONDEJAR 7ff1bacb96 Fin ajout données stuber + début DbManager
1 month ago
Kevin MONDEJAR 4fd8b07cc6 modif entity + ajout données stuber
1 month ago
kekentin 6755e63274 Début Relation
1 month ago

@ -0,0 +1,208 @@
kind: pipeline
type: docker
name: CI_ApiPm
trigger:
event:
- push
- pull_request
- tag
branch:
exclude:
- master
volumes:
- name: docs
temp: {}
steps:
- name: restore & build
image: mcr.microsoft.com/dotnet/sdk:8.0
commands:
- dotnet build WF_EF_Api/WF_EF_Api.sln --configuration Release
depends_on: [clone]
- name: test
image: mcr.microsoft.com/dotnet/sdk:8.0
commands:
- dotnet test WF_EF_Api/XUnitTest/XUnitTest.csproj
depends_on: [restore & build]
- name: publish
image: mcr.microsoft.com/dotnet/sdk:8.0
commands:
- dotnet publish WF_EF_Api/WfApi/WfApi.csproj -c Release -o out
depends_on: [restore & build, test]
---
kind: pipeline
type: docker
name: CI_ApiPm_Master
trigger:
event:
- push
branch:
- master
volumes:
- name: doc
temp: {}
steps:
- name: restore & build
image: mcr.microsoft.com/dotnet/sdk:8.0
commands:
- dotnet build WF_EF_Api/WF_EF_Api.sln --configuration Release
depends_on: [clone]
- name: test
image: mcr.microsoft.com/dotnet/sdk:8.0
commands:
- dotnet test WF_EF_Api/XUnitTest/XUnitTest.csproj
depends_on: [restore & build]
- name: generate doc
image: mcr.microsoft.com/dotnet/sdk:8.0
volumes:
- name: doc
path: /doc
commands:
- dotnet new tool-manifest
- dotnet tool install NSwag.ConsoleCore
- dotnet restore WF_EF_Api/WF_EF_Api.sln
- dotnet clean WF_EF_Api/WfApi/WfApi.csproj
- cd WF_EF_Api/WfApi
- dotnet nswag aspnetcore2openapi /output:/doc/swagger.json
depends_on: [clone, restore & build , test]
- name: code-inspection
image: hub.codefirst.iut.uca.fr/marc.chevaldonne/codefirst-dronesonarplugin-dotnet8
secrets: [ SECRET_SONAR_LOGIN ]
environment:
sonar_host: https://codefirst.iut.uca.fr/sonar/
sonar_token_wtf:
from_secret: SECRET_SONAR_LOGIN
project_key: wtf-service
commands:
- dotnet restore WF_EF_Api/WF_EF_Api.sln
- dotnet sonarscanner begin /k:$${project_key} /d:sonar.host.url=$${sonar_host} /d:sonar.coverageReportPaths="coveragereport/SonarQube.xml" /d:sonar.login=$${sonar_token_wtf}
- dotnet build WF_EF_Api/WF_EF_Api.sln -c Release --no-restore
- dotnet test WF_EF_Api/XUnitTest/XUnitTest.csproj --logger trx --no-restore /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura --collect "XPlat Code Coverage"
- reportgenerator -reports:"**/coverage.cobertura.xml" -reporttypes:SonarQube -targetdir:"coveragereport"
- dotnet sonarscanner end /d:sonar.login=$${sonar_token_wtf}
depends_on: [test,generate doc]
- name: publish
image: mcr.microsoft.com/dotnet/sdk:8.0
commands:
- dotnet publish WF_EF_Api/WfApi/WfApi.csproj -c Release -o out
depends_on: [restore & build, test]
- name: deploy-api-db
image: hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-dockerproxy-clientdrone:latest
environment:
IMAGENAME: postgres:16.8-alpine3.20
CONTAINERNAME: wtf-api
COMMAND: create
PRIVATE: true
CODEFIRST_CLIENTDRONE_ENV_POSTGRES_PASSWORD:
from_secret: POSTGRES_PASSWORD_API
CODEFIRST_CLIENTDRONE_ENV_POSTGRES_USER:
from_secret: POSTGRES_USER_API
CODEFIRST_CLIENTDRONE_ENV_POSTGRES_DB:
from_secret: POSTGRES_DB_API
ADMINS: kentinbrongniart,lenibeaulaton,kevinmondejar,louisguichard-montguers,maximerocher,tommynguyen2
- name: deploy-auth-db
image: hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-dockerproxy-clientdrone:latest
environment:
IMAGENAME: postgres:16.8-alpine3.20
CONTAINERNAME: wtf-api-auth
COMMAND: create
PRIVATE: true
CODEFIRST_CLIENTDRONE_ENV_POSTGRES_PASSWORD:
from_secret: POSTGRES_PASSWORD_AUTH
CODEFIRST_CLIENTDRONE_ENV_POSTGRES_USER:
from_secret: POSTGRES_USER_AUTH
CODEFIRST_CLIENTDRONE_ENV_POSTGRES_DB:
from_secret: POSTGRES_DB_AUTH
ADMINS: kentinbrongniart,lenibeaulaton,kevinmondejar,louisguichard-montguers,maximerocher,tommynguyen2
- name: deploy-test-db
image: hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-dockerproxy-clientdrone:latest
environment:
IMAGENAME: postgres:16.8-alpine3.20
CONTAINERNAME: wtf-api-test
COMMAND: create
PRIVATE: true
CODEFIRST_CLIENTDRONE_ENV_POSTGRES_PASSWORD: "test"
CODEFIRST_CLIENTDRONE_ENV_POSTGRES_USER: "test"
CODEFIRST_CLIENTDRONE_ENV_POSTGRES_DB: "wtf-test"
ADMINS: kentinbrongniart,lenibeaulaton,kevinmondejar,louisguichard-montguers,maximerocher,tommynguyen2
- name: update-database
image: mcr.microsoft.com/dotnet/sdk:8.0
#DB_PATH_AUTH: "WhatTheFantasy-wtf-api-auth"
environment:
HOST: "WhatTheFantasy-wtf-api-test"
PASSWORD: "test"
USER: "test"
DB: "wtf-test"
commands:
- cd WF_EF_Api/StubbedContextLib
- dotnet tool install --global dotnet-ef
- export PATH="$PATH:/root/.dotnet/tools"
- dotnet ef database update --connection "Host=$${HOST};Database=$${DB};Username=$${USER};Password=$${PASSWORD};"
depends_on: [deploy-api-db,deploy-auth-db,deploy-test-db]
- name: publish-to-registry
image: plugins/docker
settings:
dockerfile: WF_EF_Api/WfApi/Dockerfile
context: WF_EF_Api/
registry: hub.codefirst.iut.uca.fr
repo: hub.codefirst.iut.uca.fr/whatthefantasy/wf-pmapi
username:
from_secret: SECRET_REGISTRY_USERNAME
password:
from_secret: SECRET_REGISTRY_PASSWORD
depends_on: [restore & build, test, code-inspection, publish]
- name: deploy-container
image: hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-dockerproxy-clientdrone:latest
environment:
IMAGENAME: hub.codefirst.iut.uca.fr/whatthefantasy/wf-pmapi:latest
CONTAINERNAME: web-services
COMMAND: create
OVERWRITE: true
CODEFIRST_CLIENTDRONE_ENV_DB_SERVER_API: "WhatTheFantasy-wtf-api"
CODEFIRST_CLIENTDRONE_ENV_DB_USER_API:
from_secret: POSTGRES_USER_API
CODEFIRST_CLIENTDRONE_ENV_DB_PASSWORD_API:
from_secret: POSTGRES_PASSWORD_API
CODEFIRST_CLIENTDRONE_ENV_DB_DATABASE_API:
from_secret: POSTGRES_DB_API
CODEFIRST_CLIENTDRONE_ENV_DB_SERVER_AUTH: "WhatTheFantasy-wtf-api-auth"
CODEFIRST_CLIENTDRONE_ENV_DB_USER_AUTH:
from_secret: POSTGRES_USER_AUTH
CODEFIRST_CLIENTDRONE_ENV_DB_PASSWORD_AUTH:
from_secret: POSTGRES_PASSWORD_AUTH
CODEFIRST_CLIENTDRONE_ENV_DB_DATABASE_AUTH:
from_secret: POSTGRES_DB_AUTH
#CODEFIRST_CLIENTDRONE_ENV_DB_SERVER_API_TEST: "WhatTheFantasy-wtf-api-test"
CODEFIRST_CLIENTDRONE_ENV_DB_SERVER_API_TEST: "api-test"
CODEFIRST_CLIENTDRONE_ENV_DB_USER_API_TEST: "test"
CODEFIRST_CLIENTDRONE_ENV_DB_PASSWORD_API_TEST: "test"
CODEFIRST_CLIENTDRONE_ENV_DB_DATABASE_API_TEST: "wtf-db-test"
ADMINS: kentinbrongniart,lenibeaulaton,kevinmondejar,louisguichard-montguers,maximerocher,tommynguyen2
depends_on: [restore & build, test, code-inspection, publish, publish-to-registry]

@ -1,2 +1,75 @@
# WF-PmAPI # WF-PmAPI
### Commandes de démarrage
Installer les outils dotnet
```bash
dotnet tool install --global dotnet-ef
```
Générer une migration
```bash
dotnet ef migrations add myFirstMigration
```
Générer la base de donnée
```bash
dotnet ef database update
```
### Paquets
- NSwag.AspNetCore <br>
- Moq
🟨 En cours / ✅ Fait / ❌ Pas fait
### Critères Entity Framework
niveau | description | coeff | jalon | État
--- | --- | --- | --- | ---
☢️ | Le dépôt doit être accessible par l'enseignant | ☢️ | J1 | ✅
☢️ | un .gitignore doit exister au premier push | ☢️ | J1 | ✅
🎬 | les *projets* et les tests compilent | 1 | J1 & J2 | ✅
🎬 | le projet et le tests s'exécutent sans bug (concernant la partie persistance) | 3 | J1 & J2 | ✅
🟢 | Transcription du modèle : Modèle vers entités (et inversement) | 2 | J1 | ✅
🟢 | Requêtes CRUD simples (sur une table) | 1 | J1 | ✅
🟢 | Utilisation de LINQ to Entities | 2 | J1 | ✅
🟡 | Injection / indépendance du fournisseur | 1 | J1 | ✅
🟡 | Requêtes CRUD sur des données complexes (images par exemple) | 2 | J1 | ✅
🟢 | Tests - Appli Console | 1 | J1 | ✅
🟢 | Tests - Tests unitaires (avec SQLite in memory) | 2 | J1 | ❌
🟢 | Tests - Données stubbées et/ou Moq | 1 | J1 | ✅
🟡 | CI : build, tests, Sonar (doc?) | 1 | J1 | ✅
🟡 | Utilisation de relations (One-to-One, One-to-Many, Many-to-Many) (+ mapping, TU, Requêtes) | 4 | J1 | ✅
🟢 | Liens avec le web service | 2 | J1 | ✅
🟡 | Utilisation d'un *Logger* | 1 | J1 | ❌
🟡 | Déploiement | 4 | J2 | ✅
🔴 | Unit of Work❌ / Repository✅ + extras (héritage, accès concurrents...) | 8 | J2 | 🟨
🟢 | Utilisation dans le projet | 2 | J2 | ✅
🟢 | mon dépôt possède un readme qui apporte quelque chose... | 2 | J2 | ✅
### Critères Web API
niveau | description | coeff | jalon | État
--- | --- | --- | --- | ---
☢️ | Le dépôt doit être accessible par l'enseignant | ☢️ | J1 | ✅
☢️ | un .gitignore doit exister au premier push | ☢️ | J1 | ✅
🎬 | les *projets* et les tests compilent | 1 | J1 & J2 | ✅
🎬 | le projet et le tests s'exécutent sans bug (concernant la partie web api) | 4 | J1 & J2 | ✅
🟢 | Modèle <-> DTO | 1 | J1 | ❌
🟢 | Entities <-> DTO | 1 | J1 | ✅
🟡 | Authentification | 4 | J1 |
🟢 | Requêtes GET, PUT, POST, DELETE sur des données simples (1 seul type d'objet en retour, propriétés de types natifs) | 2 | J1 | ✅
🟡 | Pagination & filtrage | 2 | J1 | ✅
🟢 | Injection de service | 2 | J1 | ✅
🟡 | Requêtes GET, PUT, POST, DELETE sur des données complexes (plusieurs données complexes en retour) | 4 | J1 | ✅
🟢 | Tests - Appli Console (consommation des requêtes) | 4 | J1 | ✅
🟢 | Tests - Tests unitaires (avec Stub et/ou Moq) | 2 | J1 | ✅
🟡 | CI : build, tests, Sonar, Documentation (en particulier Swagger avec exemples...) | 1 | J1 | ✅
🟢 | Liens avec la persistance en base de données | 4 | J1 | ✅
🟡 | Utilisation d'un *Logger* | 1 | J1 | ❌
🟡 | Déploiement | 4 | J2 | ✅
🟡 | Utilisation dans le projet | 4 | J2 | ✅
🎬 | mon dépôt possède un readme qui apporte quelque chose... | 1 | J2 | ✅

@ -7,4 +7,19 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.3" />
<PackageReference Include="NSwag.Core" Version="14.3.0" />
<PackageReference Include="NSwag.Core.Yaml" Version="14.3.0" />
<PackageReference Include="NSwag.Generation.AspNetCore" Version="14.3.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\StubbedContextLib\StubbedContextLib.csproj" />
</ItemGroup>
</Project> </Project>

@ -1 +1,134 @@
 using Contextlib;
using Entity;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using StubbedContextLib;
using static System.Net.Mime.MediaTypeNames;
using static System.Net.WebRequestMethods;
var connection = new SqliteConnection("DataSource=:memory:");
connection.Open();
var options = new DbContextOptionsBuilder<WTFContext>()
.UseSqlite(connection)
.Options;
using (var _context = new StubWTFContext(options))
{
_context.Database.EnsureCreated();
// ---- Test Image ---- //
var imageManager = new DbImagesManager(_context);
await imageManager.AddImage(new Images() { Id = 0, ImgPath = "https://www.bing.com/ck/a?!&&p=390428c2820add92760900204667aa721b17d4eb9e8537c91544d76283d06b14JmltdHM9MTc0MjQyODgwMA&ptn=3&ver=2&hsh=4&fclid=297ef5ed-ac44-66f2-2498-e058adb06776&u=a1aHR0cHM6Ly93d3cucG9rZXBlZGlhLmZyL01hamFzcGlj&ntb=1" });
await imageManager.AddImage(new Images() { Id = 0, ImgPath = "https://www.bing.com/images/search?view=detailV2&ccid=t57OzeAT&id=1CCCBB65825E5FB93F10CA6D29EFDBBFEB5CDF27&thid=OIP.t57OzeATZKjBDDrzXqbc5gHaE7&mediaurl=https%3a%2f%2fimg-19.commentcamarche.net%2fP51ArxVXHJKsgdTzGDaqajlWJ3s%3d%2f1500x%2fsmart%2f7b5dd43e607643fea1a61960e3f66fc4%2fccmcms-commentcamarche%2f39481621.jpg&cdnurl=https%3a%2f%2fth.bing.com%2fth%2fid%2fR.b79ececde01364a8c10c3af35ea6dce6%3frik%3dJ99c67%252fb7yltyg%26pid%3dImgRaw%26r%3d0&exph=999&expw=1500&q=image&simid=608026907577902968&ck=0D54F216D075AD6E0ABC46B3AAB7E80A&selectedIndex=19&itb=0" });
Console.WriteLine("---- Test ajout image (id : 11, 12)");
var images = await imageManager.GetAllImage();
foreach (var image in images.items)
{
Console.WriteLine($"- ({image.Id}) : {(image.ImgPath.Length <= 40 ? image.ImgPath : image.ImgPath.Substring(0, 40)+"...")}");
}
Console.WriteLine("");
await imageManager.UpdateImage(12, new Images() { ImgPath = "https://testUpdate/stub"});
Console.WriteLine("---- Test mise a jour image (id : 12)");
images = await imageManager.GetAllImage();
foreach (var image in images.items)
{
Console.WriteLine($"- ({image.Id}) : {(image.ImgPath.Length <= 40 ? image.ImgPath : image.ImgPath.Substring(0, 40) + "...")}");
}
Console.WriteLine("");
await imageManager.RemoveImage(12);
Console.WriteLine("---- Test suppression image (id : 12)");
images = await imageManager.GetAllImage();
foreach (var image in images.items)
{
Console.WriteLine($"- ({image.Id}) : {(image.ImgPath.Length <= 40 ? image.ImgPath : image.ImgPath.Substring(0, 40) + "...")}");
}
Console.WriteLine("");
Console.WriteLine("---- Test getById image (id : 11)");
var img = await imageManager.GetImageById(11);
Console.WriteLine($"- ({img.Id}) : {(img.ImgPath.Length <= 40 ? img.ImgPath : img.ImgPath.Substring(0, 40) + "...")}");
Console.WriteLine("");
Console.WriteLine("---- Test getSomme image (nb : 5, page : 1)");
images = await imageManager.GetSomeImage(1,5);
foreach (var image in images.items)
{
Console.WriteLine($"- ({image.Id}) : {(image.ImgPath.Length <= 40 ? image.ImgPath : image.ImgPath.Substring(0, 40) + "...")}");
}
Console.WriteLine("");
Console.WriteLine("---- Test LastId image");
var id = await imageManager.GetLastImageId();
Console.WriteLine($"- Last image id : {id}");
Console.WriteLine("");
Console.WriteLine("-------------------------------------------------------------------------------");
// ---- Test Character ---- //
var characterManager = new DbCharacterManager(_context);
await characterManager.AddCharacter(new Character() { Id = 0, Name = "Vipélière", IdImage = 11 });
Console.WriteLine("---- Test ajout charcter (id : 11)");
var characters = await characterManager.GetAll();
foreach (var charac in characters.items)
{
Console.WriteLine($"- ({charac.Id}) : {charac.Name} -> {charac.IdImage} : {(charac.Images.ImgPath.Length <= 40 ? charac.Images.ImgPath : charac.Images.ImgPath.Substring(0, 40) + "...")}");
}
Console.WriteLine("");
await characterManager.UpdateCharacter(11,new Character() {Name = "Majespic"});
Console.WriteLine("---- Test mise a jour charcter (id : 11)");
characters = await characterManager.GetAll();
foreach (var charac in characters.items)
{
Console.WriteLine($"- ({charac.Id}) : {charac.Name} -> {charac.IdImage} : {(charac.Images.ImgPath.Length <= 40 ? charac.Images.ImgPath : charac.Images.ImgPath.Substring(0, 40) + "...")}");
}
Console.WriteLine("");
await characterManager.RemoveCharacter(11);
Console.WriteLine("---- Test sup (id : 5)");
characters = await characterManager.GetAll();
foreach (var charac in characters.items)
{
Console.WriteLine($"- ({charac.Id}) : {charac.Name} -> {charac.IdImage} : {(charac.Images.ImgPath.Length <= 40 ? charac.Images.ImgPath : charac.Images.ImgPath.Substring(0, 40) + "...")}");
}
Console.WriteLine("");
Console.WriteLine("---- Test GetById (id : 5)");
var chara = await characterManager.GetCharById(5);
Console.WriteLine($"- ({chara.Id}) : {chara.Name} -> {chara.IdImage} : {(chara.Images.ImgPath.Length <= 40 ? chara.Images.ImgPath : chara.Images.ImgPath.Substring(0, 40) + "...")}");
Console.WriteLine("");
Console.WriteLine("---- Test GetByName (name : Jon Snow)");
chara = await characterManager.GetCharByName("Jon Snow");
Console.WriteLine($"- ({chara.Id}) : {chara.Name} -> {chara.IdImage} : {(chara.Images.ImgPath.Length <= 40 ? chara.Images.ImgPath : chara.Images.ImgPath.Substring(0, 40) + "...")}");
Console.WriteLine("");
Console.WriteLine("---- Test LastId Character");
id = await characterManager.GetLastCharId();
Console.WriteLine($"- Last character id : {id}");
Console.WriteLine("");
}

@ -6,4 +6,28 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer.Design" Version="1.1.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="NLog" Version="5.4.0" />
<PackageReference Include="NSwag.Core" Version="14.3.0" />
<PackageReference Include="NSwag.Core.Yaml" Version="14.3.0" />
<PackageReference Include="NSwag.Generation.AspNetCore" Version="14.3.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Entity\Entity.csproj" />
<ProjectReference Include="..\Shared\Shared.csproj" />
</ItemGroup>
</Project> </Project>

@ -0,0 +1,154 @@
using Entity;
using Microsoft.EntityFrameworkCore;
using Shared;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contextlib
{
public class DbCharacterManager : ICharacterService<Character>
{
private WTFContext _context;
private GenericRepository<Character> _repo;
private DbImagesManager _dbI;
public DbCharacterManager(WTFContext context)
{
_context = context ?? throw new ArgumentNullException(nameof(context), "Database context cannot be null.");
_repo = new GenericRepository<Character>(_context);
_dbI = new DbImagesManager(context);
}
/// <summary>
/// Adds a new character to the database.
/// </summary>
/// <param name="character">The character to be added to the database.</param>
/// <returns>A task that represents the asynchronous operation.</returns>
/// <exception cref="ArgumentNullException">Thrown when the provided character is null.</exception>
public async Task AddCharacter(Character character)
{
if (character == null)
{
throw new ArgumentNullException(nameof(character), "character cannot be null.");
}
var image = await _dbI.GetImageByPath(character.Images.ImgPath);
if (image != null)
{
character.IdImage = image.Id;
character.Images = image;
}
_repo.Insert(character);
await _context.SaveChangesAsync();
}
/// <summary>
/// Retrieves all characters from the database and returns them in a paginated format.
/// </summary>
/// <returns>A task representing the asynchronous operation, with a <see cref="PaginationResult{Character}"/> as its result containing the full list of characters and pagination information.</returns>
public async Task<PaginationResult<Character>> GetAll()
{
List<Character> charLst = _repo.GetItems(0, _repo.Count(), [nameof(Character.Images)]).ToList();
return new PaginationResult<Character>(charLst.Count, 0, charLst.Count, charLst);
}
/// <summary>
/// Retrieves a character by its ID from the database.
/// </summary>
/// <param name="id">The unique identifier of the character to retrieve.</param>
/// <returns>A task that represents the asynchronous operation, with a <see cref="Character"/> as its result.</returns>
/// <exception cref="KeyNotFoundException">Thrown when no character is found with the given ID.</exception>
public async Task<Character> GetCharById(int id)
{
Character? character = _repo.GetById(id, item => item.Id == id, nameof(Character.Images));
if (character == null)
{
throw new KeyNotFoundException($"Error : No character found with the ID: {id}.");
}
return character;
}
/// <summary>
/// Retrieves a character by its name from the database.
/// </summary>
/// <param name="name">The name of the character to retrieve.</param>
/// <returns>A task that represents the asynchronous operation, with a <see cref="Character"/> as its result.</returns>
/// <exception cref="KeyNotFoundException">Thrown when no character is found with the given name.</exception>
public async Task<Character?> GetCharByName(string name)
{
var character = _repo.GetItems(item => item.Name == name,0,1, [nameof(Character.Images)]).FirstOrDefault();
return character;
}
/// <summary>
/// Retrieves the highest character ID from the database.
/// </summary>
/// <returns>The highest character ID in the database. 0 if there is no character in the database</returns>
public async Task<int> GetLastCharId()
{
PaginationResult<Character> characters = await GetAll();
int lastCharId = 0;
foreach (Character character in characters.items)
{
if (character.Id >= lastCharId)
{
lastCharId = character.Id + 1;
}
}
return lastCharId;
}
public async Task<PaginationResult<Character>> GetSomeChar(int page, int count)
{
var charLst = _repo.GetItems(page, count, [nameof(Character.Images)]).ToList();
return new PaginationResult<Character>(charLst.Count, 0, charLst.Count, charLst);
}
/// <summary>
/// Removes a character from the database by its ID.
/// </summary>
/// <param name="id">The ID of the character to remove.</param>
/// <returns>A task representing the asynchronous operation.</returns>
/// <exception cref="KeyNotFoundException">Thrown when no character is found with the given ID.</exception>
public async Task RemoveCharacter(int id)
{
_repo.Delete(id);
await _context.SaveChangesAsync();
}
/// <summary>
/// Updates a character's details by its ID.
/// </summary>
/// <param name="id">The ID of the character to update.</param>
/// <param name="character">The updated character information.</param>
/// <returns>A task representing the asynchronous operation.</returns>
/// /// <exception cref="ArgumentNullException">Thrown when the provided character is null.</exception>
/// <exception cref="KeyNotFoundException">Thrown when no character is found with the given ID.</exception>
public async Task UpdateCharacter(int id, Character character)
{
Character? charac = _repo.GetById(id);
if (charac != null)
{
bool change = false;
var image = await _dbI.GetImageByPath(character.Images.ImgPath);
if (image != null)
{
charac.IdImage = image.Id;
charac.Images = image;
change = true;
}
if (character.Name != null)
{
charac.Name = character.Name;
change = true;
}
_repo.Update(charac);
if (change) _context.SaveChanges();
}
}
}
}

@ -0,0 +1,221 @@
using Entity;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Update;
using Shared;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contextlib
{
public class DbCommentaryManager : ICommentaryService<Commentary>
{
private WTFContext _context;
private GenericRepository<Commentary> _repo;
public DbCommentaryManager(WTFContext context)
{
_context = context ?? throw new ArgumentNullException(nameof(context), "Database context cannot be null.");
_repo = new GenericRepository<Commentary>(context);
}
/// <summary>
/// Adds a new comment to the database.
/// </summary>
/// <param name="comment">The comment to add.</param>
/// <returns>A task representing the asynchronous operation.</returns>
/// <exception cref="ArgumentNullException">Thrown when the comment is null.</exception>
public async Task AddComment(Commentary comment, int idQuote)
{
if (comment == null)
{
throw new ArgumentNullException(nameof(comment), "Comment cannot be null.");
}
var quote = await _context.quotes
.Include(q => q.Commentarys) // collection des commentaires est chargée
.FirstOrDefaultAsync(q => q.Id == idQuote);
var dbU = new DbUsersManager(_context);
var User = await dbU.GetUserByUsername(comment.User.UserName);
if (User == null)
{
throw new ArgumentException("Quote not exist", nameof(comment.User.UserName));
}
if (quote == null)
{
throw new ArgumentException("Quote not exist", nameof(idQuote));
}
comment.User = User;
comment.IdUser = User.Id;
// Lien entre le commentaire et la citation
comment.Quote = quote;
comment.IdQuote = idQuote;
// Ajout commentaire à la collection des commentaires de la citation
//_repo.Insert(comment);
_context.Add(comment);
await _context.SaveChangesAsync();
}
/// <summary>
/// Deletes all comments associated with a specific quote ID from the database.
/// </summary>
/// <param name="quoteId">The ID of the quote whose comments need to be deleted.</param>
/// <returns>A task representing the asynchronous operation.</returns>
/// <exception cref="KeyNotFoundException">Thrown when no comments are found for the provided quote ID.</exception>
public async Task DeleteCommentaryForQuote(int quoteId)
{
var comments = await _context.comments.Where(x => x.IdQuote == quoteId).ToListAsync();
if (!comments.Any())
{
throw new KeyNotFoundException($"No comments found for the quote ID: {quoteId}.");
}
_context.comments.RemoveRange(comments);
await _context.SaveChangesAsync();
}
/// <summary>
/// Deletes all comments associated with a specific user ID from the database.
/// </summary>
/// <param name="userId">The ID of the user whose comments need to be deleted.</param>
/// <returns>A task representing the asynchronous operation.</returns>
/// <exception cref="KeyNotFoundException">Thrown when no comments are found for the provided user ID.</exception>
public async Task DeleteCommentaryForUser(int userId)
{
var comments = await _context.comments.Include(c => c.User).Where(x => x.IdUser == userId).ToListAsync();
if (!comments.Any())
{
throw new KeyNotFoundException($"No comments found for the user ID: {userId}.");
}
_context.comments.RemoveRange(comments);
await _context.SaveChangesAsync();
}
public async Task<PaginationResult<Commentary>> GetAllCommentary()
{
var comments = await _context.comments.Include(c => c.User).Include(c=>c.User.Images).ToListAsync();
return new PaginationResult<Commentary>(comments.Count, 0, comments.Count, comments);
}
public async Task<Commentary> GetCommentaryById(int id)
{
var comment = await _context.comments.Include(c => c.User).Include(c => c.User.Images).Where(x => x.Id == id).FirstOrDefaultAsync();
if(comment == null)
{
throw new KeyNotFoundException($"No comments found with the given ID: {id}.");
}
return comment;
}
public async Task<PaginationResult<Commentary>> GetCommentaryByQuote(int quoteId, int index, int pageSize)
{
var comments = await _context.comments.Include(c => c.User).Include(c => c.User.Images).Where(x => x.IdQuote == quoteId).ToListAsync();
if (!comments.Any())
{
throw new KeyNotFoundException($"No comments found for the quote ID: {quoteId}.");
}
if ((index * pageSize + pageSize) > comments.Count)
{
if (pageSize > comments.Count)
{
return new PaginationResult<Commentary>(comments.Count(), index, pageSize, comments);
}
else
{
return new PaginationResult<Commentary>(pageSize, index, pageSize, comments.Skip(index * pageSize - (((index * pageSize) + pageSize) - comments.Count)).Take(pageSize).ToList());
}
}
return new PaginationResult<Commentary>(comments.Count, index, pageSize, comments.Skip(index * pageSize).Take(pageSize).ToList());
}
public async Task<PaginationResult<Commentary>> GetCommentaryByUser(int userId, int index, int pageSize)
{
var comments = await _context.comments.Include(c => c.User).Where(x => x.IdUser == userId).ToListAsync();
if (!comments.Any())
{
throw new KeyNotFoundException($"No comments found for the user ID: {userId}.");
}
if ((index * pageSize + pageSize) > comments.Count)
{
if (pageSize > comments.Count)
{
return new PaginationResult<Commentary>(comments.Count(), index, pageSize, comments);
}
else
{
return new PaginationResult<Commentary>(pageSize, index, pageSize, comments.Skip(index * pageSize - (((index * pageSize) + pageSize) - comments.Count)).Take(pageSize).ToList());
}
}
return new PaginationResult<Commentary>(comments.Count, index, pageSize, comments.Skip(index * pageSize).Take(pageSize).ToList());
}
public async Task<int> LastCommentaryId()
{
var last = await _context.comments.OrderByDescending(x => x.Id).FirstOrDefaultAsync();
if(last == null)
{
return 0;
}
return last.Id;
}
public async Task RemoveCommentary(int id)
{
Commentary? commentary = await GetCommentaryById(id);
if (commentary == null)
{
throw new KeyNotFoundException($"Error : No comment found with the ID: {id}.");
}
_repo.Delete(commentary);
await _context.SaveChangesAsync();
}
public async Task UpdateCommentary(int id, Commentary comment)
{
var modif = false;
var com = await _context.comments.Where(x => x.Id == id).FirstOrDefaultAsync();
if (comment == null)
{
throw new ArgumentNullException(nameof(comment), "The updated comment data cannot be null.");
}
if (com == null)
{
throw new KeyNotFoundException($"No comments found with the given ID: {id}.");
}
if (comment.Comment != null)
{
com.Comment = comment.Comment;
modif = true;
}
if(comment.DateCommentary != null){
com.DateCommentary = comment.DateCommentary;
modif = true;
}
if(comment.IdQuote != 0)
{
com.IdQuote = comment.IdQuote;
modif = true;
}
if (comment.IdUser != 0)
{
com.IdUser = comment.IdUser;
modif = true;
}
if (modif)
{
await _context.SaveChangesAsync();
}
}
}
}

@ -0,0 +1,117 @@
using Entity;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Shared;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contextlib
{
public class DbFavoriteManager : IFavoriteService<Quote>
{
private WTFContext _context;
private GenericRepository<Quote> _repo;
public DbFavoriteManager(WTFContext context)
{
_context = context ?? throw new ArgumentNullException(nameof(context), "Database context cannot be null.");
_repo = new GenericRepository<Quote>(context);
}
public async Task AddFavorite(int quoteid, int userId)
{
var quote = await _context.quotes // collection des commentaires est chargée
.Include(q => q.Favorite)
.FirstOrDefaultAsync(q => q.Id == quoteid);
var user = await _context.users // collection des commentaires est chargée
.Include(u => u.Favorite)
.FirstOrDefaultAsync(q => q.Id == userId);
if (quote == null && user == null)
{
throw new ArgumentException("Quote or User not exist", nameof(quoteid));
}
var fav = new Favorite
{
// Lien entre le favorite et la citation
Quote = quote,
IdQuote = quoteid,
// Lien entre le favorite et le user
Users = user,
IdUsers = userId,
};
if (fav != null)
{
// Ajout favorite à la collection des favorites de la citation
quote.Favorite.Add(user);
// Ajout favorite à la collection des favorites de la citation
user.Favorite.Add(quote);
}
_context.Add(fav);
await _context.SaveChangesAsync();
}
public async Task RemoveAllFavoriteForQuote(int quoteId)
{
var fav = _context.favorites.Where(item => item.IdQuote == quoteId).ToList();
if (fav == null) throw new KeyNotFoundException();
foreach (var item in fav)
{
_context.favorites.Remove(item);
}
await _context.SaveChangesAsync();
}
public async Task RemoveAllFavoriteForUser(int userId)
{
var fav = _context.favorites.Where(item => item.IdUsers == userId).ToList();
if (fav == null) throw new KeyNotFoundException();
foreach (var item in fav)
{
_context.favorites.Remove(item);
}
await _context.SaveChangesAsync();
}
public async Task RemoveFavorite(int quoteid, int userId)
{
var fav = await _context.favorites.Where(item=>item.IdQuote==quoteid && item.IdUsers==userId).FirstAsync();
if (fav == null) throw new KeyNotFoundException();
_context.favorites.Remove(fav);
await _context.SaveChangesAsync();
}
public async Task<Quote?> GetFavorite(int userId, int idQuote)
{
return await _context.quotes.Where( item => item.Id == idQuote && item.Favorite.Any(u => u.Id == userId) )
.Include(q => q.Source).Include(q => q.Character).ThenInclude(c => c.Images).Include(q=>q.Favorite)
.FirstOrDefaultAsync();
}
public async Task<PaginationResult<Quote>> GetFavoriteByIdUser(int userId, int index, int count)
{
List<Quote> fav = await _context.quotes.Where(item => item.Favorite.Any(u => u.Id == userId))
.Include(q => q.Source).Include(q => q.Character).ThenInclude(c => c.Images).Include(q => q.Favorite)
.Skip(index * count).Take(count).ToListAsync();
return new PaginationResult<Quote>(fav.Count,index,count,fav);
}
}
}

@ -0,0 +1,102 @@
using Entity;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Shared;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace Contextlib
{
public class DbImagesManager : IImagesService<Images>
{
private WTFContext _context;
private GenericRepository<Images> _repository;
public DbImagesManager(WTFContext context)
{
_context = context ?? throw new ArgumentNullException(nameof(context), "Database context cannot be null.");
_repository = new GenericRepository<Images>(context);
}
public async Task AddImage(Images image)
{
_repository.Insert(image);
await _context.SaveChangesAsync();
}
public async Task<PaginationResult<Images>> GetAllImage()
{
return new PaginationResult<Images>(await CountImage(), 0, await CountImage(), _repository.GetItems(0, await CountImage()).ToList());
}
public async Task<Images?> GetImageById(int id)
{
var image = _repository.GetById(id);
if(image == null)
{
throw new KeyNotFoundException($"No image with the id {id}");
}
return image;
}
public async Task<int> GetLastImageId()
{
var last = await GetAllImage();
int id = 1;
{
foreach (Images image in last.items)
{
if(image.Id >= id)
id = image.Id + 1;
}
}
return id;
}
public async Task<PaginationResult<Images>> GetSomeImage(int index, int pageSize)
{
var images = _repository.GetItems(index, pageSize);
return new PaginationResult<Images>(images.Count(),index,pageSize,images.ToList());
}
public async Task RemoveImage(int id)
{
_repository.Delete(id);
await _context.SaveChangesAsync();
}
public async Task UpdateImage(int id, Images image)
{
var img = _repository.GetById(id);
var modif = false;
if (image != null && img != null)
{
if (image.ImgPath != null)
{
img.ImgPath = image.ImgPath;
modif = true;
}
_repository.Update(img);
if (modif)
{
await _context.SaveChangesAsync();
}
}
}
public async Task<int> CountImage()
{
return await _context.images.CountAsync();
}
public async Task<Images?> GetImageByPath(string path)
{
var image = _repository.GetItems(item => item.ImgPath == path,0,1).FirstOrDefault();
return image;
}
}
}

@ -0,0 +1,155 @@
using Entity;
using Microsoft.EntityFrameworkCore;
using Shared;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contextlib
{
public class DbQuestionManager : IQuestionService<Question>
{
private WTFContext _context;
private GenericRepository<Question> _repository;
public DbQuestionManager(WTFContext context)
{
_context = context ?? throw new ArgumentNullException(nameof(context), "Database context cannot be null.");
_repository = new GenericRepository<Question>(context);
}
public async Task AddQuestion(Question question)
{
_repository.Insert(question);
await _context.SaveChangesAsync();
}
public async Task<int> CountQuestions()
{
return _repository.Count();
}
public async Task<PaginationResult<Question>> GetAllQuestion()
{
return new PaginationResult<Question>(_repository.Count(), 0, _repository.Count(), _repository.GetItems(0,_repository.Count()).ToList());
}
public async Task<PaginationResult<Question>> GetInvalidQuestion(int index, int pageSize)
{
List<Question> questionList = _repository.GetItems(item => item.IsValid == false, index, pageSize).ToList();
return new PaginationResult<Question>(questionList.Count(), index, pageSize, questionList);
}
public async Task<Question> GetQuestionById(int id)
{
return _repository.GetById(id);
}
public async Task<Question> GetRandomQuestion()
{
Random rnd = new Random();
Question? question = null;
while(question == null)
{
question = await GetQuestionById(rnd.Next(0, await LastId()-1));
}
return question;
}
public async Task<Question> GetRandomQuestionQuoteToCharacter()
{
//dabord implémenter get random quote
throw new NotImplementedException();
}
public async Task<Question> GetRandomQuestionQuoteToSource()
{
//dabord implémenter get random quote
throw new NotImplementedException();
}
public async Task<PaginationResult<Question>> GetSomeQuestion(int index, int pageSize)
{
List<Question> questionList = _repository.GetItems(item => item.IsValid == false, index, pageSize).ToList();
return new PaginationResult<Question>(questionList.Count(), index, pageSize, questionList);
}
public async Task RemoveQuestion(int id)
{
_repository.Delete(id);
await _context.SaveChangesAsync();
}
public async Task UpdateQuestion(int id, Question question)
{
Question? questionUpdated = await GetQuestionById(id);
if (question != null && questionUpdated != null)
{
bool modified = false;
if (question.IsValid != questionUpdated.IsValid)
{
questionUpdated.IsValid = question.IsValid;
modified = true;
}
if (question.Text != null)
{
questionUpdated.Text = question.Text;
modified = true;
}
if (question.AnswerA != null)
{
questionUpdated.AnswerA = question.AnswerA;
modified = true;
}
if (question.AnswerB != null)
{
questionUpdated.AnswerB = question.AnswerB;
modified = true;
}
if (question.AnswerC != null)
{
questionUpdated.AnswerC = question.AnswerC;
modified = true;
}
if (question.AnswerD != null)
{
questionUpdated.AnswerD = question.AnswerD;
modified = true;
}
if (question.CorrectAnswer != null)
{
questionUpdated.CorrectAnswer = question.CorrectAnswer;
modified = true;
}
_repository.Update(questionUpdated);
if(modified) _context.SaveChanges();
}
;
}
public async Task ValidateQuestion(int id, bool isvalid)
{
Question? question = await GetQuestionById(id);
if (question == null) throw new KeyNotFoundException($"Aucune question avec l'id {id}");
question.IsValid = isvalid;
_repository.Update(question);
}
public async Task<int> LastId()
{
PaginationResult<Question> questions = await GetAllQuestion();
int id = 1;
foreach (Question question in questions.items)
{
if (question.Id >= id)
{
id = question.Id + 1;
}
}
return id;
}
}
}

@ -0,0 +1,298 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Entity;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Shared;
namespace Contextlib
{
public class DbQuoteManager : IQuoteService<Quote>
{
private WTFContext _context;
private GenericRepository<Quote> _repo;
private DbCharacterManager _dbC;
private DbSourceManager _dbS;
private DbImagesManager _dbI;
public DbQuoteManager(WTFContext context)
{
_context = context ?? throw new ArgumentNullException(nameof(context), "Database context cannot be null.");
_repo = new GenericRepository<Quote>(_context);
_dbS = new DbSourceManager(_context);
_dbC = new DbCharacterManager(_context);
_dbI = new DbImagesManager(_context);
}
public async Task<Quote> 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<PaginationResult<Quote>> GetAllQuote()
{
List<Quote> quotes = _context.quotes.Where(item => item.IsValid)
.Include(q => q.Source).Include(q => q.Character).ThenInclude(c => c.Images)
.ToList();
return new PaginationResult<Quote>(quotes.Count, 0, quotes.Count, quotes);
}
public async Task<PaginationResult<Quote>> GetAllQuoteLang(int index, int pageSize, int lang)
{
List<Quote> quotes = await _context.quotes.Where(item => item.IsValid && item.Langage == (LangEnum)lang)
.Include(q => q.Source).Include(q => q.Character).ThenInclude(c => c.Images)
.Skip(index * pageSize).Take(pageSize).ToListAsync();
return new PaginationResult<Quote>(quotes.Count, index, pageSize, quotes);
}
public async Task<Quote?> GetDailyQuote(DateOnly date, int lang)
{
List<Quote> quotes = await _context.quotes.Where(item => item.IsValid && item.Langage == (LangEnum)lang)
.Include(q => q.Source).Include(q => q.Character).ThenInclude(c => c.Images).Include(q => q.Favorite)
.ToListAsync();
if (quotes.Count() == 0) return null;
Quote quote = quotes[date.DayNumber % quotes.Count()];
return quote;
}
public async Task<PaginationResult<Quote>> GetFavorites(int index, int pageSize, int UserId)
{
List<Quote> quotes = _context.quotes.Where(item => item.IsValid && item.Favorite.Where(p => p.Id == UserId) != null)
.Include(q => q.Source).Include(q => q.Character).ThenInclude(c => c.Images).Include(q => q.Favorite)
.Skip(index * pageSize).Take(pageSize).ToList();
return new PaginationResult<Quote>(quotes.Count, index, pageSize, quotes);
}
public async Task<PaginationResult<Quote>> GetInvalidQuote(int index, int pageSize, int lang)
{
List<Quote> quotes = _context.quotes.Where(item => !item.IsValid && item.Langage == (LangEnum)lang)
.Include(q => q.Source).Include(q => q.Character).ThenInclude(c => c.Images)
.Skip(index * pageSize).Take(pageSize).ToList();
return new PaginationResult<Quote>(quotes.Count, index, pageSize, quotes);
}
public async Task<PaginationResult<Quote>> GetInvalidQuote(int index, int pageSize)
{
List<Quote> quotes = _context.quotes.Where(item => !item.IsValid)
.Include(q => q.Source).Include(q => q.Character).ThenInclude(c => c.Images)
.Skip(index * pageSize).Take(pageSize).ToList();
return new PaginationResult<Quote>(quotes.Count, index, pageSize, quotes);
}
public async Task<int> GetLastQuoteId()
{
PaginationResult<Quote> quotes = await GetAllQuote();
int lastQuoteId = 0;
foreach (Quote quote in quotes.items)
{
if (quote.Id >= lastQuoteId)
{
lastQuoteId = quote.Id + 1;
}
}
return lastQuoteId;
}
public async Task<Quote?> GetQuoteById(int id)
{
Quote? quote = _context.quotes.Where(item => item.Id == id)
.Include(q => q.Source).Include(q => q.Character).ThenInclude(c => c.Images)
.FirstOrDefault();
return quote;
}
public async Task<PaginationResult<Quote>> GetSomeQuote(int index, int pageSize)
{
List<Quote> quotes = _context.quotes.Where(item => item.IsValid)
.Include(q => q.Source).Include(q => q.Character).ThenInclude(c => c.Images)
.Skip(index * pageSize).Take(pageSize).ToList();
return new PaginationResult<Quote>(quotes.Count, index, pageSize, quotes);
}
public async Task<PaginationResult<Quote>> GetSuggestions(int index, int pageSize, int lang) // A changer Suggestion Random
{
List<Quote> quotes = _context.quotes.Where(item => item.IsValid && item.Langage == (LangEnum)lang)
.Include(q => q.Source).Include(q => q.Character).ThenInclude(c => c.Images)
//.OrderBy(q=> new Random() )
.Skip(index * pageSize).Take(pageSize).ToList();
return new PaginationResult<Quote>(quotes.Count, index, pageSize, quotes);
}
public async Task<PaginationResult<Quote>> GetValidQuote(int index, int pageSize)
{
List<Quote> quotes = _context.quotes.Where(item => item.IsValid)
.Include(q => q.Source).Include(q => q.Character).ThenInclude(c => c.Images)
.Skip(index * pageSize).Take(pageSize).ToList();
return new PaginationResult<Quote>(quotes.Count, index, pageSize, quotes);
}
public async Task<PaginationResult<Quote>> SearchByCharacter(string character, int index, int pageSize, int lang)
{
List<Quote> quotes = _context.quotes.Where(item => item.IsValid && item.Langage==(LangEnum)lang && (item.Character.Name).Contains(character))
.Include(q => q.Source).Include(q => q.Character).ThenInclude(c => c.Images)
.Skip(index * pageSize).Take(pageSize).ToList();
return new PaginationResult<Quote>(quotes.Count, index, pageSize, quotes);
}
public async Task<PaginationResult<Quote>> SearchByContent(string content, int index, int pageSize, int lang)
{
List<Quote> quotes = _context.quotes.Where(item => item.IsValid && item.Langage == (LangEnum)lang && (item.Content).Contains(content))
.Include(q => q.Source).Include(q => q.Character).ThenInclude(c => c.Images)
.Skip(index * pageSize).Take(pageSize).ToList();
return new PaginationResult<Quote>(quotes.Count, index, pageSize, quotes);
}
public async Task<PaginationResult<Quote>> SearchBySource(string source, int index, int pageSize, int lang)
{
List<Quote> quotes = _context.quotes.Where(item => item.IsValid && item.Langage == (LangEnum)lang && (item.Source.Title).Contains(source))
.Include(q => q.Source).Include(q => q.Character).ThenInclude(c => c.Images)
.Skip(index * pageSize).Take(pageSize).ToList();
return new PaginationResult<Quote>(quotes.Count, index, pageSize, quotes);
}
public async Task RemoveQuote(int quoteId)
{
var quote = _repo.GetById(quoteId);
if (quote == null) throw new KeyNotFoundException();
_repo.Delete( quote );
await _context.SaveChangesAsync();
}
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)
{
bool change = false;
if (quote.IdSource != 0)
{
q.IdSource = quote.IdSource;
change = true;
}
if (quote.IdCharacter != 0)
{
q.IdCharacter = quote.IdCharacter;
change = true;
}
if (quote.IdSource != 0)
{
q.IdSource = quote.IdSource;
change = true;
}
if (quote.IdUsersPropose !=0)
{
q.IdUsersPropose = quote.IdUsersPropose;
change = true;
}
if (quote.Content != null || quote.Content == "")
{
q.Content = quote.Content;
change = true;
}
if (quote.IsValid != q.IsValid)
{
q.IsValid = quote.IsValid;
change = true;
}
if (quote.Likes != q.Likes)
{
q.Likes = quote.Likes;
change = true;
}
if (quote.Langage != q.Langage)
{
q.Langage = quote.Langage;
change = true;
}
_repo.Update(q);
if (change) _context.SaveChanges();
}
return ;
}
public async Task ValidateQuote(int quoteId, bool isValidate)
{
Quote? q = _repo.GetById(quoteId);
if (q != null)
{
q.IsValid = isValidate;
_repo.Update(q);
_context.SaveChanges();
}
return;
}
}
}

@ -0,0 +1,114 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Entity;
using Shared;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace Contextlib
{
public class DbSourceManager : ISourceService<Source>
{
private WTFContext _context;
private GenericRepository<Source> _repo;
public DbSourceManager(WTFContext context)
{
_context = context ?? throw new ArgumentNullException(nameof(context), "Database context cannot be null.");
_repo = new GenericRepository<Source>(_context);
}
public async Task AddSource(Source source)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source), "character cannot be null.");
}
_repo.Insert(source);
await _context.SaveChangesAsync();
}
public async Task<PaginationResult<Source>> GetAll()
{
List<Source> srcLst = _repo.GetItems(0, _repo.Count(), []).ToList();
return new PaginationResult<Source>(srcLst.Count, 0, srcLst.Count, srcLst);
}
public async Task<int> GetLastSourceId()
{
throw new NotImplementedException();
}
public async Task<PaginationResult<Source>> GetSomesSource(int page, int count)
{
var srcLst = _repo.GetItems(page, count, []).ToList();
return new PaginationResult<Source>(srcLst.Count, 0, srcLst.Count, srcLst);
}
public async Task<PaginationResult<Source>> GetSourceByDate(int date)
{
var srcLst = _repo.GetItems(item => item.Year == date, 0, _repo.Count(), []).ToList();
return new PaginationResult<Source>(srcLst.Count, 0, srcLst.Count, srcLst);
}
public async Task<Source> GetSourceById(int id)
{
Source? source = _repo.GetById(id, item => item.Id == id, []);
if (source == null)
{
throw new KeyNotFoundException($"Error : No source found with the ID: {id}.");
}
return source;
}
public async Task<Source?> GetSourceByTitle(string title)
{
var source = _repo.GetItems(item => item.Title == title, 0, 1, []).FirstOrDefault();
return source;
}
public async Task<Source?> GetSourceByType(int type)
{
var source = _repo.GetItems(item => item.TypeSrc == (TypeSrcEnum)type, 0, 1, []).FirstOrDefault();
return source;
}
public async Task RemoveSource(int id)
{
_repo.Delete(id);
await _context.SaveChangesAsync();
}
public async Task UpdateSource(int id, Source source)
{
Source? src = _repo.GetById(id);
if (src != null)
{
bool change = false;
if (src.Title != source.Title)
{
src.Title = source.Title;
change = true;
}
if (src.Year != source.Year)
{
src.Year = source.Year;
change = true;
}
if (src.TypeSrc != source.TypeSrc)
{
src.TypeSrc = source.TypeSrc;
change = true;
}
_repo.Update(src);
if (change) _context.SaveChanges();
}
}
}
}

@ -0,0 +1,190 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Entity;
using Microsoft.EntityFrameworkCore;
using Shared;
namespace Contextlib
{
public class DbUsersManager : IUserService<Users>
{
private WTFContext _context;
private GenericRepository<Users> _repo;
public DbUsersManager( WTFContext context )
{
_context = context ?? throw new ArgumentNullException(nameof(context), "Database context cannot be null.");
_repo = new GenericRepository<Users>(_context);
}
public async Task AddUser(Users user)
{
/*if (await ExistEmail(user.Email) || (await ExistUsername(user.UserName)))
{
throw new ArgumentException("The given Email or Username Already exist");
}*/
if (user == null) {
throw new ArgumentNullException(nameof(user), "user cannot be null.");
}
var dbI = new DbImagesManager(_context);
var image = await dbI.GetImageByPath(user.Images.ImgPath);
if(image != null)
{
user.IdImage = image.Id;
user.Images = image;
}
_repo.Insert(user);
await _context.SaveChangesAsync();
}
public async Task<int> CountUser()
{
return _repo.Count();
}
public async Task<bool> ExistEmail(string email)
{
Users? users = await _context.users.Where(u=>u.Email == email).FirstOrDefaultAsync();
return users != null;
}
public async Task<bool> ExistUsername(string username)
{
Users? users = await _context.users.Where(u => u.UserName == username).FirstOrDefaultAsync();
return users != null;
}
public async Task<PaginationResult<Users>> GetAllUser()
{
List<Users> users = _repo.GetItems(0,_repo.Count(),[nameof(Users.Images)]).ToList();
return new PaginationResult<Users>(users.Count,0,users.Count,users);
}
public async Task<string> GetHashPassword(string username)
{
Users? user = _context.users.Where(u=>u.UserName == username).FirstOrDefault();
if (user == null)
{
return "";
}
return user.Password;
}
public async Task<int> GetLastUserId()
{
PaginationResult<Users> users = await GetAllUser();
int lastUserId = 0;
foreach (Users user in users.items)
{
if (user.Id >= lastUserId)
{
lastUserId = user.Id + 1;
}
}
return lastUserId;
}
public async Task<PaginationResult<Users>> GetSomeUser(int index, int pageSize)
{
List<Users> users = _repo.GetItems(index, pageSize, [nameof(Users.Images)]).ToList();
return new PaginationResult<Users>(users.Count, index, pageSize, users);
}
public async Task<Users> GetUserByEmail(string email)
{
var user = _repo.GetItems(item => item.Email == email, 0, 1, [nameof(Character.Images)]).FirstOrDefault();
if (user == null)
{
throw new KeyNotFoundException($"Error : No user found with the email: {email}.");
}
return user;
}
public async Task<Users> GetUserById(int id)
{
Users? user =_repo.GetById(id, item => item.Id == id, nameof(Users.Images));
if (user == null)
{
throw new KeyNotFoundException($"Error : No users found with the ID: {id}.");
}
return user;
}
public async Task<Users> GetUserByUsername(string username)
{
var user = _repo.GetItems(item => item.UserName == username, 0, 1, [nameof(Character.Images)]).FirstOrDefault();
if (user == null)
{
throw new KeyNotFoundException($"Error : No user found with the name: {username}.");
}
return user;
}
public async Task RemoveUser(int id)
{
Users? user = _repo.GetById(id);
if (user == null)
{
throw new KeyNotFoundException($"Error : No users found with the ID: {id}.");
}
_repo.Delete(user);
await _context.SaveChangesAsync();
}
public async Task SetAdminRole(bool isAdmin)
{
throw new NotImplementedException();
}
public async Task<Users> UpdateUser(int userId, Users user)
{
Users? u = _repo.GetById(userId, item => item.Id == userId, nameof(Users.Images));
if (u != null)
{
bool change = false;
if (user.Images.ImgPath != null)
{
var dbI = new DbImagesManager(_context);
var img = await dbI.GetImageByPath(user.Images.ImgPath);
if (img != null)
{
u.IdImage = dbI.GetImageByPath(user.Images.ImgPath).Id;
change = true;
}
}
if (user.UserName != null)
{
u.UserName = user.UserName;
change = true;
}
if (user.Email != null)
{
u.Email = user.Email;
change = true;
}
if (user.Password != null)
{
u.Password = user.Password;
change = true;
}
if (user.Lang != u.Lang)
{
u.Lang = user.Lang;
change = true;
}
_repo.Update(u);
if (change)_context.SaveChanges();
}
return u;
}
}
}

@ -0,0 +1,120 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
namespace Contextlib
{
public class GenericRepository<T> where T : class
{
private DbContext Context { get; set; }
private DbSet<T> Set { get; set; }
public GenericRepository(DbContext context)
{
Context = context;
Set = Context.Set<T>();
}
public virtual T? GetById(object id)
=> Set.Find(id);
public virtual T? GetById(object id, Expression<Func<T, bool>>? filter = null, params string[] includeProperties)
{
IQueryable<T> query = Set;
if (filter != null)
{
query = query.Where(filter);
}
foreach (string includeProperty in includeProperties)
{
query = query.Include(includeProperty);
}
return query.FirstOrDefault();
}
public virtual IEnumerable<T> GetItems(Expression<Func<T, bool>>? filter = null,
int index = 0, int count = 10,
params string[] includeProperties)
=> GetItems(filter, null, index, count, includeProperties);
public virtual IEnumerable<T> GetItems(Func<IQueryable<T>, IOrderedQueryable<T>>? orderBy = null,
int index = 0, int count = 10,
params string[] includeProperties)
=> GetItems(null, orderBy, index, count, includeProperties);
public virtual IEnumerable<T> GetItems(int index = 0, int count = 10,
params string[] includeProperties)
=> GetItems(null, null, index, count, includeProperties);
public virtual IEnumerable<T> GetItems(Expression<Func<T, bool>>? filter = null,
Func<IQueryable<T>, IOrderedQueryable<T>>? orderBy = null,
int index = 0, int count = 10,
params string[] includeProperties)
{
IQueryable<T> query = Set;
if (filter != null)
{
query = query.Where(filter);
}
foreach (string includeProperty in includeProperties)
{
query = query.Include(includeProperty);
}
if (orderBy != null)
{
query = orderBy(query);
}
return query.Skip(index * count)
.Take(count)
.ToList();
}
public virtual void Insert(T entity)
{
if (Set.Entry(entity).IsKeySet)
return;
Set.Add(entity);
}
public virtual void Insert(params T[] entities)
{
foreach (var entity in entities)
{
Insert(entity);
}
}
public virtual void Delete(object id)
{
T? entity = Set.Find(id);
if (entity == null) return;
Delete(entity);
}
public virtual void Delete(T entity)
{
if (Context.Entry(entity).State == EntityState.Detached)
{
Set.Attach(entity);
}
Set.Remove(entity);
}
public virtual void Update(T entity)
{
Set.Attach(entity);
Context.Entry(entity).State = EntityState.Modified;
}
public virtual int Count()
{
return Set.Count();
}
}
}

@ -0,0 +1,101 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using Entity;
using Microsoft.EntityFrameworkCore;
namespace Contextlib
{
public class WTFContext : DbContext
{
//public DbSet<Admin> admins { get; set; }
public DbSet<Character> characters { get; set; }
public DbSet<Commentary> comments { get; set; }
public DbSet<Favorite> favorites { get; set; }
public DbSet<Images> images { get; set; }
public DbSet<Question> question { get; set; }
public DbSet<Quiz> quizzes { get; set; }
//public DbSet<QuizQuestion> quizQuestions { get; set; }
public DbSet<Quote> quotes { get; set; }
//public DbSet<RecordQuiz> records { get; set; }
public DbSet<Source> sources { get; set; }
public DbSet<Users> users { get; set; }
public DbSet<Admin> admins { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Users>()
.HasMany(q => q.Favorite)
.WithMany(u => u.Favorite)
.UsingEntity<Favorite>(
l => l.HasOne(f => f.Quote)
.WithMany()
.OnDelete(DeleteBehavior.ClientCascade)
.HasForeignKey(f => f.IdQuote),
r => r.HasOne(f => f.Users)
.WithMany()
.OnDelete(DeleteBehavior.ClientCascade)
.HasForeignKey(f => f.IdUsers)
);
modelBuilder.Entity<Users>()
.HasMany(u => u.Quotes)
.WithOne(q => q.User)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasForeignKey(q => q.IdUsersPropose);
modelBuilder.Entity<Users>()
.HasMany<Quote>()
.WithMany()
.UsingEntity<Commentary>(
i => i.HasKey(e => e.Id)
);
modelBuilder.Entity<Commentary>()
.HasOne(c => c.User)
.WithMany()
.HasForeignKey(c => c.IdUser);
modelBuilder.Entity<Quote>()
.HasMany(q => q.Commentarys)
.WithOne(c => c.Quote)
.OnDelete(DeleteBehavior.ClientCascade)
.HasForeignKey(c => c.IdQuote);
modelBuilder.Entity<Quiz>()
.HasMany(q => q.Questions)
.WithMany(u => u.Quizs)
.UsingEntity<QuizQuestion>(
l => l.HasOne<Question>().WithMany().HasForeignKey(q => q.IdQuestion),
r => r.HasOne<Quiz>().WithMany().HasForeignKey(u => u.IdQuiz)
);
//modelBuilder.Entity<Admin>()
// .HasOne(a => a.User)
// .WithOne(u => u.admin);
}
public WTFContext()
{ }
public WTFContext(DbContextOptions<WTFContext> options)
: base(options)
{ }
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
if (!options.IsConfigured)
{
options.UseSqlServer(
$"Server={Environment.GetEnvironmentVariable("DB_SERVER_AUTH")};" +
$"Database={Environment.GetEnvironmentVariable("DB_DATABASE_AUTH")};" +
$"User Id={Environment.GetEnvironmentVariable("DB_USER_AUTH")};" +
$"Password={Environment.GetEnvironmentVariable("DB_PASSWORD_AUTH")};");
//options.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Wf-Database.mdf;Trusted_Connection=True;");
}
}
}
}

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DTO
{
public class CharacterDTO
{
public int Id { get; set; }
public string Name { get; set; }
public string imagePath { get; set; }
}
}

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DTO
{
public class CommentaryDTO
{
public int Id { get; set; }
public string Comment { get; set; }
public DateTime Date { get; set; }
public string User { get; set; }
public string ImagePath { get; set; }
}
}

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.3" />
<PackageReference Include="NSwag.Core" Version="14.3.0" />
<PackageReference Include="NSwag.Core.Yaml" Version="14.3.0" />
<PackageReference Include="NSwag.Generation.AspNetCore" Version="14.3.0" />
</ItemGroup>
</Project>

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DTO
{
public class FavoriteDTO
{
public int IdUser { get; set; }
public int IdQuote { get; set; }
}
}

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DTO
{
public class ImageDTO
{
public int IdImage { get; set; }
public string ImagePath { get; set; }
}
}

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DTO
{
public class QuestionDTO
{
public int Id { get; set; }
public string Question { get; set; }
public string AnswerA { get; set; }
public string AnswerB { get; set; }
public string AnswerC { get; set; }
public string AnswerD { get; set; }
public string CorrectAnswer { get; set; }
}
}

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DTO
{
public class QuizDTO
{
public int Id { get; set; }
public int NbQuestion { get; set; }
public string ImagePath { get; set; }
public string Title { get; set; }
}
}

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DTO
{
public class QuizQuestionDTO
{
public int IdQuestion { get; set; }
public int IdQuiz { get; set; }
}
}

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DTO
{
public class QuoteDTO
{
public int Id { get; set; }
public string Content { get; set; }
public string Character { get; set; }
public string ImagePath { get; set; }
public string TitleSource { get; set; }
public int DateSource { get; set; }
public int Like { get; set; }
public TypeLangageDTO Langage { get; set; }
public TypeSrcEnumDTO Type { get; set; }
public Boolean IsValide { get; set; }
}
}

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DTO
{
public class SourceDTO
{
public int Id { get; set; }
public string Title { get; set; }
public int Date { get; set; }
public TypeSrcEnumDTO Type { get; set; }
}
}

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DTO
{
public enum TypeLangageDTO
{
vo,
vf
}
}

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DTO
{
public enum TypeSrcEnumDTO
{
movie,
serie,
book,
videogame
}
}

@ -0,0 +1,13 @@
namespace DTO
{
public class UserDTO
{
public int Id { get; set; }
public string Pseudo { get; set; }
public string Password { get; set; }
public string Email { get; set; }
public DateTime date { get; set; }
public TypeLangageDTO Lang { get; set; }
public string ImageProfil { get; set; }
}
}

@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.3" />
<PackageReference Include="NSwag.Core" Version="14.3.0" />
<PackageReference Include="NSwag.Core.Yaml" Version="14.3.0" />
<PackageReference Include="NSwag.Generation.AspNetCore" Version="14.3.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DTO\DTO.csproj" />
<ProjectReference Include="..\Entity\Entity.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,505 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Entity;
using DTO;
using System.Reflection.Metadata;
namespace Dto2Entities
{
public static class Extention
{
// --------------------------- ToDto --------------------------- \\
public static CharacterDTO ToDto(this Character item)
{
if (item == null) return null;
CharacterDTO character = new CharacterDTO();
character.Id = item.Id;
character.Name = item.Name;
character.imagePath = item.Images.ImgPath;
return character;
}
public static List<CharacterDTO> ToDto(this List<Character> item)
{
List<CharacterDTO> characterDTOs = new List<CharacterDTO>();
foreach (Character character in item)
{
characterDTOs.Add(character.ToDto());
}
return characterDTOs;
}
public static CommentaryDTO ToDto(this Commentary item)
{
if (item == null) return null;
CommentaryDTO commentary = new CommentaryDTO();
commentary.Id = item.Id;
commentary.Date = item.DateCommentary;
commentary.Comment = item.Comment;
commentary.User = item.User.UserName;
commentary.ImagePath = item.User.Images.ImgPath;
return commentary;
}
public static List<CommentaryDTO> ToDto(this List<Commentary> item)
{
List<CommentaryDTO> commentaryDTOs = new List<CommentaryDTO>();
foreach (Commentary commentary in item)
{
commentaryDTOs.Add(commentary.ToDto());
}
return commentaryDTOs;
}
// Surement a refaire car Faoirite Entity modifier sur branche EF
public static FavoriteDTO ToDto(this Favorite item)
{
if (item == null) return null;
FavoriteDTO favorite = new FavoriteDTO();
favorite.IdUser = item.IdUsers;
favorite.IdQuote = item.IdQuote;
return favorite;
}
public static List<FavoriteDTO> ToDto(this List<Favorite> item)
{
List<FavoriteDTO> favoriteDTOs = new List<FavoriteDTO>();
foreach (Favorite favorite in item)
{
favoriteDTOs.Add(favorite.ToDto());
}
return favoriteDTOs;
}
public static ImageDTO ToDto(this Images item)
{
if (item == null) return null;
ImageDTO image = new ImageDTO();
image.IdImage = item.Id;
image.ImagePath = item.ImgPath;
return image;
}
public static List<ImageDTO> ToDto(this List<Images> item)
{
List<ImageDTO> imageDTOs = new List<ImageDTO>();
foreach (Images images in item)
{
imageDTOs.Add(images.ToDto());
}
return imageDTOs;
}
public static QuestionDTO ToDto(this Question item)
{
if (item == null) return null;
QuestionDTO question = new QuestionDTO();
question.Id = item.Id;
question.Question = item.Text;
question.AnswerA = item.AnswerA;
question.AnswerB = item.AnswerB;
question.AnswerC = item.AnswerC;
question.AnswerD = item.AnswerD;
question.CorrectAnswer = item.CorrectAnswer;
return question;
}
public static List<QuestionDTO> ToDto(this List<Question> item)
{
List<QuestionDTO> questionDTOs = new List<QuestionDTO>();
foreach (Question question in item)
{
questionDTOs.Add(question.ToDto());
}
return questionDTOs;
}
public static QuizDTO ToDto(this Quiz item)
{
if (item == null) return null;
QuizDTO quiz = new QuizDTO();
quiz.Id = item.Id;
quiz.NbQuestion = item.NbQuestion;
quiz.Title = item.Title;
quiz.ImagePath = item.Images.ImgPath;
return quiz;
}
public static List<QuizDTO> ToDto(this List<Quiz> item)
{
List<QuizDTO> quizDTOs = new List<QuizDTO>();
foreach (Quiz quiz in item)
{
quizDTOs.Add(quiz.ToDto());
}
return quizDTOs;
}
// Surement a refaire car QuizQuestion Entity modifier sur branche EF
public static QuizQuestionDTO ToDto(this QuizQuestion item)
{
if (item == null) return null;
QuizQuestionDTO quizQuestion = new QuizQuestionDTO();
quizQuestion.IdQuiz = item.IdQuiz;
quizQuestion.IdQuestion = item.IdQuestion;
return quizQuestion;
}
public static List<QuizQuestionDTO> ToDto(this List<QuizQuestion> item)
{
List<QuizQuestionDTO> quizQuestionDTOs = new List<QuizQuestionDTO>();
foreach (QuizQuestion quizQuestion in item)
{
quizQuestionDTOs.Add(quizQuestion.ToDto());
}
return quizQuestionDTOs;
}
public static QuoteDTO ToDto(this Quote item)
{
if (item == null) return null;
QuoteDTO quote = new QuoteDTO();
quote.Id = item.Id;
quote.Content = item.Content;
quote.DateSource = item.Source.Year;
quote.Character = item.Character.Name;
quote.TitleSource = item.Source.Title;
quote.Langage = item.Langage.ToDto();
quote.ImagePath = item.Character.Images.ImgPath;
quote.Like = item.Likes;
quote.Type = item.Source.TypeSrc.ToDto();
quote.IsValide = item.IsValid;
return quote;
}
public static List<QuoteDTO> ToDto(this List<Quote> item)
{
List<QuoteDTO> quoteDTOs = new List<QuoteDTO>();
foreach (Quote quote in item)
{
quoteDTOs.Add(quote.ToDto());
}
return quoteDTOs;
}
public static SourceDTO ToDto(this Source item)
{
if (item == null) return null;
SourceDTO source = new SourceDTO();
source.Id = item.Id;
source.Date = item.Year;
source.Title = item.Title;
source.Type = item.TypeSrc.ToDto();
return source;
}
public static List<SourceDTO> ToDto(this List<Source> item)
{
List<SourceDTO> sourceDTOs = new List<SourceDTO>();
foreach (Source source in item)
{
sourceDTOs.Add(source.ToDto());
}
return sourceDTOs;
}
public static UserDTO ToDto(this Users item)
{
if (item == null) return null;
UserDTO user = new UserDTO();
user.Id = item.Id;
user.Pseudo = item.UserName;
user.Password = item.Password;
user.Email = item.Email;
user.date = item.Created;
user.ImageProfil = item.Images.ImgPath;
user.Lang = item.Lang.ToDto();
return user;
}
public static List<UserDTO> ToDto(this List<Users> item)
{
List<UserDTO> users = new List<UserDTO>();
foreach (Users user in item)
{
users.Add(user.ToDto());
}
return users;
}
public static TypeLangageDTO ToDto(this LangEnum item)
{
switch (item)
{
case LangEnum.vf: return TypeLangageDTO.vf;
case LangEnum.vo: return TypeLangageDTO.vo;
default: return TypeLangageDTO.vo;
}
}
public static TypeSrcEnumDTO ToDto(this TypeSrcEnum item)
{
switch (item)
{
case TypeSrcEnum.movie: return TypeSrcEnumDTO.movie;
case TypeSrcEnum.book: return TypeSrcEnumDTO.book;
case TypeSrcEnum.series: return TypeSrcEnumDTO.serie;
case TypeSrcEnum.videogame: return TypeSrcEnumDTO.videogame;
default: return TypeSrcEnumDTO.movie;
}
}
// --------------------------- ToEntity --------------------------- \\
public static Character ToEntity(this CharacterDTO item)
{
if (item == null) return null;
Character character = new Character();
character.Id = item.Id;
character.Name = item.Name;
character.Images = new Images();
character.Images.ImgPath = item.imagePath ;
return character;
}
public static List<Character> ToEntity(this List<CharacterDTO> item)
{
List<Character> characters = new List<Character>();
foreach (CharacterDTO character in item)
{
characters.Add(character.ToEntity());
}
return characters;
}
public static Commentary ToEntity(this CommentaryDTO item)
{
if (item == null) return null;
Commentary commentary = new Commentary();
commentary.Id = item.Id;
commentary.DateCommentary = item.Date;
commentary.Comment = item.Comment;
commentary.User = new Users();
commentary.User.UserName = item.User;
commentary.User.Images = new Images();
commentary.User.Images.ImgPath = item.ImagePath;
return commentary;
}
public static List<Commentary> ToEntity(this List<CommentaryDTO> item)
{
List<Commentary> commentarys = new List<Commentary>();
foreach (CommentaryDTO commentary in item)
{
commentarys.Add(commentary.ToEntity());
}
return commentarys;
}
// Surement a refaire car Faoirite Entity modifier sur branche EF
public static Favorite ToEntity(this FavoriteDTO item)
{
if (item == null) return null;
Favorite favorite = new Favorite();
favorite.IdUsers = item.IdUser;
favorite.IdQuote = item.IdQuote;
return favorite;
}
public static List<Favorite> ToEntity(this List<FavoriteDTO> item)
{
List<Favorite> favorites = new List<Favorite>();
foreach (FavoriteDTO favorite in item)
{
favorites.Add(favorite.ToEntity());
}
return favorites;
}
public static Images ToEntity(this ImageDTO item)
{
if (item == null) return null;
Images image = new Images();
image.Id = item.IdImage;
image.ImgPath = item.ImagePath;
return image;
}
public static List<Images> ToEntity(this List<ImageDTO> item)
{
List<Images> images = new List<Images>();
foreach (ImageDTO image in item)
{
images.Add(image.ToEntity());
}
return images;
}
public static Question ToEntity(this QuestionDTO item)
{
if (item == null) return null;
Question question = new Question();
question.Id = item.Id;
question.Text = item.Question;
question.AnswerA = item.AnswerA;
question.AnswerB = item.AnswerB;
question.AnswerC = item.AnswerC;
question.AnswerD = item.AnswerD;
question.CorrectAnswer = item.CorrectAnswer;
return question;
}
public static List<Question> ToEntity(this List<QuestionDTO> item)
{
List<Question> questions = new List<Question>();
foreach (QuestionDTO question in item)
{
questions.Add(question.ToEntity());
}
return questions;
}
public static Quiz ToEntity(this QuizDTO item)
{
if (item == null) return null;
Quiz quiz = new Quiz();
quiz.Id = item.Id;
quiz.NbQuestion = item.NbQuestion;
quiz.Title = item.Title;
quiz.Images.ImgPath = item.ImagePath;
return quiz;
}
public static List<Quiz> ToEntity(this List<QuizDTO> item)
{
List<Quiz> quizs = new List<Quiz>();
foreach (QuizDTO quiz in item)
{
quizs.Add(quiz.ToEntity());
}
return quizs;
}
// Surement a refaire car QuizQuestion Entity modifier sur branche EF
public static QuizQuestion ToEntity(this QuizQuestionDTO item)
{
if (item == null) return null;
QuizQuestion quizQuestion = new QuizQuestion();
quizQuestion.IdQuiz = item.IdQuiz;
quizQuestion.IdQuestion = item.IdQuestion;
return quizQuestion;
}
public static List<QuizQuestion> ToEntity(this List<QuizQuestionDTO> item)
{
List<QuizQuestion> quizQuestions = new List<QuizQuestion>();
foreach (QuizQuestionDTO quizQuestion in item)
{
quizQuestions.Add(quizQuestion.ToEntity());
}
return quizQuestions;
}
public static Quote ToEntity(this QuoteDTO item)
{
if (item == null) return null;
Quote quote = new Quote();
quote.Id = item.Id;
quote.Content = item.Content;
quote.Source = new Source();
quote.Source.Year = item.DateSource;
quote.Character = new Character();
quote.Character.Name = item.Character;
quote.Source.Title = item.TitleSource;
quote.Langage = item.Langage.ToEntity();
quote.Character.Images = new Images();
quote.Character.Images.ImgPath = item.ImagePath;
quote.Likes = item.Like;
quote.Source.TypeSrc = item.Type.ToEntity();
quote.IsValid = item.IsValide;
return quote;
}
public static List<Quote> ToEntity(this List<QuoteDTO> item)
{
List<Quote> quotes = new List<Quote>();
foreach (QuoteDTO quote in item)
{
quotes.Add(quote.ToEntity());
}
return quotes;
}
public static Source ToEntity(this SourceDTO item)
{
if (item == null) return null;
Source source = new Source();
source.Id = item.Id;
source.Year = item.Date;
source.Title = item.Title;
source.TypeSrc = item.Type.ToEntity();
return source;
}
public static List<Source> ToEntity(this List<SourceDTO> item)
{
List<Source> sources = new List<Source>();
foreach (SourceDTO source in item)
{
sources.Add(source.ToEntity());
}
return sources;
}
public static Users ToEntity(this UserDTO item)
{
if (item == null) return null;
Users user = new Users();
user.Id = item.Id;
user.UserName = item.Pseudo;
user.Password = item.Password;
user.Email = item.Email;
user.Created = item.date;
user.Images = new Images();
user.Images.ImgPath = item.ImageProfil;
user.Lang = item.Lang.ToEntity();
return user;
}
public static List<Users> ToEntity(this List<UserDTO> item)
{
List<Users> users = new List<Users>();
foreach (UserDTO user in item)
{
users.Add(user.ToEntity());
}
return users;
}
public static LangEnum ToEntity(this TypeLangageDTO item)
{
switch (item)
{
case TypeLangageDTO.vf: return LangEnum.vf;
case TypeLangageDTO.vo: return LangEnum.vo;
default: return LangEnum.vo;
}
}
public static TypeSrcEnum ToEntity(this TypeSrcEnumDTO item)
{
switch (item)
{
case TypeSrcEnumDTO.movie: return TypeSrcEnum.movie;
case TypeSrcEnumDTO.book: return TypeSrcEnum.book;
case TypeSrcEnumDTO.serie: return TypeSrcEnum.series;
case TypeSrcEnumDTO.videogame: return TypeSrcEnum.videogame;
default: return TypeSrcEnum.movie;
}
}
}
}

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entity
{
public class Admin
{
[Key]
[ForeignKey(nameof(Users))]
public int IdUsers { get; set; }
public Users User { get; set; } = null!;
}
}

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entity
{
public class Character
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
[StringLength(50)]
public string Name { get; set; }
[ForeignKey(nameof(Images))]
public int IdImage { get; set; }
public Images Images { get; set; } = null!;
public ICollection<Quote> Quotes { get; set; } = new List<Quote>();
}
}

@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entity
{
public class Commentary
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
[ForeignKey(nameof(Users))]
public int IdUser { get; set; }
[Required]
[ForeignKey(nameof(Quote))]
public int IdQuote { get; set; }
[Required]
[Column("DateCommentary", TypeName = "date")]
public DateTime DateCommentary { get; set; }
[Required]
[MaxLength(100)]
public string Comment { get; set; }
public Quote Quote { get; set; } = null!;
public Users User { get; set; } = null!;
}
}

@ -6,4 +6,15 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.3" />
<PackageReference Include="NSwag.Core" Version="14.3.0" />
<PackageReference Include="NSwag.Core.Yaml" Version="14.3.0" />
<PackageReference Include="NSwag.Generation.AspNetCore" Version="14.3.0" />
</ItemGroup>
</Project> </Project>

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entity
{
public class Favorite
{
public int IdUsers { get; set; }
public Users Users { get; set; }
public int IdQuote { get; set; }
public Quote Quote { get; set; }
}
}

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entity
{
public class Images
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
public string ImgPath { get; set; }
public ICollection<Character> Characters { get; set; } = new List<Character>();
public ICollection<Users> Users { get; set; } = new List<Users>();
public ICollection<Quiz> Quizs { get; set; } = new List<Quiz>();
}
}

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entity
{
public enum LangEnum
{
vo,
vf
}
}

@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entity
{
public class Question
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
[StringLength(200)]
public string Text { get; set; }
[Required]
[StringLength(50)]
public string AnswerA { get; set; }
[Required]
[StringLength(50)]
public string AnswerB { get; set; }
[Required]
[StringLength(50)]
public string AnswerC { get; set; }
[Required]
[StringLength(50)]
public string AnswerD { get; set; }
[Required]
[StringLength(1)]
public string CorrectAnswer { get; set; }
[Required]
public bool IsValid { get; set; }
public ICollection<Quiz> Quizs { get; set; } = new List<Quiz>();
}
}

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entity
{
public class Quiz
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
[StringLength(50)]
public string Title { get; set; }
[Required]
[ForeignKey(nameof(Images))]
public int IdImage { get; set; }
[Required]
public int NbQuestion { get; set; }
public Images Images { get; set; } = null!;
public ICollection<Question> Questions { get; } = new List<Question>();
}
}

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entity
{
public class QuizQuestion
{
public int IdQuiz { get; set; }
public int IdQuestion { get; set; }
}
}

@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entity
{
public class Quote
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
[StringLength(100)]
public string Content { get; set; }
[Required]
public int Likes { get; set; }
[Required]
public LangEnum Langage { get; set; }
[Required]
public bool IsValid { get; set; }
[Required]
[ForeignKey(nameof(Character))]
public int IdCharacter { get; set; }
[Required]
[ForeignKey(nameof(Source))]
public int IdSource { get; set; }
[ForeignKey(nameof(Users))]
public int? IdUsersPropose { get; set; }
//Réson de pour quoi j'ai mis le user en nullable et mis .OnDelete(DeleteBehavior.ClientSetNull) dans WTFContext
//https://learn.microsoft.com/fr-fr/ef/core/saving/cascade-delete
//Les suppressions en cascade sont nécessaires quand une entité dépendante/enfant ne peut plus être associée à son entité principale/parente actuelle. Cela peut se produire à la suite de la suppression de lentité principale/parente, ou quand lentité principale/parente existe toujours mais que lentité dépendante/enfant ne lui est plus associée.
public Users? User { get; set; } = null!;
public Source Source { get; set; } = null!;
public Character Character { get; set; } = null!;
public ICollection<Commentary> Commentarys { get; set; } = new List<Commentary>();
public ICollection<Users> Favorite { get; } = new List<Users>();
}
}

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entity
{
public class Source
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
[StringLength(100)]
public string Title { get; set; }
[Required]
public int Year { get; set; }
[Required]
public TypeSrcEnum TypeSrc { get; set; }
public ICollection<Quote> Quotes { get; set; } = new List<Quote>();
}
}

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entity
{
public enum TypeSrcEnum
{
movie,
series,
book,
videogame
}
}

@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entity
{
public class Users
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
[StringLength(50)]
public string UserName { get; set; }
[Required]
public LangEnum Lang { get; set; } = LangEnum.vo;
[Required]
[StringLength(50)]
public string Email { get; set; }
[Required]
[StringLength(200)]
public string Password { get; set; }
[ForeignKey(nameof(Images))]
public int IdImage { get; set; }
[Required]
[Column("Created", TypeName = "date")]
public DateTime Created { get; set; }
public Images Images { get; set; }
public ICollection<Quote> Quotes { get; set; } = new List<Quote>();
public ICollection<Quote> Favorite { get; set; } = new List<Quote>();
//[ForeignKey(nameof(Admin))]
//public int Idadmin { get; set; }
//public Admin admin { get; set; }
}
}

@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DTO;
using Entity;
using Shared;
using Dto2Entities;
namespace ServicesApi
{
public class CharacterService : ICharacterService<CharacterDTO>
{
private ICharacterService<Character> characterService;
public CharacterService(ICharacterService<Character> character)
{
characterService = character;
}
public async Task AddCharacter(CharacterDTO character)
{
await characterService.AddCharacter(character.ToEntity());
}
public async Task<PaginationResult<CharacterDTO>> GetAll()
{
var characters = characterService.GetAll().Result.items;
return new PaginationResult<CharacterDTO>(characters.Count(), 0, 10, characters.ToDto());
}
public async Task<CharacterDTO> GetCharById(int id)
{
return (await characterService.GetCharById(id)).ToDto();
}
public async Task<CharacterDTO> GetCharByName(string name)
{
return characterService.GetCharByName(name).Result.ToDto();
}
public async Task<int> GetLastCharId()
{
return await characterService.GetLastCharId();
}
public async Task<PaginationResult<CharacterDTO>> GetSomeChar(int page, int count)
{
var characters = (await characterService.GetSomeChar(page, count)).items;
return new PaginationResult<CharacterDTO>(characters.Count(), page, count, characters.ToDto());
}
public async Task RemoveCharacter(int id)
{
await characterService.RemoveCharacter(id);
}
public async Task UpdateCharacter(int id, CharacterDTO character)
{
await characterService.UpdateCharacter(id, character.ToEntity());
}
}
}

@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DTO;
using Entity;
using Shared;
using Dto2Entities;
namespace ServicesApi
{
public class CommentaryService : ICommentaryService<CommentaryDTO>
{
private ICommentaryService<Commentary> commentaryService;
public CommentaryService(ICommentaryService<Commentary> commentary)
{
commentaryService = commentary;
}
public async Task AddComment(CommentaryDTO commentary, int idQuote)
{
await commentaryService.AddComment(commentary.ToEntity(), idQuote);
}
public async Task DeleteCommentaryForQuote(int quoteId)
{
await commentaryService.DeleteCommentaryForQuote(quoteId);
}
public async Task DeleteCommentaryForUser(int userId)
{
await commentaryService.DeleteCommentaryForUser(userId);
}
public async Task<PaginationResult<CommentaryDTO>> GetAllCommentary()
{
var commentaries = commentaryService.GetAllCommentary().Result.items;
return new PaginationResult<CommentaryDTO>(commentaries.Count(), 0, 10, commentaries.ToDto());
}
public async Task<CommentaryDTO> GetCommentaryById(int id)
{
try
{
return (await commentaryService.GetCommentaryById(id)).ToDto();
}
catch(KeyNotFoundException)
{
throw new KeyNotFoundException($"No comments found with the given ID: {id}.");
}
}
public async Task<PaginationResult<CommentaryDTO>> GetCommentaryByQuote(int quoteId, int index, int pageSize)
{
var commentaries = commentaryService.GetCommentaryByQuote(quoteId,index,pageSize).Result.items;
return new PaginationResult<CommentaryDTO>(commentaries.Count(), 0, 10, commentaries.ToDto());
}
public async Task<PaginationResult<CommentaryDTO>> GetCommentaryByUser(int userId, int index, int pageSize)
{
var commentaries = commentaryService.GetCommentaryByUser(userId, index,pageSize).Result.items;
return new PaginationResult<CommentaryDTO>(commentaries.Count(), 0, 10, commentaries.ToDto());
}
public async Task<int> LastCommentaryId()
{
return await commentaryService.LastCommentaryId();
}
public async Task RemoveCommentary(int id)
{
await commentaryService.RemoveCommentary(id);
}
public async Task UpdateCommentary(int id, CommentaryDTO commentary)
{
await commentaryService.UpdateCommentary(id,commentary.ToEntity());
}
}
}

@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DTO;
using Entity;
using Shared;
using Dto2Entities;
using static System.Net.Mime.MediaTypeNames;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace ServicesApi
{
public class FavoriteService : IFavoriteService<QuoteDTO>
{
private IFavoriteService<Quote> favoriteService;
public FavoriteService(IFavoriteService<Quote> favorite)
{
favoriteService = favorite;
}
public async Task AddFavorite(int quoteid, int userId)
{
await favoriteService.AddFavorite(quoteid, userId);
}
public async Task RemoveAllFavoriteForQuote(int quoteId)
{
await favoriteService.RemoveAllFavoriteForQuote(quoteId);
}
public async Task RemoveAllFavoriteForUser(int userId)
{
await favoriteService.RemoveAllFavoriteForUser(userId);
}
public async Task RemoveFavorite(int quoteid, int userId)
{
await favoriteService.RemoveFavorite(quoteid, userId);
}
public async Task<QuoteDTO?> GetFavorite(int userId, int idQuote)
{
return (await favoriteService.GetFavorite(userId,idQuote) ).ToDto();
}
public async Task<PaginationResult<QuoteDTO>> GetFavoriteByIdUser(int userId, int index, int count)
{
var fav = (await favoriteService.GetFavoriteByIdUser(userId, index, count)).items;
return new PaginationResult<QuoteDTO>(fav.Count(), 0, 10, fav.ToDto());
}
}
}

@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DTO;
using Entity;
using Shared;
using Dto2Entities;
using static System.Net.Mime.MediaTypeNames;
namespace ServicesApi
{
public class ImageService : IImagesService<ImageDTO>
{
private IImagesService<Images> imageService;
public ImageService(IImagesService<Images> image)
{
imageService = image;
}
public async Task AddImage(ImageDTO image)
{
await imageService.AddImage(image.ToEntity());
}
public async Task<PaginationResult<ImageDTO>> GetAllImage()
{
var images = imageService.GetAllImage().Result.items;
return new PaginationResult<ImageDTO>(images.Count(), 0, 10, images.ToDto());
}
public async Task<ImageDTO> GetImageById(int id)
{
var image = await imageService.GetImageById(id);
if (image == null)
{
throw new KeyNotFoundException($"No image with the id {id}");
}
return image.ToDto();
}
public async Task<ImageDTO?> GetImageByPath(string path)
{
var image = await imageService.GetImageByPath(path);
if (image == null)
{
return null;
}
return image.ToDto();
}
public async Task<int> GetLastImageId()
{
return await imageService.GetLastImageId();
}
public async Task<PaginationResult<ImageDTO>> GetSomeImage(int index, int pageSize)
{
var images = imageService.GetSomeImage(index,pageSize).Result.items;
return new PaginationResult<ImageDTO>(images.Count(), 0, 10, images.ToDto());
}
public async Task RemoveImage(int id)
{
await imageService.RemoveImage(id);
}
public async Task UpdateImage(int id, ImageDTO image)
{
await imageService.UpdateImage(id, image.ToEntity());
}
}
}

@ -0,0 +1,89 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DTO;
using Entity;
using Shared;
using Dto2Entities;
using static System.Net.Mime.MediaTypeNames;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
namespace ServicesApi
{
public class QuestionService : IQuestionService<QuestionDTO>
{
private IQuestionService<Question> questionService;
public QuestionService(IQuestionService<Question> question)
{
questionService = question;
}
public async Task AddQuestion(QuestionDTO question)
{
await questionService.AddQuestion(question.ToEntity());
}
public async Task<int> CountQuestions()
{
return await questionService.CountQuestions();
}
public async Task<PaginationResult<QuestionDTO>> GetAllQuestion()
{
var questions = questionService.GetAllQuestion().Result.items;
return new PaginationResult<QuestionDTO>(questions.Count(), 0, 10, questions.ToDto());
}
public async Task<PaginationResult<QuestionDTO>> GetInvalidQuestion(int index, int pageSize)
{
var questions = questionService.GetInvalidQuestion(index,pageSize).Result.items;
return new PaginationResult<QuestionDTO>(questions.Count(), 0, 10, questions.ToDto());
}
public async Task<QuestionDTO> GetQuestionById(int id)
{
return questionService.GetQuestionById(id).Result.ToDto();
}
public async Task<QuestionDTO> GetRandomQuestion()
{
return questionService.GetRandomQuestion().Result.ToDto();
}
public async Task<QuestionDTO> GetRandomQuestionQuoteToCharacter()
{
return questionService.GetRandomQuestionQuoteToCharacter().Result.ToDto();
}
public async Task<QuestionDTO> GetRandomQuestionQuoteToSource()
{
return questionService.GetRandomQuestionQuoteToSource().Result.ToDto();
}
public async Task<PaginationResult<QuestionDTO>> GetSomeQuestion(int index, int pageSize)
{
var questions = questionService.GetSomeQuestion(index, pageSize).Result.items;
return new PaginationResult<QuestionDTO>(questions.Count(), 0, 10, questions.ToDto());
}
public async Task RemoveQuestion(int id)
{
await questionService.RemoveQuestion(id);
}
public async Task UpdateQuestion(int id, QuestionDTO question)
{
await questionService.UpdateQuestion(id, question.ToEntity());
}
public async Task ValidateQuestion(int id, bool isvalid)
{
await questionService.ValidateQuestion(id, isvalid);
}
}
}

@ -0,0 +1,126 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Metadata;
using System.Text;
using System.Threading.Tasks;
using DTO;
using Dto2Entities;
using Entity;
using Shared;
namespace ServicesApi
{
public class QuoteService : IQuoteService<QuoteDTO>
{
private IQuoteService<Quote> quoteService;
public QuoteService(IQuoteService<Quote> quote)
{
quoteService = quote;
}
public async Task<QuoteDTO> AddQuote(QuoteDTO quote)
{
return (await quoteService.AddQuote(quote.ToEntity())).ToDto();
}
public async Task<PaginationResult<QuoteDTO>> GetAllQuote()
{
var quotes = quoteService.GetAllQuote().Result.items;
return new PaginationResult<QuoteDTO>(quotes.Count(), 0, quotes.Count(), quotes.ToDto());
}
public async Task<PaginationResult<QuoteDTO>> GetAllQuoteLang(int index, int pageSize, int lang)
{
var quotes = quoteService.GetAllQuoteLang(index, pageSize,lang).Result.items;
return new PaginationResult<QuoteDTO>(quotes.Count(), index, pageSize, quotes.ToDto());
}
public async Task<QuoteDTO> GetDailyQuote(DateOnly date, int lang)
{
return quoteService.GetDailyQuote(date, lang).Result.ToDto();
}
public async Task<PaginationResult<QuoteDTO>> GetFavorites(int index, int pageSize, int UserId)
{
var quotes = quoteService.GetFavorites(index, pageSize, UserId).Result.items;
return new PaginationResult<QuoteDTO>(quotes.Count(), index, pageSize, quotes.ToDto());
}
public async Task<PaginationResult<QuoteDTO>> GetInvalidQuote(int index, int pageSize, int lang)
{
var quotes = quoteService.GetInvalidQuote(index, pageSize, lang).Result.items;
return new PaginationResult<QuoteDTO>(quotes.Count(), index, pageSize, quotes.ToDto());
}
public async Task<PaginationResult<QuoteDTO>> GetInvalidQuote(int index, int pageSize)
{
var quotes = quoteService.GetInvalidQuote(index, pageSize).Result.items;
return new PaginationResult<QuoteDTO>(quotes.Count(), index, pageSize, quotes.ToDto());
}
public async Task<int> GetLastQuoteId()
{
return await quoteService.GetLastQuoteId();
}
public async Task<QuoteDTO?> GetQuoteById(int id)
{
var quote= quoteService.GetQuoteById(id).Result;
if (quote != null) return quote.ToDto();
else return null;
}
public async Task<PaginationResult<QuoteDTO>> GetSomeQuote(int index, int pageSize)
{
var quotes = quoteService.GetSomeQuote(index, pageSize).Result.items;
return new PaginationResult<QuoteDTO>(quotes.Count(), index, pageSize, quotes.ToDto());
}
public async Task<PaginationResult<QuoteDTO>> GetSuggestions(int index, int pageSize, int lang)
{
var quotes = quoteService.GetSuggestions(index, pageSize, lang).Result.items;
return new PaginationResult<QuoteDTO>(quotes.Count(), index, pageSize, quotes.ToDto());
}
public async Task<PaginationResult<QuoteDTO>> GetValidQuote(int index, int pageSize)
{
var quotes = quoteService.GetValidQuote(index, pageSize).Result.items;
return new PaginationResult<QuoteDTO>(quotes.Count(), index, pageSize, quotes.ToDto());
}
public async Task RemoveQuote(int quoteId)
{
await quoteService.RemoveQuote(quoteId);
}
public async Task<PaginationResult<QuoteDTO>> SearchByCharacter(string character, int index, int pageSize, int lang)
{
var quotes = quoteService.SearchByCharacter(character, index, pageSize, lang).Result.items;
return new PaginationResult<QuoteDTO>(quotes.Count(), index, pageSize, quotes.ToDto());
}
public async Task<PaginationResult<QuoteDTO>> SearchByContent(string content, int index, int pageSize, int lang)
{
var quotes = quoteService.SearchByContent(content, index, pageSize, lang).Result.items;
return new PaginationResult<QuoteDTO>(quotes.Count(), index, pageSize, quotes.ToDto());
}
public async Task<PaginationResult<QuoteDTO>> SearchBySource(string source, int index, int pageSize, int lang)
{
var quotes = quoteService.SearchBySource(source, index, pageSize, lang).Result.items;
return new PaginationResult<QuoteDTO>(quotes.Count(), index, pageSize, quotes.ToDto());
}
public async Task UpdateQuote(int quoteId, QuoteDTO quote)
{
await quoteService.UpdateQuote(quoteId, quote.ToEntity());
}
public async Task ValidateQuote(int quoteId, bool isValidate)
{
await quoteService.ValidateQuote(quoteId, isValidate);
}
}
}

@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.3" />
<PackageReference Include="NSwag.Core" Version="14.3.0" />
<PackageReference Include="NSwag.Core.Yaml" Version="14.3.0" />
<PackageReference Include="NSwag.Generation.AspNetCore" Version="14.3.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Contextlib\Contextlib.csproj" />
<ProjectReference Include="..\Dto2Entities\Dto2Entities.csproj" />
<ProjectReference Include="..\DTO\DTO.csproj" />
<ProjectReference Include="..\Shared\Shared.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DTO;
using Entity;
using Shared;
using Dto2Entities;
using static System.Net.Mime.MediaTypeNames;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace ServicesApi
{
public class SourceService : ISourceService<SourceDTO>
{
private ISourceService<Source> srcService;
public SourceService(ISourceService<Source> src)
{
srcService = src;
}
public async Task AddSource(SourceDTO source)
{
await srcService.AddSource(source.ToEntity());
}
public async Task<PaginationResult<SourceDTO>> GetAll()
{
var sources = srcService.GetAll().Result.items;
return new PaginationResult<SourceDTO>(sources.Count(), 0, 10, sources.ToDto());
}
public async Task<int> GetLastSourceId()
{
return await srcService.GetLastSourceId();
}
public async Task<PaginationResult<SourceDTO>> GetSomesSource(int page, int count)
{
var sources = (await srcService.GetSomesSource(page, count)).items;
return new PaginationResult<SourceDTO>(sources.Count(), page, count, sources.ToDto());
}
public async Task<PaginationResult<SourceDTO>> GetSourceByDate(int date)
{
var sources = (await srcService.GetSourceByDate(date)).items;
return new PaginationResult<SourceDTO>(sources.Count(), 0, 10, sources.ToDto());
}
public async Task<SourceDTO> GetSourceById(int id)
{
return (await srcService.GetSourceById(id)).ToDto();
}
public async Task<SourceDTO> GetSourceByTitle(string title)
{
return srcService.GetSourceByTitle(title).Result.ToDto();
}
public async Task<SourceDTO> GetSourceByType(int type)
{
return srcService.GetSourceByType(type).Result.ToDto();
}
public async Task RemoveSource(int id)
{
await srcService.RemoveSource(id);
}
public async Task UpdateSource(int id, SourceDTO source)
{
await srcService.UpdateSource(id, source.ToEntity());
}
}
}

@ -0,0 +1,100 @@
using Shared;
using DTO;
using Contextlib;
using Entity;
using System.Xml.XPath;
using Dto2Entities;
namespace ServicesApi
{
public class UserService : IUserService<UserDTO>
{
private IUserService<Users> userService;
public UserService(IUserService<Users> user)
{
userService = user;
}
public async Task AddUser(UserDTO user)
{
await userService.AddUser(user.ToEntity());
}
public async Task<int> CountUser()
{
return await userService.CountUser();
}
public async Task<bool> ExistEmail(string email)
{
return await userService.ExistEmail(email);
}
public async Task<bool> ExistUsername(string username)
{
return await userService.ExistUsername(username);
}
public async Task<PaginationResult<UserDTO>> GetAllUser()
{
var users = userService.GetAllUser().Result.items;
return new PaginationResult<UserDTO>(users.Count(), 0, 10, users.ToDto());
}
public async Task<string> GetHashPassword(string username)
{
return await userService.GetHashPassword(username);
}
public async Task<int> GetLastUserId()
{
return await userService.GetLastUserId();
}
public async Task<PaginationResult<UserDTO>> GetSomeUser(int index, int pageSize)
{
var users = userService.GetSomeUser(index, pageSize).Result.items;
return new PaginationResult<UserDTO>(users.Count(),index, pageSize, users.ToDto());
}
public async Task<UserDTO> GetUserByEmail(string email)
{
return userService.GetUserByEmail(email).Result.ToDto();
}
public async Task<UserDTO> GetUserById(int id)
{
try
{
return (await userService.GetUserById(id)).ToDto();
}
catch(KeyNotFoundException e)
{
throw new KeyNotFoundException(e.Message);
}
}
public async Task<UserDTO> GetUserByUsername(string username)
{
return userService.GetUserByUsername(username).Result.ToDto();
}
public async Task RemoveUser(int id)
{
await userService.RemoveUser(id);
}
public async Task SetAdminRole(bool isAdmin)
{
await userService.SetAdminRole(isAdmin);
}
public async Task<UserDTO> UpdateUser(int userId, UserDTO user)
{
return userService.UpdateUser(userId, user.ToEntity()).Result.ToDto();
}
}
}

@ -35,5 +35,7 @@ namespace Shared
// Retrieves the unique identifier of the last added character. // Retrieves the unique identifier of the last added character.
Task<int> GetLastCharId(); Task<int> GetLastCharId();
Task<PaginationResult<TChar>> GetSomeChar(int page, int count);
} }
} }

@ -6,49 +6,49 @@ using System.Threading.Tasks;
namespace Shared namespace Shared
{ {
public interface ICommentService<TComment> public interface ICommentaryService<TComment>
{ {
// Retrieves a comment by its unique identifier (id). // Retrieves a comment by its unique identifier (id).
// 'id' is the unique identifier of the comment. // 'id' is the unique identifier of the comment.
Task<TComment> GetCommentById(int id); Task<TComment> GetCommentaryById(int id);
// Retrieves comments related to a specific quote, with pagination. // Retrieves comments related to a specific quote, with pagination.
// 'quoteId' is the unique identifier of the quote. // 'quoteId' is the unique identifier of the quote.
// 'index' is the page number (for pagination). // 'index' is the page number (for pagination).
// 'pageSize' is the number of comments per page. // 'pageSize' is the number of comments per page.
Task<PaginationResult<TComment>> GetCommentByQuote(int quoteId, int index, int pageSize); Task<PaginationResult<TComment>> GetCommentaryByQuote(int quoteId, int index, int pageSize);
// Retrieves all comments, with pagination support. // Retrieves all comments, with pagination support.
// This returns a list of all comments. // This returns a list of all comments.
Task<PaginationResult<TComment>> GetAllComment(); Task<PaginationResult<TComment>> GetAllCommentary();
// Retrieves comments made by a specific user, with pagination. // Retrieves comments made by a specific user, with pagination.
// 'userId' is the unique identifier of the user. // 'userId' is the unique identifier of the user.
// 'index' is the page number (for pagination). // 'index' is the page number (for pagination).
// 'pageSize' is the number of comments per page. // 'pageSize' is the number of comments per page.
Task<PaginationResult<TComment>> GetCommentByUser(int userId, int index, int pageSize); Task<PaginationResult<TComment>> GetCommentaryByUser(int userId, int index, int pageSize);
// Adds a new commenT. // Adds a new commenT.
// 'comment' is the comment object that will be added. // 'comment' is the comment object that will be added.
Task AddComment(TComment comment); Task AddComment(TComment commentary, int idQuote);
// Updates an existing comment identified by 'id'. // Updates an existing comment identified by 'id'.
// 'id' is the unique identifier of the comment, and 'comment' contains the updated comment data. // 'id' is the unique identifier of the comment, and 'comment' contains the updated comment data.
Task UpdateComment(int id, TComment comment); Task UpdateCommentary(int id, TComment comment);
// Removes a comment based on its unique identifier ('id'). // Removes a comment based on its unique identifier ('id').
// 'id' is the unique identifier of the comment to be removed. // 'id' is the unique identifier of the comment to be removed.
Task RemoveComment(int id); Task RemoveCommentary(int id);
// Deletes all comments related to a specific quote. // Deletes all comments related to a specific quote.
// 'quoteId' is the unique identifier of the quote for which comments will be deleted. // 'quoteId' is the unique identifier of the quote for which comments will be deleted.
Task DeleteCommentForQuote(int quoteId); Task DeleteCommentaryForQuote(int quoteId);
// Deletes all comments made by a specific user. // Deletes all comments made by a specific user.
// 'userId' is the unique identifier of the user whose comments will be deleted. // 'userId' is the unique identifier of the user whose comments will be deleted.
Task DeleteCommentForuser(int userId); Task DeleteCommentaryForUser(int userId);
// Retrieves the last comment ID. // Retrieves the last comment ID.
Task<int> LastCommentId(); Task<int> LastCommentaryId();
} }
} }

@ -1,12 +1,13 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Shared namespace Shared
{ {
public interface IFavoriteService public interface IFavoriteService<TQuote>
{ {
// Adds a quote to a user's list of favorites. // Adds a quote to a user's list of favorites.
// 'quoteid' is the unique identifier of the quote to be added to favorites. // 'quoteid' is the unique identifier of the quote to be added to favorites.
@ -25,4 +26,8 @@ namespace Shared
// Removes a specific quote from the favorite lists of all users. // 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. // 'quoteId' is the unique identifier of the quote to be removed from all users' favorites.
Task RemoveAllFavoriteForQuote(int quoteId); Task RemoveAllFavoriteForQuote(int quoteId);
Task<PaginationResult<TQuote>> GetFavoriteByIdUser(int userId, int index, int count);
Task<TQuote> GetFavorite(int userId, int idQuote);
} }
}

@ -10,7 +10,7 @@ namespace Shared
{ {
// Retrieves an image by its unique identifier (id). // Retrieves an image by its unique identifier (id).
// 'id' is the unique identifier of the image. // 'id' is the unique identifier of the image.
Task<TImage> GetImageById(string id); Task<TImage> GetImageById(int id);
// Retrieves all images, with pagination support. // Retrieves all images, with pagination support.
// This returns a list of all images in the system. // This returns a list of all images in the system.
@ -35,5 +35,7 @@ namespace Shared
// Retrieves the last Image ID. // Retrieves the last Image ID.
Task<int> GetLastImageId(); Task<int> GetLastImageId();
Task<TImage?> GetImageByPath(string path);
} }
} }

@ -10,7 +10,7 @@ namespace Shared
{ {
// Retrieves the daily quote in a specified language. // Retrieves the daily quote in a specified language.
// 'lang' is a language code. // 'lang' is a language code.
Task<TQuote> GetDayliQuote(int lang); Task<TQuote> GetDailyQuote(DateOnly date, int lang);
// Retrieves a specific quote by its unique identifier (id). // Retrieves a specific quote by its unique identifier (id).
Task<TQuote> GetQuoteById(int id); Task<TQuote> GetQuoteById(int id);
@ -25,8 +25,11 @@ namespace Shared
// Retrieves all available quotes but filtered by language. // Retrieves all available quotes but filtered by language.
// 'lang' is a language code used to filter the quotes in the chosen language. // 'lang' is a language code used to filter the quotes in the chosen language.
Task<PaginationResult<TQuote>> GetAllQuoteLang(int lang); Task<PaginationResult<TQuote>> GetAllQuoteLang(int index, int pageSize, int lang);
// Retrieves all inavailable quotes but filtered by language.
// 'lang' is a language code used to filter the quotes in the chosen language.
Task<PaginationResult<TQuote>> GetInvalidQuote(int index, int pageSize, int lang);
// Retrieves a page of quote suggestions based on the index (pagination) and language. // Retrieves a page of quote suggestions based on the index (pagination) and language.
// 'index' is the starting point for pagination // 'index' is the starting point for pagination
// 'pageSize' determines the number of quotes per page // 'pageSize' determines the number of quotes per page
@ -73,7 +76,7 @@ namespace Shared
// Adds a new quote. // Adds a new quote.
// 'quote' is the quote object that will be added. // 'quote' is the quote object that will be added.
Task AddQuote(TQuote quote); Task<TQuote> AddQuote(TQuote quote);
// Updates an existing quote identified by 'quoteId' with new details. // Updates an existing quote identified by 'quoteId' with new details.
// 'quoteId' is the ID of the quote to be updated // 'quoteId' is the ID of the quote to be updated
@ -83,14 +86,12 @@ namespace Shared
// Removes a quote based on its unique identifier ('quoteId'). // Removes a quote based on its unique identifier ('quoteId').
Task RemoveQuote(int quoteId); Task RemoveQuote(int quoteId);
// Returns the total number of quotes available.
Task<int> CountQuotes();
// Retrieves the last ID. // Retrieves the last ID.
Task<int> GetLastQuoteId(); Task<int> GetLastQuoteId();
// Validates or invalidates a quote based on the 'quoteId' and a boolean value ('isValidate'). // Validates or invalidates a quote based on the 'quoteId' and a boolean value ('isValidate').
// If 'isValidate' is true, the quote is marked as valid; if false, it is invalid. // If 'isValidate' is true, the quote is marked as valid; if false, it is invalid.
Task ValidateQuote(int quoteId, bool isValidate); Task ValidateQuote(int quoteId, bool isValidate);
} }
} }

@ -18,11 +18,10 @@ namespace Shared
// Retrieves a source by its date. // Retrieves a source by its date.
// 'date' is the date associated with the source to be retrieved. // 'date' is the date associated with the source to be retrieved.
Task<TSource> GetSourceByDate(string date); Task<PaginationResult<TSource>> GetSourceByDate(int date);
// Retrieves a source by its type. // Retrieves a source by its type.
// 'type' is the type of the source to be retrieved. // 'type' is the type of the source to be retrieved.
Task<TSource> GetSourceByType(string type); Task<TSource> GetSourceByType(int type);
// Retrieves all sources, with pagination support. // Retrieves all sources, with pagination support.
// This returns a list of all sources in the system. // This returns a list of all sources in the system.
@ -43,5 +42,7 @@ namespace Shared
// Retrieves the unique identifier of the last added source. // Retrieves the unique identifier of the last added source.
Task<int> GetLastSourceId(); Task<int> GetLastSourceId();
Task<PaginationResult<TSource>> GetSomesSource(int page, int count);
} }
} }

@ -35,11 +35,11 @@ namespace Shared
// Updates the details of an existing user identified by 'userId'. // Updates the details of an existing user identified by 'userId'.
// 'userId' is the ID of the user to be updated, and 'user' contains the new user data. // 'userId' is the ID of the user to be updated, and 'user' contains the new user data.
Task UpdateUser(int userId, TUser user); Task<TUser> UpdateUser(int userId, TUser user);
// Removes a user from the system based on their unique identifier ('userId'). // Removes a user from the system based on their unique identifier ('userId').
// 'userId' is the unique identifier of the user to be removed. // 'userId' is the unique identifier of the user to be removed.
Task RemoveUser(int userId); Task RemoveUser(int id);
// Retrieves the hashed password for a given username. // Retrieves the hashed password for a given username.
// 'username' is the username for which the password hash is to be retrieved. // 'username' is the username for which the password hash is to be retrieved.

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Shared
{
public class Mapper<T,U> where T : class
where U : class
{
readonly HashSet<Tuple<T, U>> mapper = new HashSet<Tuple<T, U>>();
public bool AddMapping(T t, U u)
{
var mapping = new Tuple<T, U>(t, u);
if (mapper.Contains(mapping)) return false;
mapper.Add(mapping);
return true;
}
public T? GetT(U u)
{
var result = mapper.Where(tuple => ReferenceEquals(tuple.Item2, u));
if (result.Count() != 1)
{
return null;
}
return result.First().Item1;
}
public U? GetU(T t)
{
var result = mapper.Where(tuple => ReferenceEquals(tuple.Item1, t));
if (result.Count() != 1)
{
return null;
}
return result.First().Item2;
}
public void Reset()
{
mapper.Clear();
}
}
}

@ -6,4 +6,15 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.3" />
<PackageReference Include="NSwag.Core" Version="14.3.0" />
<PackageReference Include="NSwag.Core.Yaml" Version="14.3.0" />
<PackageReference Include="NSwag.Generation.AspNetCore" Version="14.3.0" />
</ItemGroup>
</Project> </Project>

@ -0,0 +1,153 @@
using DTO;
using Shared;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StubApi
{
public class QuoteServiceStub : IQuoteService<QuoteDTO>
{
private readonly List<QuoteDTO> _quotes;
public QuoteServiceStub()
{
_quotes = new List<QuoteDTO>
{
new QuoteDTO{Id=0, Content="Que la force soit avec toi", Character="Obi-Wan", ImagePath="http://image1", TitleSource="Star Wars", DateSource=1977, Like=32, Langage=TypeLangageDTO.vo, Type=TypeSrcEnumDTO.movie,IsValide=true},
new QuoteDTO{Id=1, Content="Je suis ton père", Character="Darth Vader", ImagePath="http://image2", TitleSource="Star Wars", DateSource=1980, Like=120, Langage=TypeLangageDTO.vo, Type=TypeSrcEnumDTO.movie,IsValide=true},
new QuoteDTO{Id=2, Content="Que la vengeance commence", Character="Anakin Skywalker", ImagePath="http://image3", TitleSource="Star Wars: Episode III", DateSource=2005, Like=95, Langage=TypeLangageDTO.vo, Type=TypeSrcEnumDTO.movie,IsValide=true},
new QuoteDTO{Id=3, Content="J'adore l'odeur du napalm au matin", Character="Kilgore", ImagePath="http://image4", TitleSource="Apocalypse Now", DateSource=1979, Like=56, Langage=TypeLangageDTO.vo, Type=TypeSrcEnumDTO.movie,IsValide=true},
new QuoteDTO{Id=4, Content="Je suis Groot", Character="Groot", ImagePath="http://image5", TitleSource="Guardians of the Galaxy", DateSource=2014, Like=200, Langage=TypeLangageDTO.vo, Type=TypeSrcEnumDTO.movie,IsValide=true},
new QuoteDTO{Id=5, Content="La vie est un rêve", Character="Don Quichotte", ImagePath="http://image6", TitleSource="Don Quichotte", DateSource=1605, Like=34, Langage=TypeLangageDTO.vf, Type=TypeSrcEnumDTO.book,IsValide=true},
new QuoteDTO{Id=6, Content="To infinity and beyond!", Character="Buzz Lightyear", ImagePath="http://image7", TitleSource="Toy Story", DateSource=1995, Like=180, Langage=TypeLangageDTO.vo, Type=TypeSrcEnumDTO.movie,IsValide=true},
new QuoteDTO{Id=7, Content="Je ne suis pas un héros", Character="Bruce Wayne", ImagePath="http://image8", TitleSource="The Dark Knight", DateSource=2008, Like=250, Langage=TypeLangageDTO.vo, Type=TypeSrcEnumDTO.movie,IsValide=true},
new QuoteDTO{Id=8, Content="Je suis le maître du jeu", Character="Jigsaw", ImagePath="http://image9", TitleSource="Saw", DateSource=2004, Like=65, Langage=TypeLangageDTO.vo, Type=TypeSrcEnumDTO.movie,IsValide=true},
new QuoteDTO{Id=9, Content="Liberté, égalité, fraternité", Character="La devise de la France", ImagePath="http://image10", TitleSource="Révolution française", DateSource=1789, Like=300, Langage=TypeLangageDTO.vf, Type=TypeSrcEnumDTO.book,IsValide=true},
new QuoteDTO{Id=10, Content="Un petit pas pour l'homme, un grand pas pour l'humanité", Character="Neil Armstrong", ImagePath="http://image11", TitleSource="Moon landing", DateSource=1969, Like=500, Langage=TypeLangageDTO.vo, Type=TypeSrcEnumDTO.book,IsValide=true},
new QuoteDTO{Id=11, Content="C'est la vie", Character="Charles", ImagePath="http://image12", TitleSource="French Movie", DateSource=2013, Like=45, Langage=TypeLangageDTO.vf, Type=TypeSrcEnumDTO.movie,IsValide=true},
new QuoteDTO{Id=12, Content="Voici Johnny!", Character="Jack Torrance", ImagePath="http://image13", TitleSource="The Shining", DateSource=1980, Like=300, Langage=TypeLangageDTO.vo, Type=TypeSrcEnumDTO.movie,IsValide=true},
new QuoteDTO{Id=13, Content="Je suis un simple serveur", Character="Hannibal", ImagePath="http://image14", TitleSource="The Silence of the Lambs", DateSource=1991, Like=200, Langage=TypeLangageDTO.vo, Type=TypeSrcEnumDTO.movie,IsValide=true},
new QuoteDTO{Id=14, Content="N'attends pas le moment parfait, prends le moment et rends-le parfait", Character="Zig Ziglar", ImagePath="http://image15", TitleSource="Motivation", DateSource=1995, Like=150, Langage=TypeLangageDTO.vf, Type=TypeSrcEnumDTO.book,IsValide=true},
new QuoteDTO{Id=15, Content="Le seul vrai voyage est de changer de regard", Character="Marcel Proust", ImagePath="http://image16", TitleSource="À la recherche du temps perdu", DateSource=1913, Like=125, Langage=TypeLangageDTO.vf, Type=TypeSrcEnumDTO.book,IsValide=true},
new QuoteDTO{Id=16, Content="La force sera avec toi, toujours", Character="Obi-Wan Kenobi", ImagePath="http://image17", TitleSource="Star Wars: Episode IV", DateSource=1977, Like=320, Langage=TypeLangageDTO.vo, Type=TypeSrcEnumDTO.movie,IsValide=true},
new QuoteDTO{Id=17, Content="J'ai toujours rêvé d'être un gangster", Character="Henry Hill", ImagePath="http://image18", TitleSource="Goodfellas", DateSource=1990, Like=500, Langage=TypeLangageDTO.vo, Type=TypeSrcEnumDTO.movie,IsValide=true},
new QuoteDTO{Id=18, Content="Je vous ai compris", Character="De Gaulle", ImagePath="http://image19", TitleSource="Discours de Gaulle", DateSource=1958, Like=250, Langage=TypeLangageDTO.vf, Type=TypeSrcEnumDTO.book,IsValide=true},
new QuoteDTO{Id=19, Content="Courage, fuyons!", Character="Frédéric", ImagePath="http://image20", TitleSource="Le Pourceau", DateSource=1834, Like=75, Langage=TypeLangageDTO.vf, Type=TypeSrcEnumDTO.book,IsValide=false}
};
}
public async Task<QuoteDTO> AddQuote(QuoteDTO quote)
{
_quotes.Add(quote);
return quote;
}
public async Task<PaginationResult<QuoteDTO>> GetAllQuote()
{
return new PaginationResult<QuoteDTO>(_quotes.Where(q=>q.IsValide == true).ToList().Count,
0,
_quotes.Count,
_quotes.Where(q => q.IsValide == true).ToList());
}
public async Task<PaginationResult<QuoteDTO>> GetAllQuoteLang(int index, int pageSize, int lang)
{
TypeLangageDTO langageType = (TypeLangageDTO)lang;
return new PaginationResult<QuoteDTO>(_quotes.Where(q => q.IsValide = true).ToList().Count,
index,
pageSize,
_quotes.Where(q => q.IsValide == true && q.Langage == langageType ).ToList().Skip(index * pageSize).Take(pageSize).ToList()
);
}
public async Task<QuoteDTO> GetDailyQuote(DateOnly date, int lang)
{
int nb = _quotes.Where(q => q.Langage == (TypeLangageDTO)lang && q.IsValide == true).Count();
return _quotes.Where(q => q.Langage == (TypeLangageDTO)lang && q.IsValide == true).ToList().Find(q => q.Id == date.DayNumber%nb) ?? _quotes.Where(q => q.Langage == (TypeLangageDTO)lang && q.IsValide == true).First();
}
public async Task<PaginationResult<QuoteDTO>> GetFavorites(int index, int pageSize, int UserId)
{
throw new NotImplementedException();
}
public async Task<PaginationResult<QuoteDTO>> GetInvalidQuote(int index, int pageSize)
{
throw new NotImplementedException();
}
public async Task<int> GetLastQuoteId() // JE VOIS PAS L'INTERET
{
throw new NotImplementedException();
}
public async Task<QuoteDTO> GetQuoteById(int id)
{
return _quotes.FirstOrDefault(q => q.Id == id);
}
public async Task<PaginationResult<QuoteDTO>> GetSomeQuote(int index, int pageSize)
{
return new PaginationResult<QuoteDTO>(_quotes.Where(q => q.IsValide = true).ToList().Count,
index,
pageSize,
_quotes.Where(q => q.IsValide = true).ToList().Skip(index * pageSize).Take(pageSize).ToList()
);
}
public async Task<PaginationResult<QuoteDTO>> GetSuggestions(int index, int pageSize, int lang)
{
throw new NotImplementedException();
}
public async Task<PaginationResult<QuoteDTO>> GetValidQuote(int index, int pageSize)
{
throw new NotImplementedException();
}
public async Task RemoveQuote(int quoteId)
{
_quotes.Remove( GetQuoteById(quoteId).Result );
}
public async Task<PaginationResult<QuoteDTO>> SearchByCharacter(string character, int index, int pageSize, int lang)
{
throw new NotImplementedException();
}
public async Task<PaginationResult<QuoteDTO>> SearchByContent(string content, int index, int pageSize, int lang)
{
throw new NotImplementedException();
}
public async Task<PaginationResult<QuoteDTO>> SearchBySource(string source, int index, int pageSize, int lang)
{
throw new NotImplementedException();
}
public async Task UpdateQuote(int quoteId, QuoteDTO quote)
{
throw new NotImplementedException();
}
public async Task ValidateQuote(int quoteId, bool isValidate)
{
throw new NotImplementedException();
}
public async Task<PaginationResult<QuoteDTO>> GetInvalidQuote(int index, int pageSize, int lang)
{
TypeLangageDTO langageType = (TypeLangageDTO)lang;
return new PaginationResult<QuoteDTO>(_quotes.Where(q => q.IsValide == false && q.Langage == langageType).ToList().Count,
index,
pageSize,
_quotes.Where(q => q.IsValide == false && q.Langage == langageType).ToList().Skip(index * pageSize).Take(pageSize).ToList()
);
}
}
}

@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.3" />
<PackageReference Include="NSwag.Core" Version="14.3.0" />
<PackageReference Include="NSwag.Core.Yaml" Version="14.3.0" />
<PackageReference Include="NSwag.Generation.AspNetCore" Version="14.3.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DTO\DTO.csproj" />
<ProjectReference Include="..\Shared\Shared.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,123 @@
using Shared;
using DTO;
namespace StubApi
{
public class UserServiceStub : IUserService<UserDTO>
{
private readonly List<UserDTO> _users;
public UserServiceStub()
{
_users = new List<UserDTO>
{
new UserDTO { Id = 1, Pseudo = "dev", Password = "1234", Email = "testeur@example.com", date = new DateTime(2025,1,1), ImageProfil = "https://image_profil_1" },
new UserDTO { Id = 2, Pseudo = "admin", Password = "admin123", Email = "admin@example.com", date = new DateTime(2025,1,1), ImageProfil = "https://image_profil_2" },
new UserDTO { Id = 3, Pseudo = "user123", Password = "password123", Email = "user123@example.com", date = new DateTime(2022,1,1), ImageProfil = "https://image_profil_3" },
new UserDTO { Id = 4, Pseudo = "testuser", Password = "testpass", Email = "testuser@example.com", date = new DateTime(2024,1,1), ImageProfil = "https://image_profil_4" },
new UserDTO { Id = 5, Pseudo = "johnDoe", Password = "john123", Email = "johndoe@example.com", date = new DateTime(2021,1,1), ImageProfil = "https://image_profil_5" },
new UserDTO { Id = 6, Pseudo = "janedoe", Password = "jane123", Email = "janedoe@example.com", date = new DateTime(2023,1,1), ImageProfil = "https://image_profil_6" },
new UserDTO { Id = 7, Pseudo = "mark_smith", Password = "mark1234", Email = "marks@example.com", date = new DateTime(2022,1,1), ImageProfil = "https://image_profil_7" },
new UserDTO { Id = 8, Pseudo = "alice", Password = "alicepass", Email = "alice@example.com", date = new DateTime(2025,1,1), ImageProfil = "https://image_profil_8" },
new UserDTO { Id = 9, Pseudo = "bob_lee", Password = "bob123", Email = "bob@example.com", date = new DateTime(2021,1,1), ImageProfil = "https://image_profil_9" },
new UserDTO { Id = 10, Pseudo = "lucas", Password = "lucaspass", Email = "lucas@example.com", date = new DateTime(2023,1,1), ImageProfil = "https://image_profil_10" },
new UserDTO { Id = 11, Pseudo = "emily", Password = "emily2024", Email = "emily@example.com", date = new DateTime(2022,1,1), ImageProfil = "https://image_profil_11" },
new UserDTO { Id = 12, Pseudo = "chris", Password = "chris1234", Email = "chris@example.com", date = new DateTime(2025,1,1), ImageProfil = "https://image_profil_12" },
new UserDTO { Id = 13, Pseudo = "susan", Password = "susan123", Email = "susan@example.com", date = new DateTime(2023,1,1), ImageProfil = "https://image_profil_13" },
new UserDTO { Id = 14, Pseudo = "michael", Password = "michael2025", Email = "michael@example.com", date = new DateTime(2022,1,1), ImageProfil = "https://image_profil_14" },
new UserDTO { Id = 15, Pseudo = "olivia", Password = "olivia2024", Email = "olivia@example.com", date = new DateTime(2025,1,1), ImageProfil = "https://image_profil_15" },
new UserDTO { Id = 16, Pseudo = "david", Password = "david123", Email = "david@example.com", date = new DateTime(2021,1,1), ImageProfil = "https://image_profil_16" },
new UserDTO { Id = 17, Pseudo = "laura", Password = "laura456", Email = "laura@example.com", date = new DateTime(2023,1,1), ImageProfil = "https://image_profil_17" },
new UserDTO { Id = 18, Pseudo = "steve", Password = "steve789", Email = "steve@example.com", date = new DateTime(2022,1,1), ImageProfil = "https://image_profil_18" },
new UserDTO { Id = 19, Pseudo = "tina", Password = "tina321", Email = "tina@example.com", date = new DateTime(2025,1,1), ImageProfil = "https://image_profil_19" },
new UserDTO { Id = 20, Pseudo = "peter", Password = "peter123", Email = "peter@example.com", date = new DateTime(2024,1,1), ImageProfil = "https://image_profil_20" }
};
}
public async Task AddUser(UserDTO user)
{
_users.Add(user);
}
public async Task<int> CountUser()
{
return _users.Count;
}
public async Task<bool> ExistEmail(string email)
{
if (_users.FirstOrDefault(u => u.Email == email) == null) return false;
return true;
}
public async Task<bool> ExistUsername(string username)
{
if (_users.FirstOrDefault(u => u.Pseudo == username) == null) return false;
return true;
}
public async Task<PaginationResult<UserDTO>> GetAllUser()
{
return new PaginationResult<UserDTO>(_users.Count,0,_users.Count, _users);
}
public async Task<string> GetHashPassword(string username)
{
return _users.FirstOrDefault(u => u.Pseudo == username).Password;
}
public async Task<int> GetLastUserId() // JE VOIS PAS L'INTERET
{
throw new NotImplementedException();
}
public async Task<PaginationResult<UserDTO>> GetSomeUser(int index, int pageSize)
{
return new PaginationResult<UserDTO>(_users.Count, index, pageSize, _users.Skip(index* pageSize).Take(pageSize).ToList());
}
public async Task<UserDTO> GetUserByEmail(string email)
{
return _users.FirstOrDefault(u => u.Email == email);
}
public async Task<UserDTO> GetUserById(int id)
{
return _users.FirstOrDefault(u => u.Id == id);
}
public async Task<UserDTO> GetUserByUsername(string username)
{
return _users.FirstOrDefault(u => u.Pseudo == username);
}
public async Task RemoveUser(int id)
{
var user = await GetUserById(id);
_users.Remove(user);
}
public async Task SetAdminRole(bool isAdmin)
{
throw new NotImplementedException();
}
public async Task<UserDTO> UpdateUser(int userId, UserDTO user)
{
UserDTO userUpdate = new UserDTO();
userUpdate = GetUserById(userId).Result;
// Update users properties
userUpdate.Pseudo = user.Pseudo;
userUpdate.Password = user.Password;
userUpdate.Email = user.Email;
userUpdate.date = user.date;
userUpdate.ImageProfil = user.ImageProfil;
return userUpdate;
}
}
}

@ -0,0 +1,497 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional
namespace StubbedContextLib.Migrations
{
/// <inheritdoc />
public partial class myFirstMigration : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "images",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
ImgPath = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_images", x => x.Id);
});
migrationBuilder.CreateTable(
name: "question",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Text = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
AnswerA = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
AnswerB = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
AnswerC = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
AnswerD = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
CorrectAnswer = table.Column<string>(type: "character varying(1)", maxLength: 1, nullable: false),
IsValid = table.Column<bool>(type: "boolean", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_question", x => x.Id);
});
migrationBuilder.CreateTable(
name: "sources",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Title = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
Year = table.Column<int>(type: "integer", nullable: false),
TypeSrc = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_sources", x => x.Id);
});
migrationBuilder.CreateTable(
name: "characters",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
IdImage = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_characters", x => x.Id);
table.ForeignKey(
name: "FK_characters_images_IdImage",
column: x => x.IdImage,
principalTable: "images",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "quizzes",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Title = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
IdImage = table.Column<int>(type: "integer", nullable: false),
NbQuestion = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_quizzes", x => x.Id);
table.ForeignKey(
name: "FK_quizzes_images_IdImage",
column: x => x.IdImage,
principalTable: "images",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "users",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
UserName = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
Email = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
Password = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
IdImage = table.Column<int>(type: "integer", nullable: false),
Created = table.Column<DateTime>(type: "date", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_users", x => x.Id);
table.ForeignKey(
name: "FK_users_images_IdImage",
column: x => x.IdImage,
principalTable: "images",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "QuizQuestion",
columns: table => new
{
IdQuiz = table.Column<int>(type: "integer", nullable: false),
IdQuestion = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_QuizQuestion", x => new { x.IdQuestion, x.IdQuiz });
table.ForeignKey(
name: "FK_QuizQuestion_question_IdQuestion",
column: x => x.IdQuestion,
principalTable: "question",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_QuizQuestion_quizzes_IdQuiz",
column: x => x.IdQuiz,
principalTable: "quizzes",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "admins",
columns: table => new
{
IdUsers = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
UserId = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_admins", x => x.IdUsers);
table.ForeignKey(
name: "FK_admins_users_UserId",
column: x => x.UserId,
principalTable: "users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "quotes",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Content = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
Likes = table.Column<int>(type: "integer", nullable: false),
Langage = table.Column<int>(type: "integer", nullable: false),
IsValid = table.Column<bool>(type: "boolean", nullable: false),
IdCharacter = table.Column<int>(type: "integer", nullable: false),
IdSource = table.Column<int>(type: "integer", nullable: false),
IdUsersPropose = table.Column<int>(type: "integer", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_quotes", x => x.Id);
table.ForeignKey(
name: "FK_quotes_characters_IdCharacter",
column: x => x.IdCharacter,
principalTable: "characters",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_quotes_sources_IdSource",
column: x => x.IdSource,
principalTable: "sources",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_quotes_users_IdUsersPropose",
column: x => x.IdUsersPropose,
principalTable: "users",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
name: "comments",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
IdUser = table.Column<int>(type: "integer", nullable: false),
IdQuote = table.Column<int>(type: "integer", nullable: false),
DateCommentary = table.Column<DateTime>(type: "date", nullable: false),
Comment = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_comments", x => x.Id);
table.ForeignKey(
name: "FK_comments_quotes_IdQuote",
column: x => x.IdQuote,
principalTable: "quotes",
principalColumn: "Id");
table.ForeignKey(
name: "FK_comments_users_IdUser",
column: x => x.IdUser,
principalTable: "users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "favorites",
columns: table => new
{
IdUsers = table.Column<int>(type: "integer", nullable: false),
IdQuote = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_favorites", x => new { x.IdQuote, x.IdUsers });
table.ForeignKey(
name: "FK_favorites_quotes_IdQuote",
column: x => x.IdQuote,
principalTable: "quotes",
principalColumn: "Id");
table.ForeignKey(
name: "FK_favorites_users_IdUsers",
column: x => x.IdUsers,
principalTable: "users",
principalColumn: "Id");
});
migrationBuilder.InsertData(
table: "images",
columns: new[] { "Id", "ImgPath" },
values: new object[,]
{
{ 1, "https://th.bing.com/th/id/OIP.TJuWNCsibz8MVmhdNQEdMwHaE8?w=244&h=180&c=7&r=0&o=5&pid=1.7" },
{ 2, "https://th.bing.com/th/id/OIP.NgXRQ5-IknA6_qOPFhLWIwHaHK?w=165&h=180&c=7&r=0&o=5&pid=1.7" },
{ 3, "https://th.bing.com/th/id/OIP.XcJoJ6bC9sAMjol1pJn5UQHaLH?w=118&h=180&c=7&r=0&o=5&pid=1.7" },
{ 4, "https://th.bing.com/th/id/OIP.PPIESqZaNDa-qUcfSDXhdQHaGK?w=210&h=180&c=7&r=0&o=5&pid=1.7" },
{ 5, "https://th.bing.com/th/id/OIP.XBghSl2kfRNNtQoSxc901wHaHa?w=177&h=180&c=7&r=0&o=5&pid=1.7" },
{ 6, "https://th.bing.com/th/id/OIP.af1Aid64cqEKoIOBgCPxtQHaJO?w=145&h=182&c=7&r=0&o=5&pid=1.7" },
{ 7, "https://th.bing.com/th/id/OIP.ri5vSXr5lNTLt4DO6KQXyQHaI4?w=158&h=189&c=7&r=0&o=5&pid=1.7" },
{ 8, "https://th.bing.com/th/id/OIP.uPTRLR8uspCiafiunUqKfQHaMJ?w=115&h=180&c=7&r=0&o=5&pid=1.7" },
{ 9, "https://th.bing.com/th/id/OIP.hcJis4rKbyQtugsoFJU2ngHaM_?w=118&h=207&c=7&r=0&o=5&pid=1.7" },
{ 10, "https://th.bing.com/th/id/OIP.Py1_XfUrKJY_A6tYEmFS5wHaE8?w=280&h=187&c=7&r=0&o=5&pid=1.7" }
});
migrationBuilder.InsertData(
table: "question",
columns: new[] { "Id", "AnswerA", "AnswerB", "AnswerC", "AnswerD", "CorrectAnswer", "IsValid", "Text" },
values: new object[,]
{
{ 1, "Gimli", "Aragorn", "Frodon", "Gandalf", "B", true, "Qui est le leader de la Communauté de l'Anneau ?" },
{ 2, "Serdaigle", "Gryffondor", "Serpentard", "Poufsouffle", "B", false, "Dans quelle maison Harry Potter est-il ?" },
{ 3, "Saroumane", "Sauron", "Gollum", "Gothmog", "B", true, "Qui est le Seigneur des Ténèbres dans la saga Le Seigneur des Anneaux ?" },
{ 4, "Han Solo", "Princesse Leia", "Chewbacca", "R2-D2", "A", true, "Dans le film Star Wars : Episode IV, qui sauve Luke Skywalker de l'Étoile de la Mort ?" },
{ 5, "Reine Jadis", "Aslan", "Edmund", "Lucy", "B", true, "Qui est le souverain de Narnia dans Le Lion, la Sorcière Blanche et l'Armoire Magique ?" },
{ 6, "Smaug", "Falkor", "Norbert", "Shenron", "A", true, "Quel est le nom du dragon dans Le Hobbit ?" },
{ 7, "Bella Swan", "Edward Cullen", "Jacob Black", "Victoria", "A", true, "Qui est la première personne à être mordue par un vampire dans Twilight ?" },
{ 8, "Obi-Wan Kenobi", "Yoda", "Han Solo", "Luke Skywalker", "A", true, "Quel personnage dit Que la Force soit avec toi dans Star Wars ?" },
{ 9, "Dr. Ellie Sattler", "Alan Grant", "John Hammond", "Dennis Nedry", "B", true, "Dans Jurassic Park, quel est le nom du paléontologue sur l'île ?" },
{ 10, "Cersei Lannister", "Arya Stark", "Daenerys Targaryen", "Sansa Stark", "C", true, "Dans Game of Thrones, qui est surnommée la Mère des Dragons ?" }
});
migrationBuilder.InsertData(
table: "sources",
columns: new[] { "Id", "Title", "TypeSrc", "Year" },
values: new object[,]
{
{ 1, "Jurassic Park", 0, 1993 },
{ 2, "Le Seigneur des anneaux : La Communauté de l'anneau", 0, 2001 },
{ 3, "Game of throne", 1, 2011 },
{ 4, "Harry Potter à l'école des sorcier", 0, 1997 },
{ 5, "Star Wars, épisode IV : Un nouvel espoir", 0, 1977 }
});
migrationBuilder.InsertData(
table: "characters",
columns: new[] { "Id", "IdImage", "Name" },
values: new object[,]
{
{ 1, 1, "Alan Grant" },
{ 2, 2, "Aragorn" },
{ 3, 3, "Legolas" },
{ 4, 4, "Frodon" },
{ 5, 5, "Dobby" },
{ 6, 6, "Jon Snow" },
{ 7, 7, "Daenerys Targaryen" },
{ 8, 8, "Luke Skywalker" },
{ 9, 9, "Princess Leia" },
{ 10, 10, "Harry Potter" }
});
migrationBuilder.InsertData(
table: "quizzes",
columns: new[] { "Id", "IdImage", "NbQuestion", "Title" },
values: new object[,]
{
{ 1, 1, 5, "Quiz 1" },
{ 2, 2, 5, "Quiz 2" }
});
migrationBuilder.InsertData(
table: "users",
columns: new[] { "Id", "Created", "Email", "IdImage", "Password", "UserName" },
values: new object[,]
{
{ 1, new DateTime(2025, 5, 12, 0, 0, 0, 0, DateTimeKind.Unspecified), "jhonDhoe@gmail.com", 1, "1234", "Jhon-Dhoe" },
{ 2, new DateTime(2025, 3, 19, 0, 0, 0, 0, DateTimeKind.Unspecified), "lucy_rose@outlook.com", 2, "abcd", "Lucy-Rose" },
{ 3, new DateTime(2024, 11, 2, 0, 0, 0, 0, DateTimeKind.Unspecified), "mark.taylor@yahoo.com", 3, "5678", "Mark-Taylor" },
{ 4, new DateTime(2025, 2, 28, 0, 0, 0, 0, DateTimeKind.Unspecified), "sophie.martin@gmail.com", 4, "4321", "Sophie-Martin" },
{ 5, new DateTime(2025, 1, 15, 0, 0, 0, 0, DateTimeKind.Unspecified), "nathan_doe@aol.com", 5, "8765", "Nathan-Doe" },
{ 6, new DateTime(2025, 4, 7, 0, 0, 0, 0, DateTimeKind.Unspecified), "ella.brown@icloud.com", 6, "2468", "Ella-Brown" },
{ 7, new DateTime(2024, 12, 25, 0, 0, 0, 0, DateTimeKind.Unspecified), "oliver_smith@gmail.com", 7, "1357", "Oliver-Smith" },
{ 8, new DateTime(2025, 3, 5, 0, 0, 0, 0, DateTimeKind.Unspecified), "mia.jones@outlook.com", 8, "1122", "Mia-Jones" },
{ 9, new DateTime(2025, 2, 22, 0, 0, 0, 0, DateTimeKind.Unspecified), "kevin_williams@aol.com", 9, "2233", "Kevin-Williams" },
{ 10, new DateTime(2025, 1, 3, 0, 0, 0, 0, DateTimeKind.Unspecified), "olivia.white@yahoo.com", 10, "3344", "Olivia-White" }
});
migrationBuilder.InsertData(
table: "QuizQuestion",
columns: new[] { "IdQuestion", "IdQuiz" },
values: new object[,]
{
{ 1, 1 },
{ 2, 1 },
{ 3, 1 },
{ 4, 1 },
{ 5, 1 },
{ 6, 2 },
{ 7, 2 },
{ 8, 2 },
{ 9, 2 },
{ 10, 2 }
});
migrationBuilder.InsertData(
table: "quotes",
columns: new[] { "Id", "Content", "IdCharacter", "IdSource", "IdUsersPropose", "IsValid", "Langage", "Likes" },
values: new object[,]
{
{ 1, "Je n'y crois pas. Je n'y crois pas. Ce n'est pas possible", 1, 1, 1, true, 1, 11025 },
{ 2, "There is always hope", 2, 2, 1, true, 0, 11025 },
{ 3, "A red sun rises. Blood has been spilled this night.", 3, 2, 1, true, 0, 11025 },
{ 4, "I wish the Ring had never come to me.I wish none of this had happened.", 4, 2, 1, true, 0, 11025 },
{ 5, "Dobby is a free elf!", 5, 4, 1, true, 0, 11025 },
{ 6, "Winter is comming", 6, 3, 1, true, 0, 11025 },
{ 7, "Je suis la dernière Targaryen. Je suis la reine des dragons", 7, 3, 1, true, 1, 11025 },
{ 8, "Je ne suis pas prêt à affronter ça. C'est trop pour moi.", 8, 5, 1, true, 1, 11025 },
{ 9, "Aidez-moi, Obi-Wan Kenobi, vous êtes mon seul espoir.", 9, 5, 1, true, 1, 11025 },
{ 10, "La quoi ?", 10, 4, 1, false, 1, 11025 }
});
migrationBuilder.InsertData(
table: "comments",
columns: new[] { "Id", "Comment", "DateCommentary", "IdQuote", "IdUser" },
values: new object[,]
{
{ 1, "Ce film est le meilleur", new DateTime(2025, 2, 3, 0, 0, 0, 0, DateTimeKind.Unspecified), 1, 2 },
{ 2, "Very good", new DateTime(2025, 3, 11, 0, 0, 0, 0, DateTimeKind.Unspecified), 1, 3 }
});
migrationBuilder.InsertData(
table: "favorites",
columns: new[] { "IdQuote", "IdUsers" },
values: new object[,]
{
{ 1, 6 },
{ 2, 8 },
{ 3, 2 },
{ 4, 10 },
{ 5, 3 },
{ 6, 7 },
{ 8, 9 },
{ 9, 1 },
{ 10, 5 }
});
migrationBuilder.CreateIndex(
name: "IX_admins_UserId",
table: "admins",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_characters_IdImage",
table: "characters",
column: "IdImage");
migrationBuilder.CreateIndex(
name: "IX_comments_IdQuote",
table: "comments",
column: "IdQuote");
migrationBuilder.CreateIndex(
name: "IX_comments_IdUser",
table: "comments",
column: "IdUser");
migrationBuilder.CreateIndex(
name: "IX_favorites_IdUsers",
table: "favorites",
column: "IdUsers");
migrationBuilder.CreateIndex(
name: "IX_QuizQuestion_IdQuiz",
table: "QuizQuestion",
column: "IdQuiz");
migrationBuilder.CreateIndex(
name: "IX_quizzes_IdImage",
table: "quizzes",
column: "IdImage");
migrationBuilder.CreateIndex(
name: "IX_quotes_IdCharacter",
table: "quotes",
column: "IdCharacter");
migrationBuilder.CreateIndex(
name: "IX_quotes_IdSource",
table: "quotes",
column: "IdSource");
migrationBuilder.CreateIndex(
name: "IX_quotes_IdUsersPropose",
table: "quotes",
column: "IdUsersPropose");
migrationBuilder.CreateIndex(
name: "IX_users_IdImage",
table: "users",
column: "IdImage");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "admins");
migrationBuilder.DropTable(
name: "comments");
migrationBuilder.DropTable(
name: "favorites");
migrationBuilder.DropTable(
name: "QuizQuestion");
migrationBuilder.DropTable(
name: "quotes");
migrationBuilder.DropTable(
name: "question");
migrationBuilder.DropTable(
name: "quizzes");
migrationBuilder.DropTable(
name: "characters");
migrationBuilder.DropTable(
name: "sources");
migrationBuilder.DropTable(
name: "users");
migrationBuilder.DropTable(
name: "images");
}
}
}

@ -0,0 +1,99 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace StubbedContextLib.Migrations
{
/// <inheritdoc />
public partial class migrLangUser : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "Lang",
table: "users",
type: "integer",
nullable: false,
defaultValue: 0);
migrationBuilder.UpdateData(
table: "users",
keyColumn: "Id",
keyValue: 1,
column: "Lang",
value: 0);
migrationBuilder.UpdateData(
table: "users",
keyColumn: "Id",
keyValue: 2,
column: "Lang",
value: 0);
migrationBuilder.UpdateData(
table: "users",
keyColumn: "Id",
keyValue: 3,
column: "Lang",
value: 0);
migrationBuilder.UpdateData(
table: "users",
keyColumn: "Id",
keyValue: 4,
column: "Lang",
value: 0);
migrationBuilder.UpdateData(
table: "users",
keyColumn: "Id",
keyValue: 5,
column: "Lang",
value: 0);
migrationBuilder.UpdateData(
table: "users",
keyColumn: "Id",
keyValue: 6,
column: "Lang",
value: 0);
migrationBuilder.UpdateData(
table: "users",
keyColumn: "Id",
keyValue: 7,
column: "Lang",
value: 0);
migrationBuilder.UpdateData(
table: "users",
keyColumn: "Id",
keyValue: 8,
column: "Lang",
value: 0);
migrationBuilder.UpdateData(
table: "users",
keyColumn: "Id",
keyValue: 9,
column: "Lang",
value: 0);
migrationBuilder.UpdateData(
table: "users",
keyColumn: "Id",
keyValue: 10,
column: "Lang",
value: 0);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Lang",
table: "users");
}
}
}

@ -0,0 +1,153 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Contextlib;
using Entity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using Npgsql.EntityFrameworkCore.PostgreSQL;
namespace StubbedContextLib
{
public class StubWTFContext : WTFContext
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
/*modelBuilder.Entity<Admin>().HasData(
new Admin() { IdUsers = 1 }
);*/
modelBuilder.Entity<Images>().HasData(
new Images() { Id = 1, ImgPath = "https://th.bing.com/th/id/OIP.TJuWNCsibz8MVmhdNQEdMwHaE8?w=244&h=180&c=7&r=0&o=5&pid=1.7" },
new Images() { Id = 2, ImgPath = "https://th.bing.com/th/id/OIP.NgXRQ5-IknA6_qOPFhLWIwHaHK?w=165&h=180&c=7&r=0&o=5&pid=1.7" },
new Images() { Id = 3, ImgPath = "https://th.bing.com/th/id/OIP.XcJoJ6bC9sAMjol1pJn5UQHaLH?w=118&h=180&c=7&r=0&o=5&pid=1.7" },
new Images() { Id = 4, ImgPath = "https://th.bing.com/th/id/OIP.PPIESqZaNDa-qUcfSDXhdQHaGK?w=210&h=180&c=7&r=0&o=5&pid=1.7" },
new Images() { Id = 5, ImgPath = "https://th.bing.com/th/id/OIP.XBghSl2kfRNNtQoSxc901wHaHa?w=177&h=180&c=7&r=0&o=5&pid=1.7" },
new Images() { Id = 6, ImgPath = "https://th.bing.com/th/id/OIP.af1Aid64cqEKoIOBgCPxtQHaJO?w=145&h=182&c=7&r=0&o=5&pid=1.7" },
new Images() { Id = 7, ImgPath = "https://th.bing.com/th/id/OIP.ri5vSXr5lNTLt4DO6KQXyQHaI4?w=158&h=189&c=7&r=0&o=5&pid=1.7" },
new Images() { Id = 8, ImgPath = "https://th.bing.com/th/id/OIP.uPTRLR8uspCiafiunUqKfQHaMJ?w=115&h=180&c=7&r=0&o=5&pid=1.7" },
new Images() { Id = 9, ImgPath = "https://th.bing.com/th/id/OIP.hcJis4rKbyQtugsoFJU2ngHaM_?w=118&h=207&c=7&r=0&o=5&pid=1.7" },
new Images() { Id = 10, ImgPath = "https://th.bing.com/th/id/OIP.Py1_XfUrKJY_A6tYEmFS5wHaE8?w=280&h=187&c=7&r=0&o=5&pid=1.7" }
);
modelBuilder.Entity<Users>().HasData(
new Users() { Id = 1, Email = "jhonDhoe@gmail.com", Password = "1234", Created = new DateTime(2025, 5, 12), UserName = "Jhon-Dhoe", IdImage = 1 },
new Users() { Id = 2, Email = "lucy_rose@outlook.com", Password = "abcd", Created = new DateTime(2025, 3, 19), UserName = "Lucy-Rose", IdImage = 2 },
new Users() { Id = 3, Email = "mark.taylor@yahoo.com", Password = "5678", Created = new DateTime(2024, 11, 2), UserName = "Mark-Taylor", IdImage = 3 },
new Users() { Id = 4, Email = "sophie.martin@gmail.com", Password = "4321", Created = new DateTime(2025, 2, 28), UserName = "Sophie-Martin", IdImage = 4 },
new Users() { Id = 5, Email = "nathan_doe@aol.com", Password = "8765", Created = new DateTime(2025, 1, 15), UserName = "Nathan-Doe", IdImage = 5 },
new Users() { Id = 6, Email = "ella.brown@icloud.com", Password = "2468", Created = new DateTime(2025, 4, 7), UserName = "Ella-Brown", IdImage = 6 },
new Users() { Id = 7, Email = "oliver_smith@gmail.com", Password = "1357", Created = new DateTime(2024, 12, 25), UserName = "Oliver-Smith", IdImage = 7 },
new Users() { Id = 8, Email = "mia.jones@outlook.com", Password = "1122", Created = new DateTime(2025, 3, 5), UserName = "Mia-Jones", IdImage = 8 },
new Users() { Id = 9, Email = "kevin_williams@aol.com", Password = "2233", Created = new DateTime(2025, 2, 22), UserName = "Kevin-Williams", IdImage = 9 },
new Users() { Id = 10, Email = "olivia.white@yahoo.com", Password = "3344", Created = new DateTime(2025, 1, 3), UserName = "Olivia-White", IdImage = 10 }
);
modelBuilder.Entity<Character>().HasData(
new Character() { Id = 1 , Name = "Alan Grant", IdImage = 1},
new Character() { Id = 2, Name = "Aragorn", IdImage = 2 },
new Character() { Id = 3, Name = "Legolas", IdImage = 3 },
new Character() { Id = 4, Name = "Frodon", IdImage = 4 },
new Character() { Id = 5, Name = "Dobby", IdImage = 5 },
new Character() { Id = 6, Name = "Jon Snow", IdImage = 6 },
new Character() { Id = 7, Name = "Daenerys Targaryen", IdImage = 7 },
new Character() { Id = 8, Name = "Luke Skywalker", IdImage = 8 },
new Character() { Id = 9, Name = "Princess Leia", IdImage = 9 },
new Character() { Id = 10, Name = "Harry Potter", IdImage = 10 }
);
modelBuilder.Entity<Quote>().HasData(
new Quote() { Id = 1, Content = "Je n'y crois pas. Je n'y crois pas. Ce n'est pas possible", IdCharacter = 1, IdSource = 1, IdUsersPropose = 1, IsValid = true, Langage = LangEnum.vf, Likes = 11025 },
new Quote() { Id = 2, Content = "There is always hope", IdCharacter = 2, IdSource = 2, IdUsersPropose = 1, IsValid = true, Langage = LangEnum.vo, Likes = 11025 },
new Quote() { Id = 3, Content = "A red sun rises. Blood has been spilled this night.", IdCharacter = 3, IdSource = 2, IdUsersPropose = 1, IsValid = true, Langage = LangEnum.vo, Likes = 11025 },
new Quote() { Id = 4, Content = "I wish the Ring had never come to me.I wish none of this had happened.", IdCharacter = 4, IdSource = 2, IdUsersPropose = 1, IsValid = true, Langage = LangEnum.vo, Likes = 11025 },
new Quote() { Id = 5, Content = "Dobby is a free elf!", IdCharacter = 5, IdSource = 4, IdUsersPropose = 1, IsValid = true, Langage = LangEnum.vo, Likes = 11025 },
new Quote() { Id = 6, Content = "Winter is comming", IdCharacter = 6, IdSource = 3, IdUsersPropose = 1, IsValid = true, Langage = LangEnum.vo, Likes = 11025 },
new Quote() { Id = 7, Content = "Je suis la dernière Targaryen. Je suis la reine des dragons", IdCharacter = 7, IdSource = 3, IdUsersPropose = 1, IsValid = true, Langage = LangEnum.vf, Likes = 11025 },
new Quote() { Id = 8, Content = "Je ne suis pas prêt à affronter ça. C'est trop pour moi.", IdCharacter = 8, IdSource = 5, IdUsersPropose = 1, IsValid = true, Langage = LangEnum.vf, Likes = 11025 },
new Quote() { Id = 9, Content = "Aidez-moi, Obi-Wan Kenobi, vous êtes mon seul espoir.", IdCharacter = 9, IdSource = 5, IdUsersPropose = 1, IsValid = true, Langage = LangEnum.vf, Likes = 11025 },
new Quote() { Id = 10, Content = "La quoi ?", IdCharacter = 10, IdSource = 4, IdUsersPropose = 1, IsValid = false, Langage = LangEnum.vf, Likes = 11025 }
);
modelBuilder.Entity<Commentary>().HasData(
new Commentary() { Id = 1, Comment = "Ce film est le meilleur", DateCommentary = new DateTime(2025,2,3), IdQuote = 1, IdUser = 2 },
new Commentary() { Id = 2, Comment = "Very good", DateCommentary = new DateTime(2025, 3, 11), IdQuote = 1, IdUser = 3 }
);
modelBuilder.Entity<Favorite>().HasData(
new Favorite() { IdQuote = 2, IdUsers = 8 },
new Favorite() { IdQuote = 5, IdUsers = 3 },
new Favorite() { IdQuote = 9, IdUsers = 1 },
new Favorite() { IdQuote = 4, IdUsers = 10 },
new Favorite() { IdQuote = 3, IdUsers = 2 },
new Favorite() { IdQuote = 6, IdUsers = 7 },
new Favorite() { IdQuote = 1, IdUsers = 6 },
new Favorite() { IdQuote = 8, IdUsers = 9 },
new Favorite() { IdQuote = 10, IdUsers = 5 }
);
modelBuilder.Entity<Question>().HasData(
new Question() { Id = 1, Text = "Qui est le leader de la Communauté de l'Anneau ?", AnswerA = "Gimli", AnswerB = "Aragorn", AnswerC = "Frodon", AnswerD = "Gandalf", CorrectAnswer = "B", IsValid = true },
new Question() { Id = 2, Text = "Dans quelle maison Harry Potter est-il ?", AnswerA = "Serdaigle", AnswerB = "Gryffondor", AnswerC = "Serpentard", AnswerD = "Poufsouffle", CorrectAnswer = "B" },
new Question() { Id = 3, Text = "Qui est le Seigneur des Ténèbres dans la saga Le Seigneur des Anneaux ?", AnswerA = "Saroumane", AnswerB = "Sauron", AnswerC = "Gollum", AnswerD = "Gothmog", CorrectAnswer = "B", IsValid = true },
new Question() { Id = 4, Text = "Dans le film Star Wars : Episode IV, qui sauve Luke Skywalker de l'Étoile de la Mort ?", AnswerA = "Han Solo", AnswerB = "Princesse Leia", AnswerC = "Chewbacca", AnswerD = "R2-D2", CorrectAnswer = "A", IsValid = true },
new Question() { Id = 5, Text = "Qui est le souverain de Narnia dans Le Lion, la Sorcière Blanche et l'Armoire Magique ?", AnswerA = "Reine Jadis", AnswerB = "Aslan", AnswerC = "Edmund", AnswerD = "Lucy", CorrectAnswer = "B", IsValid = true },
new Question() { Id = 6, Text = "Quel est le nom du dragon dans Le Hobbit ?", AnswerA = "Smaug", AnswerB = "Falkor", AnswerC = "Norbert", AnswerD = "Shenron", CorrectAnswer = "A", IsValid = true },
new Question() { Id = 7, Text = "Qui est la première personne à être mordue par un vampire dans Twilight ?", AnswerA = "Bella Swan", AnswerB = "Edward Cullen", AnswerC = "Jacob Black", AnswerD = "Victoria", CorrectAnswer = "A", IsValid = true },
new Question() { Id = 8, Text = "Quel personnage dit Que la Force soit avec toi dans Star Wars ?", AnswerA = "Obi-Wan Kenobi", AnswerB = "Yoda", AnswerC = "Han Solo", AnswerD = "Luke Skywalker", CorrectAnswer = "A", IsValid = true },
new Question() { Id = 9, Text = "Dans Jurassic Park, quel est le nom du paléontologue sur l'île ?", AnswerA = "Dr. Ellie Sattler", AnswerB = "Alan Grant", AnswerC = "John Hammond", AnswerD = "Dennis Nedry", CorrectAnswer = "B", IsValid = true },
new Question() { Id = 10, Text = "Dans Game of Thrones, qui est surnommée la Mère des Dragons ?", AnswerA = "Cersei Lannister", AnswerB = "Arya Stark", AnswerC = "Daenerys Targaryen", AnswerD = "Sansa Stark", CorrectAnswer = "C", IsValid = true }
);
modelBuilder.Entity<Quiz>().HasData(
new Quiz() { Id = 1, IdImage = 1, Title = "Quiz 1", NbQuestion = 5 },
new Quiz() { Id = 2, IdImage = 2, Title = "Quiz 2", NbQuestion = 5 }
);
modelBuilder.Entity<QuizQuestion>().HasData(
new QuizQuestion() { IdQuestion = 1, IdQuiz = 1 },
new QuizQuestion() { IdQuestion = 2, IdQuiz = 1 },
new QuizQuestion() { IdQuestion = 3, IdQuiz = 1 },
new QuizQuestion() { IdQuestion = 4, IdQuiz = 1 },
new QuizQuestion() { IdQuestion = 5, IdQuiz = 1 },
new QuizQuestion() { IdQuestion = 6, IdQuiz = 2 },
new QuizQuestion() { IdQuestion = 7, IdQuiz = 2 },
new QuizQuestion() { IdQuestion = 8, IdQuiz = 2 },
new QuizQuestion() { IdQuestion = 9, IdQuiz = 2 },
new QuizQuestion() { IdQuestion = 10, IdQuiz = 2 }
);
modelBuilder.Entity<Source>().HasData(
new Source() { Id = 1, Title = "Jurassic Park", TypeSrc = TypeSrcEnum.movie, Year = 1993 },
new Source() { Id = 2, Title = "Le Seigneur des anneaux : La Communauté de l'anneau", TypeSrc = TypeSrcEnum.movie, Year = 2001 },
new Source() { Id = 3, Title = "Game of throne", TypeSrc = TypeSrcEnum.series, Year = 2011 },
new Source() { Id = 4, Title = "Harry Potter à l'école des sorcier", TypeSrc = TypeSrcEnum.movie, Year = 1997 },
new Source() { Id = 5, Title = "Star Wars, épisode IV : Un nouvel espoir", TypeSrc = TypeSrcEnum.movie, Year = 1977 }
);
}
public StubWTFContext()
{ }
public StubWTFContext(DbContextOptions<WTFContext> options)
: base(options)
{ }
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
if (!options.IsConfigured)
{
options.UseNpgsql("Host=WhatTheFantasy-wtf-api-test;Database=wtf-test;Username=test;Password=test;");
//options.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Wf-Database.mdf;Trusted_Connection=True;");
}
}
}
}

@ -6,4 +6,22 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.3" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.Design" Version="1.1.0" />
<PackageReference Include="NSwag.Core" Version="14.3.0" />
<PackageReference Include="NSwag.Core.Yaml" Version="14.3.0" />
<PackageReference Include="NSwag.Generation.AspNetCore" Version="14.3.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Contextlib\Contextlib.csproj" />
<ProjectReference Include="..\Entity\Entity.csproj" />
</ItemGroup>
</Project> </Project>

@ -0,0 +1,2 @@
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");

@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

@ -6,4 +6,15 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.3" />
<PackageReference Include="NSwag.Core" Version="14.3.0" />
<PackageReference Include="NSwag.Core.Yaml" Version="14.3.0" />
<PackageReference Include="NSwag.Generation.AspNetCore" Version="14.3.0" />
</ItemGroup>
</Project> </Project>

@ -1,27 +1,30 @@

Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17 # Visual Studio Version 17
VisualStudioVersion = 17.9.34723.18 VisualStudioVersion = 17.9.34723.18
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleTest", "ConsoleTest\ConsoleTest.csproj", "{A8B0E4D8-0726-4248-BB6D-DAA2545270B1}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleTest", "ConsoleTest\ConsoleTest.csproj", "{A8B0E4D8-0726-4248-BB6D-DAA2545270B1}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared", "Shared\Shared.csproj", "{792EF125-E2D4-457C-B536-BDAEFB49D14E}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Shared", "Shared\Shared.csproj", "{792EF125-E2D4-457C-B536-BDAEFB49D14E}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Entity", "Entity\Entity.csproj", "{69A4450C-AA43-4622-A866-9A5F7C8A2C14}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Entity", "Entity\Entity.csproj", "{69A4450C-AA43-4622-A866-9A5F7C8A2C14}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Contextlib", "Contextlib\Contextlib.csproj", "{32977454-CE94-4532-AE26-29F6951B78CF}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Contextlib", "Contextlib\Contextlib.csproj", "{32977454-CE94-4532-AE26-29F6951B78CF}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StubbedContextLib", "StubbedContextLib\StubbedContextLib.csproj", "{5CD69B14-C6AE-4628-A374-996C486E25F2}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StubbedContextLib", "StubbedContextLib\StubbedContextLib.csproj", "{5CD69B14-C6AE-4628-A374-996C486E25F2}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestModel2Entities", "TestModel2Entities\TestModel2Entities.csproj", "{2CF20FAC-C2F1-4048-9D46-F39081B0FBEF}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestModel2Entities", "TestModel2Entities\TestModel2Entities.csproj", "{2CF20FAC-C2F1-4048-9D46-F39081B0FBEF}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Entities", "Model\Entities.csproj", "{C51815EE-ED06-4F38-955E-7EBB72C0A7EF}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "XUnitTest", "XUnitTest\XUnitTest.csproj", "{48002CA2-7CFF-4077-90CF-392476320CE3}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Model2Entities", "Model2entities\Model2Entities.csproj", "{4A1CBA3D-C798-4E19-865F-39F919F1205A}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WfApi", "WfApi\WfApi.csproj", "{D4EEE1BF-CDCB-4E66-997B-7A5984DA7995}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XUnitTest", "XUnitTest\XUnitTest.csproj", "{48002CA2-7CFF-4077-90CF-392476320CE3}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StubApi", "StubApi\StubApi.csproj", "{4C5F324C-28C3-4153-B402-A07B099C24C6}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WfApi", "WfApi\WfApi.csproj", "{D4EEE1BF-CDCB-4E66-997B-7A5984DA7995}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DTO", "DTO\DTO.csproj", "{99F43B70-4143-4807-9EE7-B8A799B1E702}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dto2Entities", "Dto2Entities\Dto2Entities.csproj", "{08194729-E222-4C9A-B860-D944225B8895}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServicesApi", "ServicesApi\ServicesApi.csproj", "{6A9AC3D2-C1CD-450A-BD3C-22FAFC9B5328}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -53,14 +56,6 @@ Global
{2CF20FAC-C2F1-4048-9D46-F39081B0FBEF}.Debug|Any CPU.Build.0 = Debug|Any CPU {2CF20FAC-C2F1-4048-9D46-F39081B0FBEF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2CF20FAC-C2F1-4048-9D46-F39081B0FBEF}.Release|Any CPU.ActiveCfg = Release|Any CPU {2CF20FAC-C2F1-4048-9D46-F39081B0FBEF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2CF20FAC-C2F1-4048-9D46-F39081B0FBEF}.Release|Any CPU.Build.0 = Release|Any CPU {2CF20FAC-C2F1-4048-9D46-F39081B0FBEF}.Release|Any CPU.Build.0 = Release|Any CPU
{C51815EE-ED06-4F38-955E-7EBB72C0A7EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C51815EE-ED06-4F38-955E-7EBB72C0A7EF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C51815EE-ED06-4F38-955E-7EBB72C0A7EF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C51815EE-ED06-4F38-955E-7EBB72C0A7EF}.Release|Any CPU.Build.0 = Release|Any CPU
{4A1CBA3D-C798-4E19-865F-39F919F1205A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4A1CBA3D-C798-4E19-865F-39F919F1205A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4A1CBA3D-C798-4E19-865F-39F919F1205A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4A1CBA3D-C798-4E19-865F-39F919F1205A}.Release|Any CPU.Build.0 = Release|Any CPU
{48002CA2-7CFF-4077-90CF-392476320CE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {48002CA2-7CFF-4077-90CF-392476320CE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{48002CA2-7CFF-4077-90CF-392476320CE3}.Debug|Any CPU.Build.0 = Debug|Any CPU {48002CA2-7CFF-4077-90CF-392476320CE3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{48002CA2-7CFF-4077-90CF-392476320CE3}.Release|Any CPU.ActiveCfg = Release|Any CPU {48002CA2-7CFF-4077-90CF-392476320CE3}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -69,6 +64,22 @@ Global
{D4EEE1BF-CDCB-4E66-997B-7A5984DA7995}.Debug|Any CPU.Build.0 = Debug|Any CPU {D4EEE1BF-CDCB-4E66-997B-7A5984DA7995}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D4EEE1BF-CDCB-4E66-997B-7A5984DA7995}.Release|Any CPU.ActiveCfg = Release|Any CPU {D4EEE1BF-CDCB-4E66-997B-7A5984DA7995}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D4EEE1BF-CDCB-4E66-997B-7A5984DA7995}.Release|Any CPU.Build.0 = Release|Any CPU {D4EEE1BF-CDCB-4E66-997B-7A5984DA7995}.Release|Any CPU.Build.0 = Release|Any CPU
{4C5F324C-28C3-4153-B402-A07B099C24C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4C5F324C-28C3-4153-B402-A07B099C24C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4C5F324C-28C3-4153-B402-A07B099C24C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4C5F324C-28C3-4153-B402-A07B099C24C6}.Release|Any CPU.Build.0 = Release|Any CPU
{99F43B70-4143-4807-9EE7-B8A799B1E702}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{99F43B70-4143-4807-9EE7-B8A799B1E702}.Debug|Any CPU.Build.0 = Debug|Any CPU
{99F43B70-4143-4807-9EE7-B8A799B1E702}.Release|Any CPU.ActiveCfg = Release|Any CPU
{99F43B70-4143-4807-9EE7-B8A799B1E702}.Release|Any CPU.Build.0 = Release|Any CPU
{08194729-E222-4C9A-B860-D944225B8895}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{08194729-E222-4C9A-B860-D944225B8895}.Debug|Any CPU.Build.0 = Debug|Any CPU
{08194729-E222-4C9A-B860-D944225B8895}.Release|Any CPU.ActiveCfg = Release|Any CPU
{08194729-E222-4C9A-B860-D944225B8895}.Release|Any CPU.Build.0 = Release|Any CPU
{6A9AC3D2-C1CD-450A-BD3C-22FAFC9B5328}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6A9AC3D2-C1CD-450A-BD3C-22FAFC9B5328}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6A9AC3D2-C1CD-450A-BD3C-22FAFC9B5328}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6A9AC3D2-C1CD-450A-BD3C-22FAFC9B5328}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

@ -0,0 +1,135 @@
using System.Net;
using DTO;
using Entity;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Shared;
namespace WfApi.Controllers
{
[ApiController]
[Route("api/v1/character")] //Version API
public class CharacterController : ControllerBase
{
private readonly ICharacterService<CharacterDTO> _character;
private readonly ILogger<CharacterController> _logger;
public CharacterController(ICharacterService<CharacterDTO> characterService, ILogger<CharacterController> logger)
{
_character = characterService;
_logger = logger;
}
[HttpGet("{id}")] // Indiquer que l'id est dans l'URL
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetCharacter(int id)
{
try
{
try
{
var character = await _character.GetCharById(id);
return Ok(character);
}
catch(KeyNotFoundException)
{
return NotFound();
}
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" });
}
}
[HttpGet("all")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetAllSource(int index = 0, int count = 10)
{
try
{
var result = await _character.GetSomeChar(index, count);
if (result != null)
{
return await Task.FromResult<IActionResult>(Ok(result));
}
else
{
return NoContent();
}
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" });
}
}
[HttpPost]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status409Conflict)]
public async Task<IActionResult> CreateCharacter([FromBody] CharacterDTO newCharacter)
{
try
{
if (newCharacter == null)
{
return BadRequest(new { message = "Character data is required." });
}
try
{
var existingSource = await _character.GetCharById(newCharacter.Id);
return Conflict(new { message = "A character with this ID already exists." });
}
catch (KeyNotFoundException)
{
await _character.AddCharacter(newCharacter);
return Ok(newCharacter);
}
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" });
}
}
[HttpPut()]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status409Conflict)]
public async Task<IActionResult> UpdateCharacter([FromQuery] int id, [FromBody] CharacterDTO updatedCharacter)
{
try
{
if (updatedCharacter == null)
{
return BadRequest(new { message = "new character data is required." });
}
try
{
var existChar = await _character.GetCharById(id);
var result = _character.UpdateCharacter(id, updatedCharacter);
return Ok(result);
}
catch(KeyNotFoundException)
{
return Conflict(new { message = "A character with this ID already exists." });
}
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" });
}
}
}
}

@ -0,0 +1,108 @@
using System.Net;
using DTO;
using Entity;
using Microsoft.AspNetCore.Mvc;
using Shared;
namespace WfApi.Controllers
{
[ApiController]
[Route("api/v1/commentary")] //Version API
public class CommentariesController : ControllerBase
{
private readonly ICommentaryService<CommentaryDTO> _commentary;
private readonly ILogger<CommentariesController> _logger;
public CommentariesController(ICommentaryService<CommentaryDTO> commentaryService, ILogger<CommentariesController> logger)
{
_commentary = commentaryService;
_logger = logger;
}
[HttpGet("{id}")] // Indiquer que l'id est dans l'URL
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetCommentary(int id, int index = 0, int count = 5)
{
try
{
var result =await _commentary.GetCommentaryByQuote(id, index, count);
if (result != null)
{
return await Task.FromResult<IActionResult>(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<IActionResult> CreateCommentary([FromBody] CommentaryDTO newCommentary, int idQuote)
{
try
{
if (newCommentary == null)
{
return BadRequest(new { message = "Comment data is required." });
}
try
{
var existingCommentary = await _commentary.GetCommentaryById(newCommentary.Id);
return Conflict(new { message = "A comment with this ID already exists." });
}
catch (KeyNotFoundException e)
{
await _commentary.AddComment(newCommentary, idQuote);
return CreatedAtAction(nameof(GetCommentary), new { id = newCommentary.Id }, newCommentary);
}
}
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<IActionResult> DeleteCommentary([FromQuery] int id)
{
try
{
var existingCommentary = _commentary.GetCommentaryById(id).Result;
if (existingCommentary == null)
{
return NotFound(new { message = "Commentary not found." });
}
await _commentary.RemoveCommentary(existingCommentary.Id);
return Ok(new { message = $"Commentary {id} deleted successfully." });
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal server error." });
}
}
}
}

@ -0,0 +1,158 @@
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 FavoriteController : ControllerBase
{
private readonly IFavoriteService<QuoteDTO> _favorite;
private readonly ILogger<FavoriteController> _logger;
public FavoriteController(IFavoriteService<QuoteDTO> favoriteService, ILogger<FavoriteController> logger)
{
_favorite = favoriteService;
_logger = logger;
}
[HttpGet("{idUser}")] // Indiquer que l'id est dans l'URL
public async Task<IActionResult> GetFavoriteByIdUser(int idUser, int index = 0, int count = 10)
{
try
{
var result = await _favorite.GetFavoriteByIdUser(idUser, index, count);
if (result != null)
{
return await Task.FromResult<IActionResult>(Ok(result));
}
else
{
return NoContent();
}
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" });
}
}
[HttpGet()] // Indiquer que l'id est dans l'URL
public async Task<IActionResult> GetFavoriteByIdUser(int idUser , int idQuote)
{
try
{
var result = await _favorite.GetFavorite(idUser, idQuote);
if (result != null)
{
return await Task.FromResult<IActionResult>(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<IActionResult> 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<IActionResult> DeleteFavorite([FromQuery] int idUser, [FromQuery] int idQuote)
{
try
{
var existingFavorite = await _favorite.GetFavorite(idUser, idQuote);
if (existingFavorite == null)
{
return NotFound(new { message = "Favorite 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("alluser")] // /api/v1/commentary?id=51
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> DeleteAllFavoriteForUser([FromQuery] int idUser)
{
try
{
await _favorite.RemoveAllFavoriteForUser(idUser);
return Ok(new { message = $"Favorite from user {idUser} deleted successfully." });
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal server error." });
}
}
[HttpDelete("allquote")] // /api/v1/commentary?id=51
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> DeleteAllFavoriteForQuote([FromQuery] int idQuote)
{
try
{
await _favorite.RemoveAllFavoriteForQuote(idQuote);
return Ok(new { message = $"Favorite from quote {idQuote} deleted successfully." });
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal server error." });
}
}
}
}

@ -0,0 +1,141 @@
using DTO;
using System.Net;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Shared;
using Entity;
namespace WfApi.Controllers
{
[ApiController]
[Route("api/v1/image")] //Version API
public class ImageController : ControllerBase
{
private readonly IImagesService<ImageDTO> _img;
private readonly ILogger<ImageController> _logger;
public ImageController(IImagesService<ImageDTO> imgService, ILogger<ImageController> logger)
{
_img = imgService;
_logger = logger;
}
[HttpGet("{id}")] // Indiquer que l'id est dans l'URL
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetImageId(int id)
{
try
{
try
{
var image = await _img.GetImageById(id);
return Ok(image);
}
catch (KeyNotFoundException e)
{
return NotFound();
}
}
catch (Exception e)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error (" + e + ")" });
}
}
[HttpGet("all")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetAllImage(int index = 0, int count = 10)
{
try
{
var result = await _img.GetSomeImage(index, count);
if (result == null)
{
return NotFound();
}
return Ok(result);
}
catch (KeyNotFoundException e)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" });
}
}
[HttpPost]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> CreateImage([FromBody] ImageDTO newImage)
{
try
{
if(newImage == null)
{
return BadRequest(new { message = "Source data is required." });
}
try
{
var existImage = await _img.GetImageById(newImage.IdImage);
return Conflict(new { message = $"A Image with the ID {newImage.IdImage} already exists." });
}
catch(KeyNotFoundException e)
{
var existPath = await _img.GetImageByPath(newImage.ImagePath);
if(existPath == null)
{
await _img.AddImage(newImage);
return Ok(newImage);
}
return Conflict(new { message = $"A Image with the path {newImage.ImagePath} already exists." });
}
}
catch(Exception e)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" });
}
}
[HttpPut()]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> UpdateImage([FromQuery] int id, [FromBody] ImageDTO updatedImage)
{
try
{
if (updatedImage == null)
{
return BadRequest(new { message = "new source data is required." });
}
try
{
var existImage = await _img.GetImageById(id);
var existPath = await _img.GetImageByPath(updatedImage.ImagePath);
if (existPath == null)
{
await _img.UpdateImage(id, updatedImage);
return Ok(updatedImage);
}
return Conflict(new { message = $"A Image with the path {updatedImage.ImagePath} already exists." });
}
catch (KeyNotFoundException e)
{
return Conflict(new { message = $"A Image with the ID {id} dosen't exists." });
}
}
catch (Exception e)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error (" + e + ")" });
}
}
}
}

@ -0,0 +1,361 @@
using DTO;
using Entity;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Shared;
using System.Net;
namespace WfApi.Controllers
{
[ApiController]
[Route("api/v1/quote")] //Version API
public class QuotesController : ControllerBase
{
private readonly IQuoteService<QuoteDTO> _quote;
private readonly ILogger<UsersController> _logger;
public QuotesController(IQuoteService<QuoteDTO> quoteService, ILogger<UsersController> logger)
{
_quote = quoteService;
_logger = logger;
}
//===================================== ROUTE GET =====================================
[HttpGet("{id}")] // Indiquer que l'id est dans l'URL
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetQuote(int id)
{
try
{
var result = await _quote.GetQuoteById(id);
if (result!=null)
{
return Ok(result);
}
else
{
return NoContent();
}
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" });
}
}
[HttpGet("all")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetAllQuote([FromQuery] int index = 0, [FromQuery] int count = 10)
{
try
{
var result = await _quote.GetSomeQuote(index, count);
if (result != null)
{
return await Task.FromResult<IActionResult>(Ok(result));
}
else
{
return NoContent();
}
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" });
}
}
[HttpGet("allbylang")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetAllQuoteByLang([FromQuery] TypeLangageDTO lang, [FromQuery] int index = 0, [FromQuery] int count = 10)
{
try
{
var result = await _quote.GetAllQuoteLang(index, count,(int)lang);
if (result != null)
{
return await Task.FromResult<IActionResult>(Ok(result));
//return Ok(result));
}
else
{
return NoContent();
}
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" });
}
}
[HttpGet("dailyquote")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetDailyQuote([FromQuery] int year, [FromQuery] int month, [FromQuery] int day, [FromQuery] TypeLangageDTO lang)
{
try
{
DateOnly date = new DateOnly(year, month, day);
var result = await _quote.GetDailyQuote(date, (int)lang);
if (result != null)
{
return await Task.FromResult<IActionResult>(Ok(result));
}
else
{
return NoContent();
}
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" });
}
}
[HttpGet("invalid")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetInvalidQuote([FromQuery] TypeLangageDTO lang, [FromQuery] int index = 0, [FromQuery] int count = 10)
{
try
{
var result =await _quote.GetInvalidQuote(index, count, (int)lang);
if (result != null)
{
return await Task.FromResult<IActionResult>(Ok(result));
}
else
{
return NoContent();
}
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" });
}
}
[HttpGet("suggest")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetSuggestQuote([FromQuery] TypeLangageDTO lang, [FromQuery] int index = 0, [FromQuery] int count = 10)
{
try
{
var result = await _quote.GetSuggestions(index, count, (int)lang);
if (result != null)
{
return await Task.FromResult<IActionResult>(Ok(result));
}
else
{
return NoContent();
}
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" });
}
}
[HttpGet("searchByCharacter")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetQuoteSearchByCharacter([FromQuery] TypeLangageDTO lang, [FromQuery] string character, [FromQuery] int index = 0, [FromQuery] int count = 10)
{
try
{
var result = await _quote.SearchByCharacter(character, index, count, (int)lang);
if (result != null)
{
return await Task.FromResult<IActionResult>(Ok(result));
}
else
{
return NoContent();
}
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" });
}
}
[HttpGet("searchBySource")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetQuoteSearchBySource([FromQuery] TypeLangageDTO lang, [FromQuery] string source, [FromQuery] int index = 0, [FromQuery] int count = 10)
{
try
{
var result = await _quote.SearchBySource(source, index, count, (int)lang);
if (result != null)
{
return await Task.FromResult<IActionResult>(Ok(result));
}
else
{
return NoContent();
}
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" });
}
}
[HttpGet("searchByContent")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetQuoteSearchByContent([FromQuery] TypeLangageDTO lang, [FromQuery] string content, [FromQuery] int index = 0, [FromQuery] int count = 10)
{
try
{
var result =await _quote.SearchByContent(content, index, count, (int)lang);
if (result != null)
{
return await Task.FromResult<IActionResult>(Ok(result));
}
else
{
return NoContent();
}
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" });
}
}
//===================================== ROUTE POST =====================================
[HttpPost]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> CreateQuote([FromBody] QuoteDTO newQuote)
{
try
{
try
{
if (newQuote == null)
{
return BadRequest(new { message = "Les données de la quote sont requises." });
}
if (await _quote.GetQuoteById(newQuote.Id) != null)
{
return Conflict(new { message = "Une quote avec cet ID existe déjà." });
}
newQuote.IsValide=false;
var quote=await _quote.AddQuote(newQuote);
return CreatedAtAction(nameof(CreateQuote), new { id = newQuote.Id }, quote);
}
catch (KeyNotFoundException e)
{
return StatusCode((int)HttpStatusCode.NotFound, e);
}
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Erreur interne du serveur." });
}
}
//===================================== ROUTE PUT =====================================
[HttpPut()]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> UpdateQuote([FromQuery] int id, [FromBody] QuoteDTO updatedquote)
{
try
{
if (updatedquote == null)
{
return BadRequest(new { message = "Quote data is required." });
}
var result = _quote.UpdateQuote(id, updatedquote);
return Ok(result);
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal server error." });
}
}
[HttpPut("valide")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> ValideQuote([FromQuery] int id)
{
try
{
var updatedquote = _quote.GetQuoteById(id).Result;
if (updatedquote == null)
{
return BadRequest(new { message = "Id Quote is underfined." });
}
updatedquote.IsValide = true;
var result = _quote.UpdateQuote(id, updatedquote);
return Ok(result);
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal server error." });
}
}
//===================================== ROUTE DELETE =====================================
[HttpDelete("delete")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> DeleteQuote([FromQuery] int idQuote)
{
try {
try
{
_quote.RemoveQuote(idQuote).Wait();
return await Task.FromResult<IActionResult>(Ok());
}
catch (KeyNotFoundException e)
{
return StatusCode((int)HttpStatusCode.NotFound, e);
}
}
catch (Exception)
{
return StatusCode((int) HttpStatusCode.InternalServerError, new { message = "Erreur interne du serveur." });
}
}
}
}

@ -0,0 +1,125 @@
using System.Net;
using DTO;
using Entity;
using Microsoft.AspNetCore.Mvc;
using Shared;
namespace WfApi.Controllers
{
[Route("api/v1/source")]
[ApiController]
public class SourceController : ControllerBase
{
private readonly ISourceService<SourceDTO> _source;
private readonly ILogger<SourceController> _logger;
public SourceController(ISourceService<SourceDTO> sourceService, ILogger<SourceController> logger)
{
_source = sourceService;
_logger = logger;
}
[HttpGet("{id}")] // Indiquer que l'id est dans l'URL
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetSource(int id)
{
try
{
var source = await _source.GetSourceById(id);
if(source != null)
{
return Ok(source);
}
else
{
return NoContent();
}
}
catch(Exception e)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error (" + e + ")" });
}
}
[HttpGet("all")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetAllSource(int index = 0, int count = 10)
{
try
{
var result = await _source.GetSomesSource(index, count);
if (result != null)
{
return await Task.FromResult<IActionResult>(Ok(result));
}
else
{
return NoContent();
}
}
catch (Exception e)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error (" + e + ")" });
}
}
[HttpPost]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> CreateSource([FromBody] SourceDTO newSource)
{
try
{
if(newSource == null)
{
return BadRequest(new { message = "Source data is required." });
}
try
{
var existingSource = await _source.GetSourceById(newSource.Id);
return Conflict(new { message = "A source with this ID already exists." });
}
catch(KeyNotFoundException e)
{
await _source.AddSource(newSource);
return CreatedAtAction(nameof(GetAllSource), new { id = newSource.Id }, newSource);
}
}
catch (Exception e)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error (" + e + ")" });
}
}
[HttpPut()]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> UpdateSource([FromQuery] int id, [FromBody] SourceDTO updatedSource)
{
try
{
if (updatedSource == null)
{
return BadRequest(new { message = "new source data is required." });
}
var result = _source.UpdateSource(id, updatedSource);
return Ok(result);
}
catch (Exception e)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error (" + e + ")" });
}
}
}
}

@ -0,0 +1,673 @@
using DTO;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Shared;
using System.Net;
namespace WfApi.Controllers
{
[ApiController]
[Route("api/v1/users")] //Version API
public class UsersController : ControllerBase
{
private readonly IUserService<UserDTO> _user;
private readonly ILogger<UsersController> _logger;
public UsersController(IUserService<UserDTO> userService, ILogger<UsersController> logger)
{
_user = userService;
_logger = logger;
}
//===================================== ROUTE GET =====================================
/// <summary>
/// Gets a user by their unique identifier.
/// </summary>
/// <param name="id">The unique identifier of the user</param>
/// <returns></returns>
/// <remarks>
/// ## **Sample request**:
///
/// GET /users/{id}
///
/// Where `{id}` is the unique identifier of the user you want to retrieve.
///
/// ## **Returns**
///
/// - **200 OK** : Returns the user data if the user with the given ID exists.
/// - **204 No Content** : No user found for the provided ID, or the operation failed.
/// - **500 Internal Server Error** : If there is an exception during the process.
///
/// ## **Error Handling**
/// - In case of an internal server error (e.g., database issues), a `500 Internal Server Error` will be returned with an error message.
/// </remarks>
/// <response code="200">Returns the user data corresponding to the provided ID</response>
/// <response code="204">No content if no user is found or the operation fails</response>
/// <response code="500">Internal server error in case of an exception</response>
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[HttpGet("{id}")] // Indiquer que l'id est dans l'URL
public async Task<IActionResult> Get(int id)
{
try
{
var result =await _user.GetUserById(id);
if (result != null)
{
return await Task.FromResult<IActionResult>(Ok(result));
}
else
{
return NoContent();
}
}
catch (Exception e)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" +e.Message + " --- " + Environment.GetEnvironmentVariable("DB_SERVER_AUTH") });
}
}
/// <summary>
/// Gets a list of users with pagination support.
/// </summary>
/// <param name="index">The index of the page to retrieve (default is 0)</param>
/// <param name="count">The number of users to retrieve per page (default is 5)</param>
/// <returns></returns>
/// <remarks>
/// ## **Sample request**:
///
/// GET /users/all?index=0&count=5
///
/// The `index` parameter specifies the page number to retrieve (starting from 0), and the `count` parameter specifies how many users to return per page.
///
/// ## **Returns**
///
/// - **200 OK** : Returns a list of users if the operation is successful.
/// - **204 No Content** : If no users are found or the operation fails.
/// - **500 Internal Server Error** : If there is an exception during the execution of the request.
///
/// ## **Error Handling**
/// - In case of an internal server error (e.g., database issues), a `500 Internal Server Error` is returned with an error message.
/// </remarks>
/// <response code="200">Returns a list of users</response>
/// <response code="204">No content if no users are found or the operation fails</response>
/// <response code="500">Internal server error in case of an exception</response>
[HttpGet("all")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetAllUsers(int index = 0, int count = 5)
{
try
{
var result =await _user.GetSomeUser(index, count);
if (result != null)
{
return await Task.FromResult<IActionResult>(Ok(result));
}
else
{
return NoContent();
}
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" });
}
}
/// <summary>
/// Gets the hashed password for a given username.
/// </summary>
/// <param name="username">The username to retrieve the hashed password for</param>
/// <returns></returns>
/// <remarks>
/// ## **Sample request**:
///
/// GET /users/hashpassword?username=johndoe
///
/// The `username` parameter specifies the username for which to retrieve the hashed password.
///
/// ## **Returns**
///
/// - **200 OK** : Returns the hashed password for the user if the username exists.
/// - **400 Bad Request** : If no username is provided or if the username is invalid.
/// - **204 No Content** : If no hashed password is found for the provided username.
/// - **500 Internal Server Error** : If an exception occurs while processing the request.
///
/// ## **Error Handling**
/// - In case of a missing or invalid `username`, a `400 Bad Request` is returned with a relevant message.
/// - If there is an exception during the process (e.g., database errors), a `500 Internal Server Error` is returned.
/// </remarks>
/// <response code="200">Returns the hashed password for the provided username</response>
/// <response code="400">Bad request if no username is provided or invalid</response>
/// <response code="204">No content if no hashed password is found</response>
/// <response code="500">Internal server error in case of an exception</response>
[HttpGet("hashpassword")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetHashPassword([FromQuery] string username)
{
if (string.IsNullOrWhiteSpace(username))
{
return BadRequest(new { message = "No user defined" });
}
try
{
var result =await _user.GetHashPassword(username);
if (result != null)
{
return await Task.FromResult<IActionResult>(Ok(result));
}
else
{
return NoContent();
}
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" });
}
}
/// <summary>
/// Gets a user by their username.
/// </summary>
/// <param name="username">The username to retrieve the user</param>
/// <returns></returns>
/// <remarks>
/// ## **Sample request**:
///
/// GET /users/username?username=johndoe
///
/// The `username` parameter specifies the username of the user you want to retrieve.
///
/// ## **Returns**
///
/// - **200 OK** : Returns the user data if the username exists.
/// - **400 Bad Request** : If no username is provided or if the username is invalid.
/// - **204 No Content** : If no user is found with the provided username.
/// - **500 Internal Server Error** : If an exception occurs while processing the request.
///
/// ## **Error Handling**
/// - In case of a missing or invalid `username`, a `400 Bad Request` is returned with a relevant message.
/// - If there is an exception during the process (e.g., database errors), a `500 Internal Server Error` is returned.
/// </remarks>
/// <response code="200">Returns the user data for the provided username</response>
/// <response code="400">Bad request if no username is provided or invalid</response>
/// <response code="204">No content if no user is found with the provided username</response>
/// <response code="500">Internal server error in case of an exception</response>
[HttpGet("username")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetUserByUsername([FromQuery] string username)
{
if (string.IsNullOrWhiteSpace(username))
{
return BadRequest(new { message = "No user defined" });
}
try
{
var result =await _user.GetUserByUsername(username);
if (result != null)
{
return await Task.FromResult<IActionResult>(Ok(result));
}
else
{
return NoContent();
}
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" });
}
}
/// <summary>
/// Gets a user by their email address.
/// </summary>
/// <param name="email">The email address of the user</param>
/// <returns></returns>
/// <remarks>
/// ## **Sample request**:
///
/// GET /users/email?email=johndoe@example.com
///
/// The `email` parameter specifies the email address of the user you want to retrieve.
///
/// ## **Returns**
///
/// - **200 OK** : Returns the user data if the email exists.
/// - **400 Bad Request** : If no email is provided or if the email is invalid.
/// - **204 No Content** : If no user is found with the provided email.
/// - **500 Internal Server Error** : If an exception occurs while processing the request.
///
/// ## **Error Handling**
/// - In case of a missing or invalid `email`, a `400 Bad Request` is returned with a relevant message.
/// - If there is an exception during the process (e.g., database errors), a `500 Internal Server Error` is returned.
/// </remarks>
/// <response code="200">Returns the user data for the provided email</response>
/// <response code="400">Bad request if no email is provided or invalid</response>
/// <response code="204">No content if no user is found with the provided email</response>
/// <response code="500">Internal server error in case of an exception</response>
[HttpGet("email")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetUserByEmail([FromQuery] string email)
{
if (string.IsNullOrWhiteSpace(email))
{
return BadRequest(new { message = "No user email defined" });
}
try
{
var result =await _user.GetUserByEmail(email);
if (result != null)
{
return await Task.FromResult<IActionResult>(Ok(result));
}
else
{
return NoContent();
}
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" });
}
}
/// <summary>
/// Gets the total number of users.
/// </summary>
/// <returns></returns>
/// <remarks>
/// ## **Sample request**:
///
/// GET /users/count
///
/// This endpoint returns the total number of users present in the system.
///
/// ## **Returns**
///
/// - **200 OK** : Returns the total count of users.
/// - **204 No Content** : If no users are found or the operation fails.
/// - **500 Internal Server Error** : If an exception occurs while processing the request.
///
/// ## **Error Handling**
/// - In case of an exception during the process (e.g., database errors), a `500 Internal Server Error` is returned with a relevant message.
/// </remarks>
/// <response code="200">Returns the total count of users</response>
/// <response code="204">No content if the count could not be retrieved</response>
/// <response code="500">Internal server error in case of an exception</response>
[HttpGet("count")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetCountUser()
{
try
{
var result =await _user.CountUser();
if (result!=null)
{
return await Task.FromResult<IActionResult>(Ok(result));
}
else
{
return NoContent();
}
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" });
}
}
/// <summary>
/// Checks if a user exists by their username.
/// </summary>
/// <param name="username">The username to check for existence</param>
/// <returns></returns>
/// <remarks>
/// ## **Sample request**:
///
/// GET /users/existusername?username=johndoe
///
/// The `username` parameter specifies the username to check if it exists in the system.
///
/// ## **Returns**
///
/// - **200 OK** : If the username exists, returns a success message.
/// - **400 Bad Request** : If no username is provided or if the username is invalid.
/// - **404 Not Found** : If the user with the specified username does not exist.
/// - **500 Internal Server Error** : If an exception occurs while processing the request.
///
/// ## **Error Handling**
/// - In case of a missing or invalid `username`, a `400 Bad Request` is returned with a relevant message.
/// - If the user does not exist, a `404 Not Found` response is returned.
/// - If there is an exception during the process (e.g., database errors), a `500 Internal Server Error` is returned with an appropriate message.
/// </remarks>
/// <response code="200">Returns a success message if the username exists</response>
/// <response code="400">Bad request if no username is provided or invalid</response>
/// <response code="404">Not found if the user with the provided username does not exist</response>
/// <response code="500">Internal server error in case of an exception</response>
[HttpGet("existusername")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetExistUsername([FromQuery] string username)
{
if (string.IsNullOrWhiteSpace(username))
{
return BadRequest(new { message = "No user defined" });
}
try
{
var result =await _user.ExistUsername(username);
if (result!=null)
{
return await Task.FromResult<IActionResult>(Ok(result));
}
else
{
return NotFound("User not found");
}
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" });
}
}
/// <summary>
/// Checks if a user exists by their email address.
/// </summary>
/// <param name="email">The email address to check for existence</param>
/// <returns></returns>
/// <remarks>
/// ## **Sample request**:
///
/// GET /users/existemail?email=johndoe@example.com
///
/// The `email` parameter specifies the email address to check if it exists in the system.
///
/// ## **Returns**
///
/// - **200 OK** : If the email exists, returns a success message.
/// - **400 Bad Request** : If no email is provided or if the email is invalid.
/// - **404 Not Found** : If the user with the specified email does not exist.
/// - **500 Internal Server Error** : If an exception occurs while processing the request.
///
/// ## **Error Handling**
/// - In case of a missing or invalid `email`, a `400 Bad Request` is returned with a relevant message.
/// - If the user does not exist, a `404 Not Found` response is returned.
/// - If there is an exception during the process (e.g., database errors), a `500 Internal Server Error` is returned with an appropriate message.
/// </remarks>
/// <response code="200">Returns a success message if the email exists</response>
/// <response code="400">Bad request if no email is provided or invalid</response>
/// <response code="404">Not found if the user with the provided email does not exist</response>
/// <response code="500">Internal server error in case of an exception</response>
[HttpGet("existemail")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetExistEmail([FromQuery] string email)
{
if (string.IsNullOrWhiteSpace(email))
{
return BadRequest(new { message = "No user email defined" });
}
try
{
var result =await _user.ExistEmail(email);
if (result!=null)
{
return await Task.FromResult<IActionResult>(Ok(result));
}
else
{
return NotFound("User email not found");
}
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal Server Error" });
}
}
//===================================== ROUTE PUT =====================================
/// <summary>
/// Updates an existing user's data.
/// </summary>
/// <param name="id">The ID of the user to update</param>
/// <param name="updateduser">The updated user data</param>
/// <returns></returns>
/// <remarks>
/// ## **Sample request**:
///
/// PUT /users?id=1
/// Body:
/// {
/// "username": "newusername",
/// "email": "newemail@example.com",
/// "fullName": "New Name"
/// }
///
/// The `id` parameter specifies the user ID to be updated, and the body contains the updated user data.
///
/// ## **Returns**
///
/// - **200 OK** : If the user was successfully updated.
/// - **400 Bad Request** : If the provided user data is invalid or missing.
/// - **500 Internal Server Error** : If an error occurs while processing the update.
///
/// ## **Error Handling**
/// - If the `updateduser` object is `null`, a `400 Bad Request` is returned with a message indicating that player data is required.
/// - If an exception occurs during the process (e.g., database errors), a `500 Internal Server Error` is returned with an appropriate message.
/// </remarks>
/// <response code="200">Returns the updated user data</response>
/// <response code="400">Bad request if no user data is provided or invalid</response>
/// <response code="500">Internal server error in case of an exception</response>
[HttpPut()]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> UpdateUser([FromQuery] int id, [FromBody] UserDTO updateduser)
{
try
{
if (updateduser == null)
{
return BadRequest(new { message = "Player data is required." });
}
var result = _user.UpdateUser(id,updateduser);
return Ok(result);
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal server error." });
}
}
[HttpPut("lang")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> UpdateUserLang([FromQuery] int id, [FromBody] TypeLangageDTO lang)
{
try
{
var updateduser=await _user.GetUserById(id);
if (updateduser == null)
{
return BadRequest(new { message = "Player no found." });
}
updateduser.Lang = lang;
var result = _user.UpdateUser(id, updateduser);
return Ok(result);
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal server error." });
}
}
//===================================== ROUTE POST =====================================
/// <summary>
/// Creates a new user in the system.
/// </summary>
/// <param name="newUser">The user data to create the new user</param>
/// <returns></returns>
/// <remarks>
/// ## **Sample request**:
///
/// POST /users
/// Body:
/// {
/// "id": 123,
/// "username": "newuser",
/// "email": "newuser@example.com",
/// "fullName": "New User"
/// }
///
/// The `newUser` parameter in the body contains the data of the new user to be created.
///
/// ## **Returns**
///
/// - **201 Created** : If the user was successfully created. The location of the created resource is returned in the response header.
/// - **400 Bad Request** : If the provided user data is invalid or missing.
/// - **409 Conflict** : If a user with the specified ID already exists.
/// - **500 Internal Server Error** : If an error occurs while processing the creation of the user.
///
/// ## **Error Handling**
/// - If the `newUser` object is `null`, a `400 Bad Request` is returned with a message indicating that user data is required.
/// - If the user already exists (based on `Id`), a `409 Conflict` is returned with a message indicating that a user with this ID already exists.
/// - If there is an exception during the process (e.g., database errors), a `500 Internal Server Error` is returned with an appropriate message.
/// </remarks>
/// <response code="201">Returns the created user and its location</response>
/// <response code="400">Bad request if no user data is provided or invalid</response>
/// <response code="409">Conflict if a user with the same ID already exists</response>
/// <response code="500">Internal server error in case of an exception</response>
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status409Conflict)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> CreateUser([FromBody] UserDTO newUser)
{
try
{
if (newUser == null)
{
return BadRequest(new { message = "User data is required." });
}
try
{
var existingPlayer = await _user.GetUserById(newUser.Id);
return Conflict(new { message = "A user with this ID already exists." });
}
catch(KeyNotFoundException e)
{
_user.AddUser(newUser);
return CreatedAtAction(nameof(GetAllUsers), new { id = newUser.Id }, newUser);
}
}
catch (Exception e)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Erreur interne du serveur." + e.Message });
}
}
//===================================== ROUTE DELETE =====================================
/// <summary>
/// Deletes a player by their ID.
/// </summary>
/// <param name="id">The ID of the player to be deleted</param>
/// <returns></returns>
/// <remarks>
/// ## **Sample request**:
///
/// DELETE /api/v1/players?id=51
///
/// The `id` parameter specifies the ID of the player to be deleted.
///
/// ## **Returns**
///
/// - **200 OK** : If the player was successfully deleted, a success message is returned.
/// - **404 Not Found** : If no player with the given ID is found.
/// - **500 Internal Server Error** : If an error occurs while deleting the player.
///
/// ## **Error Handling**
/// - If no player is found with the specified `id`, a `404 Not Found` response is returned with a message "Player not found."
/// - If there is an exception during the process (e.g., database errors), a `500 Internal Server Error` response is returned with a message "Internal server error."
/// </remarks>
/// <response code="200">Returns a success message indicating the player was deleted</response>
/// <response code="404">Not found if no player with the specified ID is found</response>
/// <response code="500">Internal server error in case of an exception</response>
[HttpDelete] // /api/v1/players?id=51
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> DeletePlayer([FromQuery] int id)
{
try
{
var existingPlayer = _user.GetUserById(id).Result;
if (existingPlayer == null)
{
return NotFound(new { message = "Player not found." });
}
await _user.RemoveUser(id);
return Ok(new { message = $"User {id} deleted successfully." });
}
catch (Exception)
{
return StatusCode((int)HttpStatusCode.InternalServerError, new { message = "Internal server error." });
}
}
}
}

@ -1,33 +0,0 @@
using Microsoft.AspNetCore.Mvc;
namespace WfApi.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}
}

@ -1,8 +1,66 @@
using DTO;
using Shared;
using StubApi;
using Contextlib;
using Entity;
using StubbedContextLib;
using ServicesApi;
using Microsoft.EntityFrameworkCore;
//API
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
builder.Services.AddScoped<IUserService<UserDTO>, UserService>();
builder.Services.AddScoped<IQuoteService<QuoteDTO>, QuoteService>();
builder.Services.AddScoped<IFavoriteService<QuoteDTO>, FavoriteService>();
builder.Services.AddScoped<ICommentaryService<CommentaryDTO>, CommentaryService>();
builder.Services.AddScoped<ICharacterService<CharacterDTO>, CharacterService>();
builder.Services.AddScoped<IImagesService<ImageDTO>, ImageService>();
builder.Services.AddScoped<ISourceService<SourceDTO>, SourceService>();
builder.Services.AddScoped<IQuestionService<QuestionDTO>, QuestionService>();
//EF
builder.Services.AddScoped<WTFContext, StubWTFContext>();
builder.Services.AddScoped<IUserService<Users>, DbUsersManager>();
builder.Services.AddScoped<IQuoteService<Quote>, DbQuoteManager>();
builder.Services.AddScoped<IFavoriteService<Quote>, DbFavoriteManager>();
builder.Services.AddScoped<ICommentaryService<Commentary>, DbCommentaryManager>();
builder.Services.AddScoped<ICharacterService<Character>, DbCharacterManager>();
builder.Services.AddScoped<IImagesService<Images>, DbImagesManager>();
builder.Services.AddScoped<ISourceService<Source>, DbSourceManager>();
builder.Services.AddScoped<IQuestionService<Question>, DbQuestionManager>();
//...
// Add services to the container. // Add services to the container.
builder.Services.AddControllers(); builder.Services.AddControllers();
builder.Services.AddOpenApiDocument(options => {
options.PostProcess = document =>
{
document.Info = new NSwag.OpenApiInfo
{
Version = "v1",
Title = "What The Fantasy's API",
Description = "What The Fantasy Site API",
TermsOfService = "",
Contact = new NSwag.OpenApiContact
{
Name = "The PM Mobile What The Fantasy team",
Url = ""
},
License = new NSwag.OpenApiLicense
{
Name = "No license",
Url = "https://license.fr"
}
};
};
});
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer(); builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(); builder.Services.AddSwaggerGen();
@ -12,7 +70,7 @@ var app = builder.Build();
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment()) if (app.Environment.IsDevelopment())
{ {
app.UseSwagger(); app.UseOpenApi(); // Active la documentation OpenAPI
app.UseSwaggerUI(); app.UseSwaggerUI();
} }

@ -1,13 +0,0 @@
namespace WfApi
{
public class WeatherForecast
{
public DateOnly Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string? Summary { get; set; }
}
}

@ -6,11 +6,32 @@
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>283a610b-b95e-4b09-af22-b7d3270a917d</UserSecretsId> <UserSecretsId>283a610b-b95e-4b09-af22-b7d3270a917d</UserSecretsId>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS> <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.3" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.6" /> <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.6" />
<PackageReference Include="NSwag.AspNetCore" Version="14.2.0" />
<PackageReference Include="NSwag.Core" Version="14.3.0" />
<PackageReference Include="NSwag.Core.Yaml" Version="14.3.0" />
<PackageReference Include="NSwag.Generation.AspNetCore" Version="14.3.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Contextlib\Contextlib.csproj" />
<ProjectReference Include="..\DTO\DTO.csproj" />
<ProjectReference Include="..\Entity\Entity.csproj" />
<ProjectReference Include="..\ServicesApi\ServicesApi.csproj" />
<ProjectReference Include="..\Shared\Shared.csproj" />
<ProjectReference Include="..\StubApi\StubApi.csproj" />
<ProjectReference Include="..\StubbedContextLib\StubbedContextLib.csproj" />
</ItemGroup>
</Project> </Project>

@ -0,0 +1,283 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Moq;
using WfApi.Controllers;
using Shared;
using DTO;
namespace XUnitTest
{
public class UnitTest1
{
//private readonly Mock<IUserService<UserDTO>> _mockUserService;
//private readonly Mock<ILogger<UsersController>> _mockLogger;
//private readonly UsersController _userController;
//public UnitTest1()
//{
// // Initialisation des mocks
// _mockUserService = new Mock<IUserService<UserDTO>>();
// _mockLogger = new Mock<ILogger<UsersController>>();
// _userController = new UsersController(_mockUserService.Object, _mockLogger.Object);
//}
//[Fact]
//public async Task Get_ReturnsOk_WhenUserExists()
//{
// // Arrange
// var userId = 1;
// var userDTO = new UserDTO
// {
// Id = userId,
// Pseudo = "test",
// Email = "test@unitaire.fr",
// ImageProfil = "http://test",
// Password = "1234"
// };
// _mockUserService.Setup(service => service.GetUserById(userId)).ReturnsAsync(userDTO);
// // Act
// var result = await _userController.Get(userId);
// // Assert
// Assert.IsType<OkObjectResult>(result);
//}
//[Fact]
//public async Task GetAllUsers_ReturnsOk()
//{
// // Arrange
// var userDTO = new UserDTO
// {
// Id = 1,
// Pseudo = "test",
// Email = "test@unitaire.fr",
// ImageProfil = "http://test",
// Password = "1234"
// };
// var userDTO2 = new UserDTO
// {
// Id = 2,
// Pseudo = "test",
// Email = "test@unitaire.fr",
// ImageProfil = "http://test",
// Password = "1234"
// };
// _mockUserService.Setup(service => service.GetUserById(1)).ReturnsAsync(userDTO);
// _mockUserService.Setup(service => service.GetUserById(2)).ReturnsAsync(userDTO);
// // Act
// var result = await _userController.GetAllUsers();
// // Assert
// Assert.IsType<OkObjectResult>(result);
//}
//[Fact]
//public async Task GetHashPassword_ReturnsOk_WhenPasswordHashIsFound()
//{
// // Arrange
// var username = "testUser";
// var expectedHash = "hashedPassword";
// var taskResult = Task.FromResult(expectedHash);
// _mockUserService.Setup(service => service.GetHashPassword(username)).Returns(taskResult);
// // Act
// var result = await _userController.GetHashPassword(username);
// // Assert
// Assert.IsType<OkObjectResult>(result);
//}
//[Fact]
//public async Task GetUserByUsername_ReturnsOk_WhenPasswordHashIsFound()
//{
// // Arrange
// var username = "testUser";
// var userDTO = new UserDTO
// {
// Id = 1,
// Pseudo = "testUser",
// Email = "test@unitaire.fr",
// ImageProfil = "http://test",
// Password = "1234"
// };
// var taskResult = Task.FromResult(userDTO);
// _mockUserService.Setup(service => service.GetUserByUsername(username)).Returns(taskResult);
// // Act
// var result = await _userController.GetUserByUsername(username);
// // Assert
// Assert.IsType<OkObjectResult>(result);
//}
//[Fact]
//public async Task GetUserByEmail_ReturnsOk_WhenUserExists()
//{
// // Arrange
// var email = "test@unitaire.fr";
// var userDTO = new UserDTO
// {
// Id = 1,
// Pseudo = "testUser",
// Email = email,
// ImageProfil = "http://test",
// Password = "1234"
// };
// var taskResult = Task.FromResult(userDTO);
// _mockUserService.Setup(service => service.GetUserByEmail(email)).Returns(taskResult);
// // Act
// var result = await _userController.GetUserByEmail(email);
// // Assert
// Assert.IsType<OkObjectResult>(result);
//}
//[Fact]
//public async Task GetCountUser_ReturnsOk_WhenCountIsSuccessful()
//{
// // Arrange
// var expectedCount = 5;
// var taskResult = Task.FromResult(expectedCount);
// _mockUserService.Setup(service => service.CountUser()).Returns(taskResult);
// // Act
// var result = await _userController.GetCountUser();
// // Assert
// Assert.IsType<OkObjectResult>(result);
//}
//[Fact]
//public async Task GetExistUsername_ReturnsOk_WhenUserExists()
//{
// // Arrange
// var username = "testUser";
// var taskResult = Task.FromResult(true);
// _mockUserService.Setup(service => service.ExistUsername(username)).Returns(taskResult);
// // Act
// var result = await _userController.GetExistUsername(username);
// // Assert
// Assert.IsType<OkObjectResult>(result);
//}
//[Fact]
//public async Task GetExistEmail_ReturnsOk_WhenEmailExists()
//{
// // Arrange
// var email = "test@unitaire.fr";
// var taskResult = Task.FromResult(true);
// _mockUserService.Setup(service => service.ExistEmail(email)).Returns(taskResult);
// // Act
// var result = await _userController.GetExistEmail(email);
// // Assert
// Assert.IsType<OkObjectResult>(result);
//}
//[Fact]
//public async Task UpdateUser_ReturnsOk_WhenUserDataIsValid()
//{
// // Arrange
// var id = 1;
// var updatedUser = new UserDTO
// {
// Id = id,
// Pseudo = "UpdatedUser",
// Email = "updated@unitaire.fr",
// ImageProfil = "http://updatedImage.com",
// Password = "newPassword123"
// };
// var taskResult = Task.FromResult(updatedUser);
// _mockUserService.Setup(service => service.UpdateUser(id, updatedUser)).Returns(taskResult);
// // Act
// var result = await _userController.UpdateUser(id, updatedUser);
// // Assert
// var okResult = Assert.IsType<OkObjectResult>(result);
// Assert.IsType<OkObjectResult>(result);
//}
//[Fact]
//public async Task CreateUser_ReturnsCreatedAtAction_WhenUserIsValid()
//{
// // Arrange
// var newUser = new UserDTO
// {
// Id = 2,
// Pseudo = "NewUser",
// Email = "newuser@unitaire.fr",
// ImageProfil = "http://newuserimage.com",
// Password = "newPassword123"
// };
// _mockUserService.Setup(service => service.GetUserById(newUser.Id)).ReturnsAsync((UserDTO)null);
// _mockUserService.Setup(service => service.AddUser(newUser)).Verifiable();
// // Act
// var result = await _userController.CreateUser(newUser);
// // Assert
// var createdResult = Assert.IsType<CreatedAtActionResult>(result);
// Assert.Equal(newUser.Id, createdResult.RouteValues["id"]);
//}
//[Fact]
//public async Task DeletePlayer_ReturnsOk_WhenPlayerExists()
//{
// // Arrange
// var id = 1;
// var existingPlayer = new UserDTO
// {
// Id = id,
// Pseudo = "ExistingUser",
// Email = "existing@unitaire.fr",
// ImageProfil = "http://existingimage.com",
// Password = "existingPassword123"
// };
// _mockUserService.Setup(service => service.GetUserById(id)).ReturnsAsync(existingPlayer);
// _mockUserService.Setup(service => service.RemoveUser(existingPlayer.Id)).Verifiable();
// // Act
// var result = await _userController.DeletePlayer(id);
// // Assert
// Assert.IsType<OkObjectResult>(result);
//}
}
}

@ -1,11 +0,0 @@
namespace XUnitTest
{
public class UnitTest1
{
[Fact]
public void Test1()
{
}
}
}

@ -11,11 +11,28 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0" /> <PackageReference Include="coverlet.collector" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="9.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="Moq" Version="4.20.72" />
<PackageReference Include="NSwag.Core" Version="14.3.0" />
<PackageReference Include="NSwag.Core.Yaml" Version="14.3.0" />
<PackageReference Include="NSwag.Generation.AspNetCore" Version="14.3.0" />
<PackageReference Include="xunit" Version="2.5.3" /> <PackageReference Include="xunit" Version="2.5.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DTO\DTO.csproj" />
<ProjectReference Include="..\Shared\Shared.csproj" />
<ProjectReference Include="..\WfApi\WfApi.csproj" />
<ProjectReference Include="..\StubbedContextLib\StubbedContextLib.csproj" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Using Include="Xunit" /> <Using Include="Xunit" />
</ItemGroup> </ItemGroup>

Loading…
Cancel
Save