Compare commits

..

162 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
3 weeks ago
Leni BEAULATON d51225cf23 Bdd21 PGSQL
3 weeks ago
Leni BEAULATON 326141ebea Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
3 weeks ago
Leni BEAULATON 5153564054 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build encountered an error Details
3 weeks ago
Leni BEAULATON 1f6dfeefc4 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
3 weeks ago
Leni BEAULATON 7660456667 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON 738880a055 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON 42b791d630 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON b695a0c3a9 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON 8f60990194 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON 6d8db552c7 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON 5634943a6d Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON 552e18702c Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON 0c62d8ed3b Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON 571f2f0967 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON f96b0650bd Bdd2 PGSQL
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON dd5461e3e4 Bdd1 PGSQL
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON f1e5399674 Bdd12 SQLite
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON ff0129aba2 Bdd11 SQLite
continuous-integration/drone/push Build is passing Details
3 weeks ago
Leni BEAULATON d6b7d5cc10 Bdd10 SQLite
continuous-integration/drone/push Build is passing Details
3 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
3 weeks ago
Leni BEAULATON e9db38a673 Bdd9 SQLite
3 weeks ago
Leni BEAULATON 344c2b8a61 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
3 weeks ago
Leni BEAULATON da6534249f Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 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
3 weeks ago
Leni BEAULATON f125ebc9fd Bdd8 SQLite
3 weeks ago
Leni BEAULATON 8e24f3bd4d Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON 11e9f528b0 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON 197251908c Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON 8383532f79 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON ddc7bd482a Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON d0765e9194 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON dac0c7a433 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON ed87c0a42b Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON 26e2aaa75c Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
3 weeks ago
Leni BEAULATON 1bffdcd1ca Mise à jour de '.drone.yml'
continuous-integration/drone/push Build was killed Details
3 weeks ago
Leni BEAULATON 3c94e8900d Mise à jour de '.drone.yml'
continuous-integration/drone/push Build encountered an error Details
3 weeks ago
Leni BEAULATON feda8ddd81 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build encountered an error Details
3 weeks ago
Leni BEAULATON d1f802a002 Bdd7 SQLite
continuous-integration/drone/push Build is passing Details
3 weeks ago
Leni BEAULATON f578dffd53 Bdd6 SQLite
continuous-integration/drone/push Build is passing Details
3 weeks ago
Leni BEAULATON c6bb4053f6 Bdd5 SQLite
continuous-integration/drone/push Build is passing Details
3 weeks ago
Leni BEAULATON 5f35563be6 Bdd5
continuous-integration/drone/push Build is passing Details
3 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
3 weeks ago
Leni BEAULATON e369fb398b bdd4
3 weeks ago
Leni BEAULATON d452ae3047 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
3 weeks ago
Leni BEAULATON c5d0339496 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
3 weeks ago
Leni BEAULATON 725bfe0587 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
3 weeks ago
Leni BEAULATON e3654aa81c Bdd2
continuous-integration/drone/push Build is passing Details
3 weeks ago
Leni BEAULATON 6066064815 Connexion bdd
continuous-integration/drone/push Build is passing Details
3 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
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
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
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 4b4b0495fa ajout methodes extentions ToDto()
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

@ -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,5 +1,26 @@
# 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
@ -10,7 +31,7 @@ niveau | description | coeff | jalon | État
☢️ | 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 | 🟨
🟢 | 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 | ✅
@ -18,13 +39,13 @@ niveau | description | coeff | jalon | État
🟢 | 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 |
🟡 | 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 |
🟡 | Déploiement | 4 | J2 |
🔴 | Unit of Work❌ / Repository✅ + extras (héritage, accès concurrents...) | 8 | J2 | 🟨
🟢 | Utilisation dans le projet | 2 | J2 |
🟢 | Utilisation dans le projet | 2 | J2 |
🟢 | mon dépôt possède un readme qui apporte quelque chose... | 2 | J2 | ✅
@ -32,22 +53,23 @@ niveau | description | coeff | jalon | État
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 | 🟨
☢️ | 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 |
🟢 | 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 | ✅

@ -8,7 +8,14 @@
</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>

@ -12,6 +12,7 @@
<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">
@ -19,6 +20,9 @@
<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>

@ -2,6 +2,7 @@
using Microsoft.EntityFrameworkCore;
using Shared;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -13,11 +14,13 @@ namespace Contextlib
{
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>
@ -32,6 +35,12 @@ namespace Contextlib
{
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();
}
@ -68,15 +77,10 @@ namespace Contextlib
/// <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)
public async Task<Character?> GetCharByName(string name)
{
var character = _repo.GetItems(item => item.Name == name,0,1, [nameof(Character.Images)]).FirstOrDefault();
if (character == null)
{
throw new KeyNotFoundException($"Error : No character found with the name: {name}.");
}
return character;
}
@ -98,6 +102,12 @@ namespace Contextlib
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>
@ -121,12 +131,14 @@ namespace Contextlib
public async Task UpdateCharacter(int id, Character character)
{
Character? charac = _repo.GetById(id);
if (charac != null && charac != null)
if (charac != null)
{
bool change = false;
if (character.IdImage != 0)
var image = await _dbI.GetImageByPath(character.Images.ImgPath);
if (image != null)
{
charac.IdImage = character.IdImage;
charac.IdImage = image.Id;
charac.Images = image;
change = true;
}
if (character.Name != null)

@ -10,12 +10,12 @@ using System.Threading.Tasks;
namespace Contextlib
{
public class DbCommentManager : ICommentService<Commentary>
public class DbCommentaryManager : ICommentaryService<Commentary>
{
private WTFContext _context;
private GenericRepository<Commentary> _repo;
public DbCommentManager(WTFContext context)
public DbCommentaryManager(WTFContext context)
{
_context = context ?? throw new ArgumentNullException(nameof(context), "Database context cannot be null.");
_repo = new GenericRepository<Commentary>(context);
@ -27,14 +27,39 @@ namespace Contextlib
/// <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)
public async Task AddComment(Commentary comment, int idQuote)
{
if (comment == null)
{
throw new ArgumentNullException(nameof(comment), "Comment cannot be null.");
}
_repo.Insert(comment);
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();
}
@ -44,7 +69,7 @@ namespace Contextlib
/// <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 DeleteCommentForQuote(int quoteId)
public async Task DeleteCommentaryForQuote(int quoteId)
{
var comments = await _context.comments.Where(x => x.IdQuote == quoteId).ToListAsync();
if (!comments.Any())
@ -62,7 +87,7 @@ namespace Contextlib
/// <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 DeleteCommentForUser(int userId)
public async Task DeleteCommentaryForUser(int userId)
{
var comments = await _context.comments.Include(c => c.User).Where(x => x.IdUser == userId).ToListAsync();
if (!comments.Any())
@ -74,15 +99,15 @@ namespace Contextlib
await _context.SaveChangesAsync();
}
public async Task<PaginationResult<Commentary>> GetAllComment()
public async Task<PaginationResult<Commentary>> GetAllCommentary()
{
var comments = await _context.comments.Include(c => c.User).ToListAsync();
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> GetCommentById(int id)
public async Task<Commentary> GetCommentaryById(int id)
{
var comment = await _context.comments.Include(c => c.User).Where(x => x.Id == id).FirstOrDefaultAsync();
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}.");
@ -90,9 +115,9 @@ namespace Contextlib
return comment;
}
public async Task<PaginationResult<Commentary>> GetCommentByQuote(int quoteId, int index, int pageSize)
public async Task<PaginationResult<Commentary>> GetCommentaryByQuote(int quoteId, int index, int pageSize)
{
var comments = await _context.comments.Include(c => c.User).Where(x => x.IdQuote == quoteId).ToListAsync();
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}.");
@ -112,7 +137,7 @@ namespace Contextlib
return new PaginationResult<Commentary>(comments.Count, index, pageSize, comments.Skip(index * pageSize).Take(pageSize).ToList());
}
public async Task<PaginationResult<Commentary>> GetCommentByUser(int userId, int index, int pageSize)
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())
@ -134,7 +159,7 @@ namespace Contextlib
return new PaginationResult<Commentary>(comments.Count, index, pageSize, comments.Skip(index * pageSize).Take(pageSize).ToList());
}
public async Task<int> LastCommentId()
public async Task<int> LastCommentaryId()
{
var last = await _context.comments.OrderByDescending(x => x.Id).FirstOrDefaultAsync();
if(last == null)
@ -144,13 +169,19 @@ namespace Contextlib
return last.Id;
}
public async Task RemoveComment(int id)
public async Task RemoveCommentary(int id)
{
_repo.Delete(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 UpdateComment(int id, Commentary comment)
public async Task UpdateCommentary(int id, Commentary comment)
{
var modif = false;
var com = await _context.comments.Where(x => x.Id == id).FirstOrDefaultAsync();

@ -1,4 +1,6 @@
using Entity;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Shared;
using System;
using System.Collections.Generic;
@ -8,33 +10,108 @@ using System.Threading.Tasks;
namespace Contextlib
{
public class DbFavoriteManager : IFavoriteService
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)
{
throw new NotImplementedException();
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)
{
throw new NotImplementedException();
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)
{
throw new NotImplementedException();
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)
{
throw new NotImplementedException();
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);
}
}
}

@ -1,5 +1,6 @@
using Entity;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Shared;
using System;
using System.Collections.Generic;
@ -32,9 +33,14 @@ namespace Contextlib
return new PaginationResult<Images>(await CountImage(), 0, await CountImage(), _repository.GetItems(0, await CountImage()).ToList());
}
public async Task<Images> GetImageById(int id)
public async Task<Images?> GetImageById(int id)
{
return _repository.GetById(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()
@ -86,5 +92,11 @@ namespace Contextlib
{
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,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;
}
}
}

@ -6,7 +6,6 @@ using System.Text;
using System.Threading.Tasks;
using Entity;
using Microsoft.EntityFrameworkCore;
namespace Contextlib
{
public class WTFContext : DbContext
@ -14,7 +13,6 @@ namespace Contextlib
//public DbSet<Admin> admins { get; set; }
public DbSet<Character> characters { get; set; }
public DbSet<Commentary> comments { get; set; }
public DbSet<DailyQuote> dailyquotes { get; set; }
public DbSet<Favorite> favorites { get; set; }
public DbSet<Images> images { get; set; }
public DbSet<Question> question { get; set; }
@ -24,6 +22,7 @@ namespace Contextlib
//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)
{
@ -53,7 +52,7 @@ namespace Contextlib
.HasMany<Quote>()
.WithMany()
.UsingEntity<Commentary>(
i => i.HasKey(e => new { e.IdUser, e.IdQuote })
i => i.HasKey(e => e.Id)
);
modelBuilder.Entity<Commentary>()
@ -74,6 +73,9 @@ namespace Contextlib
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()
@ -87,7 +89,12 @@ namespace Contextlib
{
if (!options.IsConfigured)
{
options.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Wf-Database.mdf;Trusted_Connection=True;");
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; }
}
}

@ -6,6 +6,17 @@
<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" />

@ -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;
}
}
}
}

@ -1,19 +0,0 @@
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 DailyQuote
{
[Key]
[ForeignKey(nameof(Quote))]
public int IdQuote { get; set; }
public Quote Quote { get; set; } = null!;
}
}

@ -6,4 +6,15 @@
<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>

@ -46,8 +46,6 @@ namespace Entity
public Character Character { get; set; } = null!;
public ICollection<DailyQuote> DailyQuotes { get; set; } = new List<DailyQuote>();
public ICollection<Commentary> Commentarys { get; set; } = new List<Commentary>();
public ICollection<Users> Favorite { get; } = new List<Users>();

@ -1,17 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entity
{
// Peut etre enlever car inutiliser
public class RecordQuiz
{
public int IdUsers { get; set; }
public int IdQuiz { get; set; }
public int NbPoint { get; set; }
public int TimeQuiz { get; set; }
}
}

@ -17,6 +17,8 @@ namespace Entity
[Required]
[StringLength(50)]
public string UserName { get; set; }
[Required]
public LangEnum Lang { get; set; } = LangEnum.vo;
[Required]
[StringLength(50)]
@ -38,5 +40,10 @@ namespace Entity
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.
Task<int> GetLastCharId();
Task<PaginationResult<TChar>> GetSomeChar(int page, int count);
}
}

@ -6,49 +6,49 @@ using System.Threading.Tasks;
namespace Shared
{
public interface ICommentService<TComment>
public interface ICommentaryService<TComment>
{
// Retrieves a comment by its unique identifier (id).
// '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.
// 'quoteId' is the unique identifier of the quote.
// 'index' is the page number (for pagination).
// '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.
// This returns a list of all comments.
Task<PaginationResult<TComment>> GetAllComment();
Task<PaginationResult<TComment>> GetAllCommentary();
// Retrieves comments made by a specific user, with pagination.
// 'userId' is the unique identifier of the user.
// 'index' is the page number (for pagination).
// '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.
// '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'.
// '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').
// '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.
// '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.
// '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.
Task<int> LastCommentId();
Task<int> LastCommentaryId();
}
}

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

@ -35,5 +35,7 @@ namespace Shared
// Retrieves the last Image ID.
Task<int> GetLastImageId();
Task<TImage?> GetImageByPath(string path);
}
}

@ -10,7 +10,7 @@ namespace Shared
{
// Retrieves the daily quote in a specified language.
// '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).
Task<TQuote> GetQuoteById(int id);
@ -25,8 +25,11 @@ namespace Shared
// Retrieves all available quotes but filtered by 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.
// 'index' is the starting point for pagination
// 'pageSize' determines the number of quotes per page
@ -73,7 +76,7 @@ namespace Shared
// Adds a new quote.
// '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.
// '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').
Task RemoveQuote(int quoteId);
// Returns the total number of quotes available.
Task<int> CountQuotes();
// Retrieves the last ID.
Task<int> GetLastQuoteId();
// 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.
Task ValidateQuote(int quoteId, bool isValidate);
}
}

@ -18,11 +18,10 @@ namespace Shared
// Retrieves a source by its date.
// '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.
// '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.
// 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.
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'.
// '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').
// '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.
// 'username' is the username for which the password hash is to be retrieved.

@ -6,4 +6,15 @@
<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,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;
}
}
}

@ -1,22 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace StubbedContextLib.Migrations
{
/// <inheritdoc />
public partial class migr1 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}

@ -2,9 +2,9 @@
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using StubbedContextLib;
#nullable disable
@ -12,8 +12,8 @@ using StubbedContextLib;
namespace StubbedContextLib.Migrations
{
[DbContext(typeof(StubWTFContext))]
[Migration("20250317163102_migrationTest1")]
partial class migrationTest1
[Migration("20250403162101_myFirstMigration")]
partial class myFirstMigration
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
@ -21,25 +21,43 @@ namespace StubbedContextLib.Migrations
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "9.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
.HasAnnotation("Relational:MaxIdentifierLength", 63);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("Entity.Admin", b =>
{
b.Property<int>("IdUsers")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("IdUsers"));
b.Property<int>("UserId")
.HasColumnType("integer");
b.HasKey("IdUsers");
b.HasIndex("UserId");
b.ToTable("admins");
});
modelBuilder.Entity("Entity.Character", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
.HasColumnType("integer");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("IdImage")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
.HasColumnType("character varying(50)");
b.HasKey("Id");
@ -112,79 +130,61 @@ namespace StubbedContextLib.Migrations
modelBuilder.Entity("Entity.Commentary", b =>
{
b.Property<int>("IdUser")
.HasColumnType("int");
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
b.Property<int>("IdQuote")
.HasColumnType("int");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Comment")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
.HasColumnType("character varying(100)");
b.Property<DateTime>("DateCommentary")
.HasColumnType("date")
.HasColumnName("DateCommentary");
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("IdQuote")
.HasColumnType("integer");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("IdUser")
.HasColumnType("integer");
b.HasKey("IdUser", "IdQuote");
b.HasKey("Id");
b.HasIndex("IdQuote");
b.HasIndex("IdUser");
b.ToTable("comments");
b.HasData(
new
{
IdUser = 2,
IdQuote = 1,
Id = 1,
Comment = "Ce film est le meilleur",
DateCommentary = new DateTime(2025, 2, 3, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = 1
IdQuote = 1,
IdUser = 2
},
new
{
IdUser = 3,
IdQuote = 1,
Id = 2,
Comment = "Very good",
DateCommentary = new DateTime(2025, 3, 11, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = 2
});
});
modelBuilder.Entity("Entity.DailyQuote", b =>
{
b.Property<int>("IdQuote")
.HasColumnType("int");
b.HasKey("IdQuote");
b.ToTable("dailyquotes");
b.HasData(
new
{
IdQuote = 1
},
new
{
IdQuote = 5
IdQuote = 1,
IdUser = 3
});
});
modelBuilder.Entity("Entity.Favorite", b =>
{
b.Property<int>("IdQuote")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<int>("IdUsers")
.HasColumnType("int");
.HasColumnType("integer");
b.HasKey("IdQuote", "IdUsers");
@ -244,13 +244,13 @@ namespace StubbedContextLib.Migrations
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
.HasColumnType("integer");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("ImgPath")
.IsRequired()
.HasColumnType("nvarchar(max)");
.HasColumnType("text");
b.HasKey("Id");
@ -313,39 +313,42 @@ namespace StubbedContextLib.Migrations
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
.HasColumnType("integer");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("AnswerA")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
.HasColumnType("character varying(50)");
b.Property<string>("AnswerB")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
.HasColumnType("character varying(50)");
b.Property<string>("AnswerC")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
.HasColumnType("character varying(50)");
b.Property<string>("AnswerD")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
.HasColumnType("character varying(50)");
b.Property<string>("CorrectAnswer")
.IsRequired()
.HasMaxLength(1)
.HasColumnType("nvarchar(1)");
.HasColumnType("character varying(1)");
b.Property<bool>("IsValid")
.HasColumnType("boolean");
b.Property<string>("Text")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
.HasColumnType("character varying(200)");
b.HasKey("Id");
@ -360,6 +363,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "Frodon",
AnswerD = "Gandalf",
CorrectAnswer = "B",
IsValid = true,
Text = "Qui est le leader de la Communauté de l'Anneau ?"
},
new
@ -370,6 +374,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "Serpentard",
AnswerD = "Poufsouffle",
CorrectAnswer = "B",
IsValid = false,
Text = "Dans quelle maison Harry Potter est-il ?"
},
new
@ -380,6 +385,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "Gollum",
AnswerD = "Gothmog",
CorrectAnswer = "B",
IsValid = true,
Text = "Qui est le Seigneur des Ténèbres dans la saga Le Seigneur des Anneaux ?"
},
new
@ -390,6 +396,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "Chewbacca",
AnswerD = "R2-D2",
CorrectAnswer = "A",
IsValid = true,
Text = "Dans le film Star Wars : Episode IV, qui sauve Luke Skywalker de l'Étoile de la Mort ?"
},
new
@ -400,6 +407,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "Edmund",
AnswerD = "Lucy",
CorrectAnswer = "B",
IsValid = true,
Text = "Qui est le souverain de Narnia dans Le Lion, la Sorcière Blanche et l'Armoire Magique ?"
},
new
@ -410,6 +418,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "Norbert",
AnswerD = "Shenron",
CorrectAnswer = "A",
IsValid = true,
Text = "Quel est le nom du dragon dans Le Hobbit ?"
},
new
@ -420,6 +429,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "Jacob Black",
AnswerD = "Victoria",
CorrectAnswer = "A",
IsValid = true,
Text = "Qui est la première personne à être mordue par un vampire dans Twilight ?"
},
new
@ -430,6 +440,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "Han Solo",
AnswerD = "Luke Skywalker",
CorrectAnswer = "A",
IsValid = true,
Text = "Quel personnage dit Que la Force soit avec toi dans Star Wars ?"
},
new
@ -440,6 +451,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "John Hammond",
AnswerD = "Dennis Nedry",
CorrectAnswer = "B",
IsValid = true,
Text = "Dans Jurassic Park, quel est le nom du paléontologue sur l'île ?"
},
new
@ -450,6 +462,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "Daenerys Targaryen",
AnswerD = "Sansa Stark",
CorrectAnswer = "C",
IsValid = true,
Text = "Dans Game of Thrones, qui est surnommée la Mère des Dragons ?"
});
});
@ -458,20 +471,20 @@ namespace StubbedContextLib.Migrations
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
.HasColumnType("integer");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("IdImage")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<int>("NbQuestion")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<string>("Title")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
.HasColumnType("character varying(50)");
b.HasKey("Id");
@ -499,10 +512,10 @@ namespace StubbedContextLib.Migrations
modelBuilder.Entity("Entity.QuizQuestion", b =>
{
b.Property<int>("IdQuestion")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<int>("IdQuiz")
.HasColumnType("int");
.HasColumnType("integer");
b.HasKey("IdQuestion", "IdQuiz");
@ -567,32 +580,32 @@ namespace StubbedContextLib.Migrations
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
.HasColumnType("integer");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Content")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
.HasColumnType("character varying(100)");
b.Property<int>("IdCharacter")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<int>("IdSource")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<int?>("IdUsersPropose")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<bool>("IsValid")
.HasColumnType("bit");
.HasColumnType("boolean");
b.Property<int>("Langage")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<int>("Likes")
.HasColumnType("int");
.HasColumnType("integer");
b.HasKey("Id");
@ -711,7 +724,7 @@ namespace StubbedContextLib.Migrations
IdCharacter = 10,
IdSource = 4,
IdUsersPropose = 1,
IsValid = true,
IsValid = false,
Langage = 1,
Likes = 11025
});
@ -721,20 +734,20 @@ namespace StubbedContextLib.Migrations
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
.HasColumnType("integer");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Title")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
.HasColumnType("character varying(100)");
b.Property<int>("TypeSrc")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<int>("Year")
.HasColumnType("int");
.HasColumnType("integer");
b.HasKey("Id");
@ -782,9 +795,9 @@ namespace StubbedContextLib.Migrations
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
.HasColumnType("integer");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<DateTime>("Created")
.HasColumnType("date")
@ -793,20 +806,20 @@ namespace StubbedContextLib.Migrations
b.Property<string>("Email")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
.HasColumnType("character varying(50)");
b.Property<int>("IdImage")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<string>("Password")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
.HasColumnType("character varying(200)");
b.Property<string>("UserName")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
.HasColumnType("character varying(50)");
b.HasKey("Id");
@ -907,6 +920,17 @@ namespace StubbedContextLib.Migrations
});
});
modelBuilder.Entity("Entity.Admin", b =>
{
b.HasOne("Entity.Users", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("Entity.Character", b =>
{
b.HasOne("Entity.Images", "Images")
@ -937,17 +961,6 @@ namespace StubbedContextLib.Migrations
b.Navigation("User");
});
modelBuilder.Entity("Entity.DailyQuote", b =>
{
b.HasOne("Entity.Quote", "Quote")
.WithMany("DailyQuotes")
.HasForeignKey("IdQuote")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Quote");
});
modelBuilder.Entity("Entity.Favorite", b =>
{
b.HasOne("Entity.Quote", "Quote")
@ -1046,8 +1059,6 @@ namespace StubbedContextLib.Migrations
modelBuilder.Entity("Entity.Quote", b =>
{
b.Navigation("Commentarys");
b.Navigation("DailyQuotes");
});
modelBuilder.Entity("Entity.Source", b =>

@ -1,5 +1,6 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
@ -8,7 +9,7 @@ using Microsoft.EntityFrameworkCore.Migrations;
namespace StubbedContextLib.Migrations
{
/// <inheritdoc />
public partial class migrationTest1 : Migration
public partial class myFirstMigration : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
@ -17,9 +18,9 @@ namespace StubbedContextLib.Migrations
name: "images",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
ImgPath = table.Column<string>(type: "nvarchar(max)", nullable: false)
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
ImgPath = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
@ -30,14 +31,15 @@ namespace StubbedContextLib.Migrations
name: "question",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Text = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
AnswerA = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
AnswerB = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
AnswerC = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
AnswerD = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
CorrectAnswer = table.Column<string>(type: "nvarchar(1)", maxLength: 1, nullable: false)
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 =>
{
@ -48,11 +50,11 @@ namespace StubbedContextLib.Migrations
name: "sources",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Title = table.Column<string>(type: "nvarchar(100)", maxLength: 100, nullable: false),
Year = table.Column<int>(type: "int", nullable: false),
TypeSrc = table.Column<int>(type: "int", nullable: false)
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 =>
{
@ -63,10 +65,10 @@ namespace StubbedContextLib.Migrations
name: "characters",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Name = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
IdImage = table.Column<int>(type: "int", nullable: false)
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 =>
{
@ -83,11 +85,11 @@ namespace StubbedContextLib.Migrations
name: "quizzes",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Title = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
IdImage = table.Column<int>(type: "int", nullable: false),
NbQuestion = table.Column<int>(type: "int", nullable: false)
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 =>
{
@ -104,12 +106,12 @@ namespace StubbedContextLib.Migrations
name: "users",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
UserName = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
Email = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
Password = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
IdImage = table.Column<int>(type: "int", nullable: false),
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 =>
@ -127,8 +129,8 @@ namespace StubbedContextLib.Migrations
name: "QuizQuestion",
columns: table => new
{
IdQuiz = table.Column<int>(type: "int", nullable: false),
IdQuestion = table.Column<int>(type: "int", nullable: false)
IdQuiz = table.Column<int>(type: "integer", nullable: false),
IdQuestion = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
@ -147,19 +149,38 @@ namespace StubbedContextLib.Migrations
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: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Content = table.Column<string>(type: "nvarchar(100)", maxLength: 100, nullable: false),
Likes = table.Column<int>(type: "int", nullable: false),
Langage = table.Column<int>(type: "int", nullable: false),
IsValid = table.Column<bool>(type: "bit", nullable: false),
IdCharacter = table.Column<int>(type: "int", nullable: false),
IdSource = table.Column<int>(type: "int", nullable: false),
IdUsersPropose = table.Column<int>(type: "int", nullable: true)
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 =>
{
@ -187,16 +208,16 @@ namespace StubbedContextLib.Migrations
name: "comments",
columns: table => new
{
IdUser = table.Column<int>(type: "int", nullable: false),
IdQuote = table.Column<int>(type: "int", nullable: false),
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
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: "nvarchar(100)", maxLength: 100, nullable: false)
Comment = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_comments", x => new { x.IdUser, x.IdQuote });
table.PrimaryKey("PK_comments", x => x.Id);
table.ForeignKey(
name: "FK_comments_quotes_IdQuote",
column: x => x.IdQuote,
@ -210,29 +231,12 @@ namespace StubbedContextLib.Migrations
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "dailyquotes",
columns: table => new
{
IdQuote = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_dailyquotes", x => x.IdQuote);
table.ForeignKey(
name: "FK_dailyquotes_quotes_IdQuote",
column: x => x.IdQuote,
principalTable: "quotes",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "favorites",
columns: table => new
{
IdUsers = table.Column<int>(type: "int", nullable: false),
IdQuote = table.Column<int>(type: "int", nullable: false)
IdUsers = table.Column<int>(type: "integer", nullable: false),
IdQuote = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
@ -268,19 +272,19 @@ namespace StubbedContextLib.Migrations
migrationBuilder.InsertData(
table: "question",
columns: new[] { "Id", "AnswerA", "AnswerB", "AnswerC", "AnswerD", "CorrectAnswer", "Text" },
columns: new[] { "Id", "AnswerA", "AnswerB", "AnswerC", "AnswerD", "CorrectAnswer", "IsValid", "Text" },
values: new object[,]
{
{ 1, "Gimli", "Aragorn", "Frodon", "Gandalf", "B", "Qui est le leader de la Communauté de l'Anneau ?" },
{ 2, "Serdaigle", "Gryffondor", "Serpentard", "Poufsouffle", "B", "Dans quelle maison Harry Potter est-il ?" },
{ 3, "Saroumane", "Sauron", "Gollum", "Gothmog", "B", "Qui est le Seigneur des Ténèbres dans la saga Le Seigneur des Anneaux ?" },
{ 4, "Han Solo", "Princesse Leia", "Chewbacca", "R2-D2", "A", "Dans le film Star Wars : Episode IV, qui sauve Luke Skywalker de l'Étoile de la Mort ?" },
{ 5, "Reine Jadis", "Aslan", "Edmund", "Lucy", "B", "Qui est le souverain de Narnia dans Le Lion, la Sorcière Blanche et l'Armoire Magique ?" },
{ 6, "Smaug", "Falkor", "Norbert", "Shenron", "A", "Quel est le nom du dragon dans Le Hobbit ?" },
{ 7, "Bella Swan", "Edward Cullen", "Jacob Black", "Victoria", "A", "Qui est la première personne à être mordue par un vampire dans Twilight ?" },
{ 8, "Obi-Wan Kenobi", "Yoda", "Han Solo", "Luke Skywalker", "A", "Quel personnage dit Que la Force soit avec toi dans Star Wars ?" },
{ 9, "Dr. Ellie Sattler", "Alan Grant", "John Hammond", "Dennis Nedry", "B", "Dans Jurassic Park, quel est le nom du paléontologue sur l'île ?" },
{ 10, "Cersei Lannister", "Arya Stark", "Daenerys Targaryen", "Sansa Stark", "C", "Dans Game of Thrones, qui est surnommée la Mère des Dragons ?" }
{ 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(
@ -369,25 +373,16 @@ namespace StubbedContextLib.Migrations
{ 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, true, 1, 11025 }
{ 10, "La quoi ?", 10, 4, 1, false, 1, 11025 }
});
migrationBuilder.InsertData(
table: "comments",
columns: new[] { "IdQuote", "IdUser", "Comment", "DateCommentary", "Id" },
columns: new[] { "Id", "Comment", "DateCommentary", "IdQuote", "IdUser" },
values: new object[,]
{
{ 1, 2, "Ce film est le meilleur", new DateTime(2025, 2, 3, 0, 0, 0, 0, DateTimeKind.Unspecified), 1 },
{ 1, 3, "Very good", new DateTime(2025, 3, 11, 0, 0, 0, 0, DateTimeKind.Unspecified), 2 }
});
migrationBuilder.InsertData(
table: "dailyquotes",
column: "IdQuote",
values: new object[]
{
1,
5
{ 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(
@ -406,6 +401,11 @@ namespace StubbedContextLib.Migrations
{ 10, 5 }
});
migrationBuilder.CreateIndex(
name: "IX_admins_UserId",
table: "admins",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_characters_IdImage",
table: "characters",
@ -416,6 +416,11 @@ namespace StubbedContextLib.Migrations
table: "comments",
column: "IdQuote");
migrationBuilder.CreateIndex(
name: "IX_comments_IdUser",
table: "comments",
column: "IdUser");
migrationBuilder.CreateIndex(
name: "IX_favorites_IdUsers",
table: "favorites",
@ -456,10 +461,10 @@ namespace StubbedContextLib.Migrations
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "comments");
name: "admins");
migrationBuilder.DropTable(
name: "dailyquotes");
name: "comments");
migrationBuilder.DropTable(
name: "favorites");

@ -2,9 +2,9 @@
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using StubbedContextLib;
#nullable disable
@ -12,8 +12,8 @@ using StubbedContextLib;
namespace StubbedContextLib.Migrations
{
[DbContext(typeof(StubWTFContext))]
[Migration("20250318135625_migr1")]
partial class migr1
[Migration("20250405155130_migrLangUser")]
partial class migrLangUser
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
@ -21,25 +21,43 @@ namespace StubbedContextLib.Migrations
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "9.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
.HasAnnotation("Relational:MaxIdentifierLength", 63);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("Entity.Admin", b =>
{
b.Property<int>("IdUsers")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("IdUsers"));
b.Property<int>("UserId")
.HasColumnType("integer");
b.HasKey("IdUsers");
b.HasIndex("UserId");
b.ToTable("admins");
});
modelBuilder.Entity("Entity.Character", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
.HasColumnType("integer");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("IdImage")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
.HasColumnType("character varying(50)");
b.HasKey("Id");
@ -112,79 +130,61 @@ namespace StubbedContextLib.Migrations
modelBuilder.Entity("Entity.Commentary", b =>
{
b.Property<int>("IdUser")
.HasColumnType("int");
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
b.Property<int>("IdQuote")
.HasColumnType("int");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Comment")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
.HasColumnType("character varying(100)");
b.Property<DateTime>("DateCommentary")
.HasColumnType("date")
.HasColumnName("DateCommentary");
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("IdQuote")
.HasColumnType("integer");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("IdUser")
.HasColumnType("integer");
b.HasKey("IdUser", "IdQuote");
b.HasKey("Id");
b.HasIndex("IdQuote");
b.HasIndex("IdUser");
b.ToTable("comments");
b.HasData(
new
{
IdUser = 2,
IdQuote = 1,
Id = 1,
Comment = "Ce film est le meilleur",
DateCommentary = new DateTime(2025, 2, 3, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = 1
IdQuote = 1,
IdUser = 2
},
new
{
IdUser = 3,
IdQuote = 1,
Id = 2,
Comment = "Very good",
DateCommentary = new DateTime(2025, 3, 11, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = 2
});
});
modelBuilder.Entity("Entity.DailyQuote", b =>
{
b.Property<int>("IdQuote")
.HasColumnType("int");
b.HasKey("IdQuote");
b.ToTable("dailyquotes");
b.HasData(
new
{
IdQuote = 1
},
new
{
IdQuote = 5
IdQuote = 1,
IdUser = 3
});
});
modelBuilder.Entity("Entity.Favorite", b =>
{
b.Property<int>("IdQuote")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<int>("IdUsers")
.HasColumnType("int");
.HasColumnType("integer");
b.HasKey("IdQuote", "IdUsers");
@ -244,13 +244,13 @@ namespace StubbedContextLib.Migrations
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
.HasColumnType("integer");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("ImgPath")
.IsRequired()
.HasColumnType("nvarchar(max)");
.HasColumnType("text");
b.HasKey("Id");
@ -313,39 +313,42 @@ namespace StubbedContextLib.Migrations
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
.HasColumnType("integer");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("AnswerA")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
.HasColumnType("character varying(50)");
b.Property<string>("AnswerB")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
.HasColumnType("character varying(50)");
b.Property<string>("AnswerC")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
.HasColumnType("character varying(50)");
b.Property<string>("AnswerD")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
.HasColumnType("character varying(50)");
b.Property<string>("CorrectAnswer")
.IsRequired()
.HasMaxLength(1)
.HasColumnType("nvarchar(1)");
.HasColumnType("character varying(1)");
b.Property<bool>("IsValid")
.HasColumnType("boolean");
b.Property<string>("Text")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
.HasColumnType("character varying(200)");
b.HasKey("Id");
@ -360,6 +363,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "Frodon",
AnswerD = "Gandalf",
CorrectAnswer = "B",
IsValid = true,
Text = "Qui est le leader de la Communauté de l'Anneau ?"
},
new
@ -370,6 +374,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "Serpentard",
AnswerD = "Poufsouffle",
CorrectAnswer = "B",
IsValid = false,
Text = "Dans quelle maison Harry Potter est-il ?"
},
new
@ -380,6 +385,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "Gollum",
AnswerD = "Gothmog",
CorrectAnswer = "B",
IsValid = true,
Text = "Qui est le Seigneur des Ténèbres dans la saga Le Seigneur des Anneaux ?"
},
new
@ -390,6 +396,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "Chewbacca",
AnswerD = "R2-D2",
CorrectAnswer = "A",
IsValid = true,
Text = "Dans le film Star Wars : Episode IV, qui sauve Luke Skywalker de l'Étoile de la Mort ?"
},
new
@ -400,6 +407,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "Edmund",
AnswerD = "Lucy",
CorrectAnswer = "B",
IsValid = true,
Text = "Qui est le souverain de Narnia dans Le Lion, la Sorcière Blanche et l'Armoire Magique ?"
},
new
@ -410,6 +418,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "Norbert",
AnswerD = "Shenron",
CorrectAnswer = "A",
IsValid = true,
Text = "Quel est le nom du dragon dans Le Hobbit ?"
},
new
@ -420,6 +429,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "Jacob Black",
AnswerD = "Victoria",
CorrectAnswer = "A",
IsValid = true,
Text = "Qui est la première personne à être mordue par un vampire dans Twilight ?"
},
new
@ -430,6 +440,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "Han Solo",
AnswerD = "Luke Skywalker",
CorrectAnswer = "A",
IsValid = true,
Text = "Quel personnage dit Que la Force soit avec toi dans Star Wars ?"
},
new
@ -440,6 +451,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "John Hammond",
AnswerD = "Dennis Nedry",
CorrectAnswer = "B",
IsValid = true,
Text = "Dans Jurassic Park, quel est le nom du paléontologue sur l'île ?"
},
new
@ -450,6 +462,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "Daenerys Targaryen",
AnswerD = "Sansa Stark",
CorrectAnswer = "C",
IsValid = true,
Text = "Dans Game of Thrones, qui est surnommée la Mère des Dragons ?"
});
});
@ -458,20 +471,20 @@ namespace StubbedContextLib.Migrations
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
.HasColumnType("integer");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("IdImage")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<int>("NbQuestion")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<string>("Title")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
.HasColumnType("character varying(50)");
b.HasKey("Id");
@ -499,10 +512,10 @@ namespace StubbedContextLib.Migrations
modelBuilder.Entity("Entity.QuizQuestion", b =>
{
b.Property<int>("IdQuestion")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<int>("IdQuiz")
.HasColumnType("int");
.HasColumnType("integer");
b.HasKey("IdQuestion", "IdQuiz");
@ -567,32 +580,32 @@ namespace StubbedContextLib.Migrations
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
.HasColumnType("integer");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Content")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
.HasColumnType("character varying(100)");
b.Property<int>("IdCharacter")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<int>("IdSource")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<int?>("IdUsersPropose")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<bool>("IsValid")
.HasColumnType("bit");
.HasColumnType("boolean");
b.Property<int>("Langage")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<int>("Likes")
.HasColumnType("int");
.HasColumnType("integer");
b.HasKey("Id");
@ -711,7 +724,7 @@ namespace StubbedContextLib.Migrations
IdCharacter = 10,
IdSource = 4,
IdUsersPropose = 1,
IsValid = true,
IsValid = false,
Langage = 1,
Likes = 11025
});
@ -721,20 +734,20 @@ namespace StubbedContextLib.Migrations
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
.HasColumnType("integer");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Title")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
.HasColumnType("character varying(100)");
b.Property<int>("TypeSrc")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<int>("Year")
.HasColumnType("int");
.HasColumnType("integer");
b.HasKey("Id");
@ -782,9 +795,9 @@ namespace StubbedContextLib.Migrations
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
.HasColumnType("integer");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<DateTime>("Created")
.HasColumnType("date")
@ -793,20 +806,23 @@ namespace StubbedContextLib.Migrations
b.Property<string>("Email")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
.HasColumnType("character varying(50)");
b.Property<int>("IdImage")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<int>("Lang")
.HasColumnType("integer");
b.Property<string>("Password")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
.HasColumnType("character varying(200)");
b.Property<string>("UserName")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
.HasColumnType("character varying(50)");
b.HasKey("Id");
@ -821,6 +837,7 @@ namespace StubbedContextLib.Migrations
Created = new DateTime(2025, 5, 12, 0, 0, 0, 0, DateTimeKind.Unspecified),
Email = "jhonDhoe@gmail.com",
IdImage = 1,
Lang = 0,
Password = "1234",
UserName = "Jhon-Dhoe"
},
@ -830,6 +847,7 @@ namespace StubbedContextLib.Migrations
Created = new DateTime(2025, 3, 19, 0, 0, 0, 0, DateTimeKind.Unspecified),
Email = "lucy_rose@outlook.com",
IdImage = 2,
Lang = 0,
Password = "abcd",
UserName = "Lucy-Rose"
},
@ -839,6 +857,7 @@ namespace StubbedContextLib.Migrations
Created = new DateTime(2024, 11, 2, 0, 0, 0, 0, DateTimeKind.Unspecified),
Email = "mark.taylor@yahoo.com",
IdImage = 3,
Lang = 0,
Password = "5678",
UserName = "Mark-Taylor"
},
@ -848,6 +867,7 @@ namespace StubbedContextLib.Migrations
Created = new DateTime(2025, 2, 28, 0, 0, 0, 0, DateTimeKind.Unspecified),
Email = "sophie.martin@gmail.com",
IdImage = 4,
Lang = 0,
Password = "4321",
UserName = "Sophie-Martin"
},
@ -857,6 +877,7 @@ namespace StubbedContextLib.Migrations
Created = new DateTime(2025, 1, 15, 0, 0, 0, 0, DateTimeKind.Unspecified),
Email = "nathan_doe@aol.com",
IdImage = 5,
Lang = 0,
Password = "8765",
UserName = "Nathan-Doe"
},
@ -866,6 +887,7 @@ namespace StubbedContextLib.Migrations
Created = new DateTime(2025, 4, 7, 0, 0, 0, 0, DateTimeKind.Unspecified),
Email = "ella.brown@icloud.com",
IdImage = 6,
Lang = 0,
Password = "2468",
UserName = "Ella-Brown"
},
@ -875,6 +897,7 @@ namespace StubbedContextLib.Migrations
Created = new DateTime(2024, 12, 25, 0, 0, 0, 0, DateTimeKind.Unspecified),
Email = "oliver_smith@gmail.com",
IdImage = 7,
Lang = 0,
Password = "1357",
UserName = "Oliver-Smith"
},
@ -884,6 +907,7 @@ namespace StubbedContextLib.Migrations
Created = new DateTime(2025, 3, 5, 0, 0, 0, 0, DateTimeKind.Unspecified),
Email = "mia.jones@outlook.com",
IdImage = 8,
Lang = 0,
Password = "1122",
UserName = "Mia-Jones"
},
@ -893,6 +917,7 @@ namespace StubbedContextLib.Migrations
Created = new DateTime(2025, 2, 22, 0, 0, 0, 0, DateTimeKind.Unspecified),
Email = "kevin_williams@aol.com",
IdImage = 9,
Lang = 0,
Password = "2233",
UserName = "Kevin-Williams"
},
@ -902,11 +927,23 @@ namespace StubbedContextLib.Migrations
Created = new DateTime(2025, 1, 3, 0, 0, 0, 0, DateTimeKind.Unspecified),
Email = "olivia.white@yahoo.com",
IdImage = 10,
Lang = 0,
Password = "3344",
UserName = "Olivia-White"
});
});
modelBuilder.Entity("Entity.Admin", b =>
{
b.HasOne("Entity.Users", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("Entity.Character", b =>
{
b.HasOne("Entity.Images", "Images")
@ -937,17 +974,6 @@ namespace StubbedContextLib.Migrations
b.Navigation("User");
});
modelBuilder.Entity("Entity.DailyQuote", b =>
{
b.HasOne("Entity.Quote", "Quote")
.WithMany("DailyQuotes")
.HasForeignKey("IdQuote")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Quote");
});
modelBuilder.Entity("Entity.Favorite", b =>
{
b.HasOne("Entity.Quote", "Quote")
@ -1046,8 +1072,6 @@ namespace StubbedContextLib.Migrations
modelBuilder.Entity("Entity.Quote", b =>
{
b.Navigation("Commentarys");
b.Navigation("DailyQuotes");
});
modelBuilder.Entity("Entity.Source", b =>

@ -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");
}
}
}

@ -2,8 +2,8 @@
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using StubbedContextLib;
#nullable disable
@ -18,25 +18,43 @@ namespace StubbedContextLib.Migrations
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "9.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
.HasAnnotation("Relational:MaxIdentifierLength", 63);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("Entity.Admin", b =>
{
b.Property<int>("IdUsers")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("IdUsers"));
b.Property<int>("UserId")
.HasColumnType("integer");
b.HasKey("IdUsers");
b.HasIndex("UserId");
b.ToTable("admins");
});
modelBuilder.Entity("Entity.Character", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
.HasColumnType("integer");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("IdImage")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
.HasColumnType("character varying(50)");
b.HasKey("Id");
@ -109,79 +127,61 @@ namespace StubbedContextLib.Migrations
modelBuilder.Entity("Entity.Commentary", b =>
{
b.Property<int>("IdUser")
.HasColumnType("int");
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
b.Property<int>("IdQuote")
.HasColumnType("int");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Comment")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
.HasColumnType("character varying(100)");
b.Property<DateTime>("DateCommentary")
.HasColumnType("date")
.HasColumnName("DateCommentary");
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("IdQuote")
.HasColumnType("integer");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("IdUser")
.HasColumnType("integer");
b.HasKey("IdUser", "IdQuote");
b.HasKey("Id");
b.HasIndex("IdQuote");
b.HasIndex("IdUser");
b.ToTable("comments");
b.HasData(
new
{
IdUser = 2,
IdQuote = 1,
Id = 1,
Comment = "Ce film est le meilleur",
DateCommentary = new DateTime(2025, 2, 3, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = 1
IdQuote = 1,
IdUser = 2
},
new
{
IdUser = 3,
IdQuote = 1,
Id = 2,
Comment = "Very good",
DateCommentary = new DateTime(2025, 3, 11, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = 2
});
});
modelBuilder.Entity("Entity.DailyQuote", b =>
{
b.Property<int>("IdQuote")
.HasColumnType("int");
b.HasKey("IdQuote");
b.ToTable("dailyquotes");
b.HasData(
new
{
IdQuote = 1
},
new
{
IdQuote = 5
IdQuote = 1,
IdUser = 3
});
});
modelBuilder.Entity("Entity.Favorite", b =>
{
b.Property<int>("IdQuote")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<int>("IdUsers")
.HasColumnType("int");
.HasColumnType("integer");
b.HasKey("IdQuote", "IdUsers");
@ -241,13 +241,13 @@ namespace StubbedContextLib.Migrations
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
.HasColumnType("integer");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("ImgPath")
.IsRequired()
.HasColumnType("nvarchar(max)");
.HasColumnType("text");
b.HasKey("Id");
@ -310,39 +310,42 @@ namespace StubbedContextLib.Migrations
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
.HasColumnType("integer");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("AnswerA")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
.HasColumnType("character varying(50)");
b.Property<string>("AnswerB")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
.HasColumnType("character varying(50)");
b.Property<string>("AnswerC")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
.HasColumnType("character varying(50)");
b.Property<string>("AnswerD")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
.HasColumnType("character varying(50)");
b.Property<string>("CorrectAnswer")
.IsRequired()
.HasMaxLength(1)
.HasColumnType("nvarchar(1)");
.HasColumnType("character varying(1)");
b.Property<bool>("IsValid")
.HasColumnType("boolean");
b.Property<string>("Text")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
.HasColumnType("character varying(200)");
b.HasKey("Id");
@ -357,6 +360,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "Frodon",
AnswerD = "Gandalf",
CorrectAnswer = "B",
IsValid = true,
Text = "Qui est le leader de la Communauté de l'Anneau ?"
},
new
@ -367,6 +371,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "Serpentard",
AnswerD = "Poufsouffle",
CorrectAnswer = "B",
IsValid = false,
Text = "Dans quelle maison Harry Potter est-il ?"
},
new
@ -377,6 +382,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "Gollum",
AnswerD = "Gothmog",
CorrectAnswer = "B",
IsValid = true,
Text = "Qui est le Seigneur des Ténèbres dans la saga Le Seigneur des Anneaux ?"
},
new
@ -387,6 +393,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "Chewbacca",
AnswerD = "R2-D2",
CorrectAnswer = "A",
IsValid = true,
Text = "Dans le film Star Wars : Episode IV, qui sauve Luke Skywalker de l'Étoile de la Mort ?"
},
new
@ -397,6 +404,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "Edmund",
AnswerD = "Lucy",
CorrectAnswer = "B",
IsValid = true,
Text = "Qui est le souverain de Narnia dans Le Lion, la Sorcière Blanche et l'Armoire Magique ?"
},
new
@ -407,6 +415,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "Norbert",
AnswerD = "Shenron",
CorrectAnswer = "A",
IsValid = true,
Text = "Quel est le nom du dragon dans Le Hobbit ?"
},
new
@ -417,6 +426,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "Jacob Black",
AnswerD = "Victoria",
CorrectAnswer = "A",
IsValid = true,
Text = "Qui est la première personne à être mordue par un vampire dans Twilight ?"
},
new
@ -427,6 +437,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "Han Solo",
AnswerD = "Luke Skywalker",
CorrectAnswer = "A",
IsValid = true,
Text = "Quel personnage dit Que la Force soit avec toi dans Star Wars ?"
},
new
@ -437,6 +448,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "John Hammond",
AnswerD = "Dennis Nedry",
CorrectAnswer = "B",
IsValid = true,
Text = "Dans Jurassic Park, quel est le nom du paléontologue sur l'île ?"
},
new
@ -447,6 +459,7 @@ namespace StubbedContextLib.Migrations
AnswerC = "Daenerys Targaryen",
AnswerD = "Sansa Stark",
CorrectAnswer = "C",
IsValid = true,
Text = "Dans Game of Thrones, qui est surnommée la Mère des Dragons ?"
});
});
@ -455,20 +468,20 @@ namespace StubbedContextLib.Migrations
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
.HasColumnType("integer");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("IdImage")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<int>("NbQuestion")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<string>("Title")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
.HasColumnType("character varying(50)");
b.HasKey("Id");
@ -496,10 +509,10 @@ namespace StubbedContextLib.Migrations
modelBuilder.Entity("Entity.QuizQuestion", b =>
{
b.Property<int>("IdQuestion")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<int>("IdQuiz")
.HasColumnType("int");
.HasColumnType("integer");
b.HasKey("IdQuestion", "IdQuiz");
@ -564,32 +577,32 @@ namespace StubbedContextLib.Migrations
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
.HasColumnType("integer");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Content")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
.HasColumnType("character varying(100)");
b.Property<int>("IdCharacter")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<int>("IdSource")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<int?>("IdUsersPropose")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<bool>("IsValid")
.HasColumnType("bit");
.HasColumnType("boolean");
b.Property<int>("Langage")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<int>("Likes")
.HasColumnType("int");
.HasColumnType("integer");
b.HasKey("Id");
@ -708,7 +721,7 @@ namespace StubbedContextLib.Migrations
IdCharacter = 10,
IdSource = 4,
IdUsersPropose = 1,
IsValid = true,
IsValid = false,
Langage = 1,
Likes = 11025
});
@ -718,20 +731,20 @@ namespace StubbedContextLib.Migrations
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
.HasColumnType("integer");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Title")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
.HasColumnType("character varying(100)");
b.Property<int>("TypeSrc")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<int>("Year")
.HasColumnType("int");
.HasColumnType("integer");
b.HasKey("Id");
@ -779,9 +792,9 @@ namespace StubbedContextLib.Migrations
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
.HasColumnType("integer");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<DateTime>("Created")
.HasColumnType("date")
@ -790,20 +803,23 @@ namespace StubbedContextLib.Migrations
b.Property<string>("Email")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
.HasColumnType("character varying(50)");
b.Property<int>("IdImage")
.HasColumnType("int");
.HasColumnType("integer");
b.Property<int>("Lang")
.HasColumnType("integer");
b.Property<string>("Password")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
.HasColumnType("character varying(200)");
b.Property<string>("UserName")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
.HasColumnType("character varying(50)");
b.HasKey("Id");
@ -818,6 +834,7 @@ namespace StubbedContextLib.Migrations
Created = new DateTime(2025, 5, 12, 0, 0, 0, 0, DateTimeKind.Unspecified),
Email = "jhonDhoe@gmail.com",
IdImage = 1,
Lang = 0,
Password = "1234",
UserName = "Jhon-Dhoe"
},
@ -827,6 +844,7 @@ namespace StubbedContextLib.Migrations
Created = new DateTime(2025, 3, 19, 0, 0, 0, 0, DateTimeKind.Unspecified),
Email = "lucy_rose@outlook.com",
IdImage = 2,
Lang = 0,
Password = "abcd",
UserName = "Lucy-Rose"
},
@ -836,6 +854,7 @@ namespace StubbedContextLib.Migrations
Created = new DateTime(2024, 11, 2, 0, 0, 0, 0, DateTimeKind.Unspecified),
Email = "mark.taylor@yahoo.com",
IdImage = 3,
Lang = 0,
Password = "5678",
UserName = "Mark-Taylor"
},
@ -845,6 +864,7 @@ namespace StubbedContextLib.Migrations
Created = new DateTime(2025, 2, 28, 0, 0, 0, 0, DateTimeKind.Unspecified),
Email = "sophie.martin@gmail.com",
IdImage = 4,
Lang = 0,
Password = "4321",
UserName = "Sophie-Martin"
},
@ -854,6 +874,7 @@ namespace StubbedContextLib.Migrations
Created = new DateTime(2025, 1, 15, 0, 0, 0, 0, DateTimeKind.Unspecified),
Email = "nathan_doe@aol.com",
IdImage = 5,
Lang = 0,
Password = "8765",
UserName = "Nathan-Doe"
},
@ -863,6 +884,7 @@ namespace StubbedContextLib.Migrations
Created = new DateTime(2025, 4, 7, 0, 0, 0, 0, DateTimeKind.Unspecified),
Email = "ella.brown@icloud.com",
IdImage = 6,
Lang = 0,
Password = "2468",
UserName = "Ella-Brown"
},
@ -872,6 +894,7 @@ namespace StubbedContextLib.Migrations
Created = new DateTime(2024, 12, 25, 0, 0, 0, 0, DateTimeKind.Unspecified),
Email = "oliver_smith@gmail.com",
IdImage = 7,
Lang = 0,
Password = "1357",
UserName = "Oliver-Smith"
},
@ -881,6 +904,7 @@ namespace StubbedContextLib.Migrations
Created = new DateTime(2025, 3, 5, 0, 0, 0, 0, DateTimeKind.Unspecified),
Email = "mia.jones@outlook.com",
IdImage = 8,
Lang = 0,
Password = "1122",
UserName = "Mia-Jones"
},
@ -890,6 +914,7 @@ namespace StubbedContextLib.Migrations
Created = new DateTime(2025, 2, 22, 0, 0, 0, 0, DateTimeKind.Unspecified),
Email = "kevin_williams@aol.com",
IdImage = 9,
Lang = 0,
Password = "2233",
UserName = "Kevin-Williams"
},
@ -899,11 +924,23 @@ namespace StubbedContextLib.Migrations
Created = new DateTime(2025, 1, 3, 0, 0, 0, 0, DateTimeKind.Unspecified),
Email = "olivia.white@yahoo.com",
IdImage = 10,
Lang = 0,
Password = "3344",
UserName = "Olivia-White"
});
});
modelBuilder.Entity("Entity.Admin", b =>
{
b.HasOne("Entity.Users", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("Entity.Character", b =>
{
b.HasOne("Entity.Images", "Images")
@ -934,17 +971,6 @@ namespace StubbedContextLib.Migrations
b.Navigation("User");
});
modelBuilder.Entity("Entity.DailyQuote", b =>
{
b.HasOne("Entity.Quote", "Quote")
.WithMany("DailyQuotes")
.HasForeignKey("IdQuote")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Quote");
});
modelBuilder.Entity("Entity.Favorite", b =>
{
b.HasOne("Entity.Quote", "Quote")
@ -1043,8 +1069,6 @@ namespace StubbedContextLib.Migrations
modelBuilder.Entity("Entity.Quote", b =>
{
b.Navigation("Commentarys");
b.Navigation("DailyQuotes");
});
modelBuilder.Entity("Entity.Source", b =>

@ -6,7 +6,9 @@ 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
{
@ -69,7 +71,7 @@ namespace StubbedContextLib
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 = 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(
@ -77,10 +79,6 @@ namespace StubbedContextLib
new Commentary() { Id = 2, Comment = "Very good", DateCommentary = new DateTime(2025, 3, 11), IdQuote = 1, IdUser = 3 }
);
modelBuilder.Entity<DailyQuote>().HasData(
new DailyQuote() { IdQuote = 1},
new DailyQuote() { IdQuote = 5}
);
modelBuilder.Entity<Favorite>().HasData(
new Favorite() { IdQuote = 2, IdUsers = 8 },
@ -147,7 +145,8 @@ namespace StubbedContextLib
{
if (!options.IsConfigured)
{
options.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Wf-Database.mdf;Trusted_Connection=True;");
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;");
}
}
}

@ -11,6 +11,12 @@
<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>

@ -6,4 +6,15 @@
<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>

@ -1,4 +1,3 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.9.34723.18
@ -13,13 +12,19 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Contextlib", "Contextlib\Co
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StubbedContextLib", "StubbedContextLib\StubbedContextLib.csproj", "{5CD69B14-C6AE-4628-A374-996C486E25F2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Model2Entities", "Model2entities\Model2Entities.csproj", "{4A1CBA3D-C798-4E19-865F-39F919F1205A}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestModel2Entities", "TestModel2Entities\TestModel2Entities.csproj", "{2CF20FAC-C2F1-4048-9D46-F39081B0FBEF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "XUnitTest", "XUnitTest\XUnitTest.csproj", "{48002CA2-7CFF-4077-90CF-392476320CE3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WfApi", "WfApi\WfApi.csproj", "{D4EEE1BF-CDCB-4E66-997B-7A5984DA7995}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Model", "Model\Model.csproj", "{708875DC-7ED1-4FD1-9321-3E00B2E7709B}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StubApi", "StubApi\StubApi.csproj", "{4C5F324C-28C3-4153-B402-A07B099C24C6}"
EndProject
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
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -47,10 +52,10 @@ Global
{5CD69B14-C6AE-4628-A374-996C486E25F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5CD69B14-C6AE-4628-A374-996C486E25F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5CD69B14-C6AE-4628-A374-996C486E25F2}.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
{2CF20FAC-C2F1-4048-9D46-F39081B0FBEF}.Debug|Any CPU.ActiveCfg = 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.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.Build.0 = Debug|Any CPU
{48002CA2-7CFF-4077-90CF-392476320CE3}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -59,10 +64,22 @@ Global
{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.Build.0 = Release|Any CPU
{708875DC-7ED1-4FD1-9321-3E00B2E7709B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{708875DC-7ED1-4FD1-9321-3E00B2E7709B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{708875DC-7ED1-4FD1-9321-3E00B2E7709B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{708875DC-7ED1-4FD1-9321-3E00B2E7709B}.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
GlobalSection(SolutionProperties) = preSolution
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);
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.
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
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
@ -12,7 +70,7 @@ var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseOpenApi(); // Active la documentation OpenAPI
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>
<UserSecretsId>283a610b-b95e-4b09-af22-b7d3270a917d</UserSecretsId>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn>
</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="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" />
</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>

@ -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);
//}
}
}

@ -11,13 +11,25 @@
<ItemGroup>
<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="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.runner.visualstudio" Version="2.5.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DTO\DTO.csproj" />
<ProjectReference Include="..\Shared\Shared.csproj" />
<ProjectReference Include="..\WfApi\WfApi.csproj" />
<ProjectReference Include="..\StubbedContextLib\StubbedContextLib.csproj" />
</ItemGroup>

Loading…
Cancel
Save