Compare commits

...

35 Commits

Author SHA1 Message Date
Rémi REGNAULT 3e0f027562 feat: filter respected by ingredient or by recipe can be obtained by asking API
continuous-integration/drone/push Build is failing Details
1 year ago
Rémi REGNAULT ea4769063d feat: add IngredientsClassesController
1 year ago
Rémi REGNAULT 948045dced feat: add IngredientsClassesGateway
1 year ago
Rémi REGNAULT 3e2a04c1ef feat: add enum for IngredientsClasses
1 year ago
Rayhân HASSOU 1c11729000 Mise à jour de 'README.md'
continuous-integration/drone/push Build is failing Details
1 year ago
Rayhân HASSOU 8ee0c517dc Mise à jour de 'README.md'
continuous-integration/drone/push Build is failing Details
1 year ago
Rayhân HASSOU 0a873fe301 Mise à jour de 'README.md'
continuous-integration/drone/push Build is failing Details
1 year ago
Rayhân HASSOU 67b6650432 Mise à jour de 'README.md'
continuous-integration/drone/push Build is failing Details
1 year ago
Rayhân HASSOU f726f2458d Mise à jour de 'README.md'
continuous-integration/drone/push Build is failing Details
1 year ago
Rayhân HASSOU 36eab63cac Mise à jour de 'README.md'
continuous-integration/drone/push Build is failing Details
1 year ago
Rayhân HASSOU 693407024a Mise à jour de 'README.md'
continuous-integration/drone/push Build is failing Details
1 year ago
Rayhân HASSOU 298d9cb24c Mise à jour de 'README.md'
continuous-integration/drone/push Build is failing Details
1 year ago
Rémi REGNAULT 0b3c969b8a add new script that combine npm i, npm run build and npm run start
continuous-integration/drone/push Build is failing Details
1 year ago
Rémi REGNAULT ab9c584cdb npm run start is now working
1 year ago
Rémi REGNAULT f8f6ee3745 trying to have "npm run build" and "npm run start" working
continuous-integration/drone/push Build is failing Details
1 year ago
Rémi REGNAULT 54eaa217f8 trying to skip tests for code analysis
continuous-integration/drone/push Build is failing Details
1 year ago
Rémi REGNAULT ac640a2b26 undo
continuous-integration/drone/push Build is failing Details
1 year ago
Rémi REGNAULT e4d0eb38d0 trying understand why the tests are timeout
continuous-integration/drone/push Build is failing Details
1 year ago
Rémi REGNAULT 57be9d3a48 remaster .drone.yml
continuous-integration/drone/push Build is failing Details
1 year ago
Rémi REGNAULT e633f389f2 remaster .drone.yml
continuous-integration/drone/push Build is failing Details
1 year ago
Rémi REGNAULT 80fe5e5edb remaster .drone.yml
continuous-integration/drone/push Build encountered an error Details
1 year ago
Rémi REGNAULT 9746fc2bea trying understand why the tests are timeout
continuous-integration/drone/push Build is failing Details
1 year ago
Rémi REGNAULT 40e2aab69e trying understand why the tests are timeout
continuous-integration/drone/push Build is failing Details
1 year ago
Rémi REGNAULT 1fd09dd07f change ci test script timeout
continuous-integration/drone/push Build was killed Details
1 year ago
Rémi REGNAULT 77d2e87515 .drone.yml no use the specific test script
continuous-integration/drone/push Build is failing Details
1 year ago
Rémi REGNAULT 00454c50f4 add specific script that will be run on to the pipeline
1 year ago
Rémi REGNAULT e8c5c56541 fix: change message when starting the app
1 year ago
Rémi REGNAULT ae387ff6e8 fix: remove useless imports
continuous-integration/drone/push Build is failing Details
1 year ago
Rémi REGNAULT 74c60cc156 test: add tests for steps controller
continuous-integration/drone/push Build is failing Details
1 year ago
Rémi REGNAULT c183b18074 tests: add test for recipes controller
1 year ago
Rémi REGNAULT e3e444acda tests: add more test on IngredientsController
continuous-integration/drone/push Build is failing Details
1 year ago
Rémi REGNAULT c5866443c0 tests: add tests for IngredientsController for route ingredients/ and ingredients/:id
1 year ago
Rémi REGNAULT 01c8cce238 Merge branch 'master' into WORK-RRE
continuous-integration/drone/push Build is failing Details
1 year ago
Rémi REGNAULT cc96e541b2 feat: add route to get rating list
continuous-integration/drone/push Build is failing Details
1 year ago
Rémi REGNAULT c67ea5fac5 feat: add route to get comments_dictionary
1 year ago

@ -1,6 +1,6 @@
kind: pipeline kind: pipeline
type: docker type: docker
name: LeftOvers_Api name: CI
trigger: trigger:
event: event:
@ -43,6 +43,59 @@ steps:
- npm run test:coverage - npm run test:coverage
depends_on: [ api-build ] depends_on: [ api-build ]
- name: code-analysis
image: node:latest
environment:
SONAR_TOKEN:
from_secret: SONAR_TOKEN
settings:
sources: ./API-Project/src
tests: ./API-Project/tests
sonar.testExecutionReportPaths: ./API-Project/coverage/sonar-report.xml
javascript.lcov.reportPaths: ./API-Project/coverage/lcov.info
commands:
- export SONAR_SCANNER_VERSION=4.7.0.2747
- export SONAR_SCANNER_HOME=$HOME/.sonar/sonar-scanner-$SONAR_SCANNER_VERSION-linux
- curl --create-dirs -sSLo $HOME/.sonar/sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_VERSION-linux.zip
- unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
- export PATH=$SONAR_SCANNER_HOME/bin:$PATH
- export SONAR_SCANNER_OPTS="-server"
- sonar-scanner -X -D sonar.projectKey=LeftOvers_Api -D sonar.host.url=https://codefirst.iut.uca.fr/sonar
depends_on: [ api-build ]
---
kind: pipeline
type: docker
name: CD
trigger:
branch:
- master
event:
- push
steps:
- name: api-build
image: node:latest
environment:
DB_USERNAME:
from_secret: SECRET_DB_USERNAME
DB_DBHOST:
from_secret: SECRET_DB_DBHOST
DB_DBNAME:
from_secret: SECRET_DB_DBNAME
DB_USERPASSWORD:
from_secret: SECRET_DB_USERPASSWORD
DB_PORT:
from_secret: SECRET_DB_PORT
commands:
- cd ./API-Project
- npm install
- npm run build
- name: docker-build-and-push - name: docker-build-and-push
image: plugins/docker image: plugins/docker
environment: environment:
@ -87,23 +140,3 @@ steps:
DB_PORT: DB_PORT:
from_secret: SECRET_DB_PORT from_secret: SECRET_DB_PORT
depends_on: [ docker-build-and-push ] depends_on: [ docker-build-and-push ]
- name: code-analysis
image: node:latest
environment:
SONAR_TOKEN:
from_secret: SONAR_TOKEN
settings:
sources: ./API-Project/src
tests: ./API-Project/tests
sonar.testExecutionReportPaths: ./API-Project/coverage/sonar-report.xml
javascript.lcov.reportPaths: ./API-Project/coverage/lcov.info
commands:
- export SONAR_SCANNER_VERSION=4.7.0.2747
- export SONAR_SCANNER_HOME=$HOME/.sonar/sonar-scanner-$SONAR_SCANNER_VERSION-linux
- curl --create-dirs -sSLo $HOME/.sonar/sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_VERSION-linux.zip
- unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
- export PATH=$SONAR_SCANNER_HOME/bin:$PATH
- export SONAR_SCANNER_OPTS="-server"
- sonar-scanner -X -D sonar.projectKey=LeftOvers_Api -D sonar.host.url=https://codefirst.iut.uca.fr/sonar
depends_on: [ publish-jest-reports ]

@ -9,6 +9,7 @@
"version": "1.0.0", "version": "1.0.0",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@esbuild/linux-x64": "^0.19.8",
"@types/express": "^4.17.21", "@types/express": "^4.17.21",
"@types/morgan": "^1.9.9", "@types/morgan": "^1.9.9",
"cors": "^2.8.5", "cors": "^2.8.5",
@ -726,6 +727,320 @@
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/@esbuild/android-arm": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
"integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
"cpu": [
"arm"
],
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/android-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
"integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/android-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
"integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/darwin-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
"integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/darwin-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
"integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/freebsd-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
"integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/freebsd-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
"integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-arm": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
"integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
"cpu": [
"arm"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
"integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-ia32": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
"integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
"cpu": [
"ia32"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
"integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
"cpu": [
"loong64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-mips64el": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
"integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
"cpu": [
"mips64el"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-ppc64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
"integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
"cpu": [
"ppc64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-riscv64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
"integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
"cpu": [
"riscv64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-s390x": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
"integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
"cpu": [
"s390x"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-x64": {
"version": "0.19.8",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.8.tgz",
"integrity": "sha512-lytMAVOM3b1gPypL2TRmZ5rnXl7+6IIk8uB3eLsV1JwcizuolblXRrc5ShPrO9ls/b+RTp+E6gbsuLWHWi2zGg==",
"cpu": [
"x64"
],
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/netbsd-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
"integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/openbsd-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
"integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/sunos-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
"integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"sunos"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/win32-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
"integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/win32-ia32": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
"integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
"cpu": [
"ia32"
],
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/win32-x64": { "node_modules/@esbuild/win32-x64": {
"version": "0.18.20", "version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
@ -2434,6 +2749,21 @@
"@esbuild/win32-x64": "0.18.20" "@esbuild/win32-x64": "0.18.20"
} }
}, },
"node_modules/esbuild/node_modules/@esbuild/linux-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
"integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/escalade": { "node_modules/escalade": {
"version": "3.1.1", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
@ -6301,6 +6631,131 @@
"@jridgewell/trace-mapping": "0.3.9" "@jridgewell/trace-mapping": "0.3.9"
} }
}, },
"@esbuild/android-arm": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
"integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
"optional": true
},
"@esbuild/android-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
"integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
"optional": true
},
"@esbuild/android-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
"integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
"optional": true
},
"@esbuild/darwin-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
"integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
"optional": true
},
"@esbuild/darwin-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
"integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
"optional": true
},
"@esbuild/freebsd-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
"integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
"optional": true
},
"@esbuild/freebsd-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
"integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
"optional": true
},
"@esbuild/linux-arm": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
"integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
"optional": true
},
"@esbuild/linux-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
"integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
"optional": true
},
"@esbuild/linux-ia32": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
"integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
"optional": true
},
"@esbuild/linux-loong64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
"integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
"optional": true
},
"@esbuild/linux-mips64el": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
"integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
"optional": true
},
"@esbuild/linux-ppc64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
"integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
"optional": true
},
"@esbuild/linux-riscv64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
"integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
"optional": true
},
"@esbuild/linux-s390x": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
"integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
"optional": true
},
"@esbuild/linux-x64": {
"version": "0.19.8",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.8.tgz",
"integrity": "sha512-lytMAVOM3b1gPypL2TRmZ5rnXl7+6IIk8uB3eLsV1JwcizuolblXRrc5ShPrO9ls/b+RTp+E6gbsuLWHWi2zGg=="
},
"@esbuild/netbsd-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
"integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
"optional": true
},
"@esbuild/openbsd-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
"integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
"optional": true
},
"@esbuild/sunos-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
"integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
"optional": true
},
"@esbuild/win32-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
"integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
"optional": true
},
"@esbuild/win32-ia32": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
"integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
"optional": true
},
"@esbuild/win32-x64": { "@esbuild/win32-x64": {
"version": "0.18.20", "version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
@ -7649,6 +8104,14 @@
"@esbuild/win32-arm64": "0.18.20", "@esbuild/win32-arm64": "0.18.20",
"@esbuild/win32-ia32": "0.18.20", "@esbuild/win32-ia32": "0.18.20",
"@esbuild/win32-x64": "0.18.20" "@esbuild/win32-x64": "0.18.20"
},
"dependencies": {
"@esbuild/linux-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
"integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
"optional": true
}
} }
}, },
"escalade": { "escalade": {

@ -6,18 +6,21 @@
"scripts": { "scripts": {
"start": "node dist/server.js", "start": "node dist/server.js",
"build": "tsup src/server.ts --format cjs --clean", "build": "tsup src/server.ts --format cjs --clean",
"install-build-start": "npm i && npm run build && npm start",
"dev": "nodemon --watch src -e js,ts,json --exec \"ts-node src/server.ts\"", "dev": "nodemon --watch src -e js,ts,json --exec \"ts-node src/server.ts\"",
"test": "jest --detectOpenHandles", "test": "jest --detectOpenHandles",
"test:watch": "jest --watchAll", "test:watch": "jest --watchAll",
"test:coverage": "jest --coverage" "test:coverage": "jest --coverage",
"test:CI": "jest --coverage --testTimeout=120000"
}, },
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@esbuild/linux-x64": "^0.19.8",
"@types/express": "^4.17.21", "@types/express": "^4.17.21",
"@types/morgan": "^1.9.9", "@types/morgan": "^1.9.9",
"dotenv": "^16.3.1",
"cors": "^2.8.5", "cors": "^2.8.5",
"dotenv": "^16.3.1",
"express": "^4.18.2", "express": "^4.18.2",
"helmet": "^7.1.0", "helmet": "^7.1.0",
"morgan": "^1.10.0", "morgan": "^1.10.0",
@ -39,7 +42,9 @@
}, },
"jest": { "jest": {
"preset": "ts-jest", "preset": "ts-jest",
"testMatch": ["<rootDir>/tests/**/*.spec.ts"], "testMatch": [
"<rootDir>/tests/**/*.spec.ts"
],
"testResultsProcessor": "jest-sonar-reporter" "testResultsProcessor": "jest-sonar-reporter"
}, },
"jestSonar": { "jestSonar": {

@ -1,5 +1,4 @@
import { Router } from "express"; import { Router } from "express";
import { Exceptions } from "../utils/exception";
import { IngredientsGateway } from "../gateways/ingredients.gateway"; import { IngredientsGateway } from "../gateways/ingredients.gateway";
const IngredientsController = Router() const IngredientsController = Router()
@ -8,14 +7,15 @@ const ingredient_gw = new IngredientsGateway()
IngredientsController.get('/filter/:prompt', async (req, res) => { IngredientsController.get('/filter/:prompt', async (req, res) => {
const letter = req.params.prompt; const prompt = req.params.prompt;
if (!letter) { if (!prompt) {
throw new Exceptions.BadRequestException('prompt is invalid!'); res.status(400).send('invalid parameter or no parameter')
return
} }
try { try {
const ingredient = await ingredient_gw.filter(letter); const ingredient = await ingredient_gw.filter(prompt);
if (ingredient == null) { if (ingredient == null) {
res.status(404).send('Not found'); res.status(404).send('Not found');
@ -32,7 +32,8 @@ IngredientsController.get('/letter/:letter', async (req, res) => {
const letter = req.params.letter; const letter = req.params.letter;
if (!letter) { if (!letter) {
throw new Exceptions.BadRequestException('Letter is invalid!'); res.status(400).send('invalid parameter or no parameter')
return
} }
try { try {
@ -54,7 +55,8 @@ IngredientsController.get('/:id', async (req, res) => {
const id = Number(req.params.id); const id = Number(req.params.id);
if (!Number.isInteger(id)) { if (!Number.isInteger(id)) {
throw new Exceptions.BadRequestException('id invalid !'); res.status(400).send('invalid parameter')
return
} }
try { try {

@ -0,0 +1,66 @@
import { Router } from "express";
import { IngredientsClassesGateway } from "../gateways/ingredientsClasses.gateway";
import { RecipeGateway } from "../gateways/recipe.gateway";
import { IngredientsClasses } from "../types/ingredientsClasses";
const IngredientsClassesController = Router();
const class_gw: IngredientsClassesGateway = new IngredientsClassesGateway();
const recipe_gw: RecipeGateway = new RecipeGateway();
function validateAndParseId(req: any, res: any): number | null {
const id = Number(req.params.id);
if (!Number.isInteger(id)) {
res.status(400).send('Invalid parameter or no parameter');
return null;
}
return id;
}
IngredientsClassesController.get('/ofingr/:id', async (req, res) => {
const id = validateAndParseId(req, res);
if (id === null) return;
try {
const classes = await class_gw.getForIngredient(id);
if (classes.length === 0) {
res.status(404).send('Not found');
} else {
res.status(200).json(classes);
}
} catch (error) {
const error_error = error as Error;
res.status(500).send(error_error.message);
}
});
IngredientsClassesController.get('/ofrecipe/:id', async (req, res) => {
const id = validateAndParseId(req, res);
if (id === null) return;
try {
const recipe = await recipe_gw.getById(id);
if (!recipe) {
res.status(404).send('Recipe not found');
return;
}
let final_classes: IngredientsClasses[] = Array.from(new Set(Object.values(IngredientsClasses)));
for (const ingredient of recipe.ingredients) {
const new_classes: IngredientsClasses[] = await class_gw.getForIngredient(ingredient.id);
final_classes = final_classes.filter(item => new_classes.includes(item));
}
res.status(200).json(final_classes);
} catch (error) {
const error_error = error as Error;
res.status(500).send(error_error.message);
}
});
export { IngredientsClassesController };

@ -1,5 +1,4 @@
import { Router } from "express"; import { Router } from "express";
import { Exceptions } from "../utils/exception";
import { RecipeGateway } from "../gateways/recipe.gateway"; import { RecipeGateway } from "../gateways/recipe.gateway";
@ -22,7 +21,8 @@ RecipesController.get('/:id', async (req, res) => {
const id = Number(req.params.id); const id = Number(req.params.id);
if (!Number.isInteger(id)) { if (!Number.isInteger(id)) {
throw new Exceptions.BadRequestException('id invalid !'); res.status(400).send('invalid parameter or no parameter')
return
} }
try { try {
@ -46,7 +46,8 @@ RecipesController.get('/withingr/:ids', async (req, res) => {
for (let key in raw_ids) { for (let key in raw_ids) {
const test = Number(raw_ids[key]) const test = Number(raw_ids[key])
if (Number.isNaN(test) || !Number.isInteger(test)) { if (Number.isNaN(test) || !Number.isInteger(test)) {
res.status(400).json('A parameter is not an integer') res.status(400).send('A parameter is not an integer')
return
} }
ids.push(Number(test)) ids.push(Number(test))
} }
@ -55,7 +56,7 @@ RecipesController.get('/withingr/:ids', async (req, res) => {
const recipes = await recipes_gw.getIdsRecipesThatContainsIngredients(ids) const recipes = await recipes_gw.getIdsRecipesThatContainsIngredients(ids)
if (recipes.length == 0) { if (recipes.length == 0) {
res.status(404).json('no data found') res.status(404).send('no data found')
} }
else { else {
res.status(200).json(recipes) res.status(200).json(recipes)
@ -66,4 +67,49 @@ RecipesController.get('/withingr/:ids', async (req, res) => {
} }
}) })
RecipesController.get('/getcommentsdictionary/:id', async (req, res) => {
const id: number = Number(req.params.id)
if (Number.isNaN(id) || !Number.isInteger(id)) {
res.status(400).send('The parameter is not an integer')
return
}
try {
const dictionary_comments = await recipes_gw.getCommentsDictionary(id)
if (Object.keys(dictionary_comments).length == 0) {
res.status(404).send('no data found')
}
else {
res.status(200).json(dictionary_comments)
}
}
catch (error) {
const error_error = error as Error
res.status(500).send(error_error.message)
}
})
RecipesController.get('/getratinglist/:id', async (req, res) => {
const id: number = Number(req.params.id)
if (Number.isNaN(id) || !Number.isInteger(id)) {
res.status(400).send('The parameter is not an integer')
return
}
try {
const rating_list = await recipes_gw.getRatingList(id)
if (rating_list.length == 0) {
res.status(404).send('no data found')
}
else {
res.status(200).json(rating_list)
}
}
catch (error) {
const error_error = error as Error
res.status(500).send(error_error.message)
}
})
export { RecipesController } export { RecipesController }

@ -1,5 +1,4 @@
import { Router } from "express"; import { Router } from "express";
import { Exceptions } from "../utils/exception";
import { StepsGateway } from "../gateways/steps.gateway"; import { StepsGateway } from "../gateways/steps.gateway";
@ -8,16 +7,17 @@ const steps_gw = new StepsGateway()
StepsController.get('/:id', async (req, res) => { StepsController.get('/:id', async (req, res) => {
const id = String(req.params.id); const id = Number(req.params.id);
if (!Number.isInteger(id)) { if (!Number.isInteger(id)) {
throw new Exceptions.BadRequestException('id invalid !'); res.status(400).send('invalid parameter or no parameter')
return
} }
try { try {
const steps = await steps_gw.getForRecipes(Number(id)) const steps = await steps_gw.getForRecipes(Number(id))
if (steps == null) { if (steps.length == 0) {
res.status(404).send('not found') res.status(404).send('not found')
} }
else { else {

@ -1,5 +1,5 @@
import { Pool, PoolClient } from "pg" import { Pool, PoolClient } from "pg"
require('dotenv').config();
export class Connection { export class Connection {
private pool:Pool private pool:Pool

@ -0,0 +1,48 @@
import { Connection } from "../database/connection"
import { IngredientsClasses } from "../types/ingredientsClasses"
function convertToEnum<T extends Record<string, string>>(enumObject: T, value: string): T[keyof T] | undefined {
const enumKeys = Object.keys(enumObject) as Array<keyof T>;
const enumValues = enumKeys.map(key => enumObject[key]);
const index = enumValues.indexOf(value as T[keyof T]);
return index !== -1 ? enumValues[index] as T[keyof T] : undefined;
}
export class IngredientsClassesGateway {
connection: Connection
constructor() {
this.connection = new Connection()
}
async getForIngredient(id: number): Promise<IngredientsClasses[]> {
const client = await this.connection.getPoolClient()
let classes : IngredientsClasses[] = []
const query = {
text: 'SELECT name FROM IngredientsClassesAttribution, IngredientsClasses WHERE idIngredient = $1 AND idClass = id',
values: [id],
}
const res = await client.query(query)
client.release()
for (let row of res.rows) {
const classNameString: string = row.name;
const classNameEnum: IngredientsClasses | undefined = convertToEnum(IngredientsClasses, classNameString);
if (classNameEnum !== undefined) {
classes.push(classNameEnum);
}
}
console.log(classes)
return classes
}
}

@ -88,4 +88,48 @@ export class RecipeGateway {
return recipes as Recipe[]; return recipes as Recipe[];
} }
async getCommentsDictionary(id: number): Promise<{[word: string]: number}> {
let comments_dictionary: {[word: string]: number} = {}
const client = await this.connection.getPoolClient()
const query = {
text: 'SELECT comments_dico FROM Recipes WHERE id=$1',
values: [id]
}
const res = await client.query(query)
client.release()
if (res.rows != null && res.rows.length >= 1 && res.rows[0] != null) {
const dictionnary_as_str: string = res.rows[0].comments_dico.replace(/'/g, '"')
comments_dictionary = JSON.parse(dictionnary_as_str);
}
return comments_dictionary
}
async getRatingList(id: number): Promise<number[]> {
let rating_list: number[] = []
const client = await this.connection.getPoolClient()
const query = {
text: 'SELECT rating FROM Recipes WHERE id=$1',
values: [id]
}
const res = await client.query(query)
client.release()
if (res.rows != null && res.rows.length >= 1 && res.rows[0] != null) {
const list_as_str: string = res.rows[0].rating
rating_list = JSON.parse(list_as_str);
}
return rating_list
}
} }

@ -4,8 +4,8 @@ import cors from "cors";
import { IngredientsController } from "./controllers/ingredients.controller"; import { IngredientsController } from "./controllers/ingredients.controller";
import { RecipesController } from "./controllers/recipes.controller"; import { RecipesController } from "./controllers/recipes.controller";
import { StepsController } from "./controllers/steps.controller"; import { StepsController } from "./controllers/steps.controller";
import { IngredientsClassesGateway } from "./gateways/ingredientsClasses.gateway";
console.log(process.env.DB_USERNAME); import { IngredientsClassesController } from "./controllers/ingredientsClasses.controller";
let helmet = require("helmet"); let helmet = require("helmet");
const app = express(); const app = express();
@ -17,15 +17,22 @@ app.use(cors({
})); }));
app.get('/', (req, res) => { app.get('/', (req, res) => {
res.json({ message: 'Hello from express and typescript!' }); res.status(200).send('Hello from express and typescript!');
}); });
app.use('/ingredients', IngredientsController); app.use('/ingredients', IngredientsController);
app.use('/recipes', RecipesController); app.use('/recipes', RecipesController);
app.use('/steps', StepsController); app.use('/steps', StepsController);
app.use('/class', IngredientsClassesController);
const port = Number(process.env.PORT) || 3000;
const port = process.env.PORT || 3000; export const startServer = (port_to_use: number) => {
return app.listen(port_to_use, () => console.log(`App listening on PORT ${port_to_use}`));
};
export const server = app.listen(port, () => console.log(`App listening on PORT ${port}`)); if (require.main === module) {
startServer(port);
}
export default app; export default app;

@ -0,0 +1,8 @@
export enum IngredientsClasses {
DairyFree = 'DAIRY_FREE',
GlutenFree = 'GLUTEN_FREE',
Porcless = 'PORCLESS',
Vegan = 'VEGAN',
Vegetarian = 'VEGETARIAN',
Pescatarian = 'PESCATARIAN'
}

@ -25,12 +25,4 @@ export class Recipe implements IRecipe {
this.ingredients = ingredients this.ingredients = ingredients
this.steps = steps this.steps = steps
} }
addStep(newStep: string) {
this.steps.push(newStep)
}
addIngredient(newIngredient: IIngredient) {
this.ingredients.push(newIngredient)
}
} }

@ -1,7 +1,19 @@
import request from 'supertest'; import request from 'supertest';
import app, {server} from '../src/server'; import app, { startServer } from '../src/server';
import { Server, IncomingMessage, ServerResponse } from 'http';
describe('GET /api/endpoint', () => { describe('GET /api/endpoint', () => {
let server: Server<typeof IncomingMessage, typeof ServerResponse>;
const port = 3000
beforeAll(() => {
server = startServer(port);
});
afterAll((done) => {
server.close(done);
});
it('should return a 200 status code', async () => { it('should return a 200 status code', async () => {
const response = await request(app).get('/'); const response = await request(app).get('/');
expect(response.status).toBe(200); expect(response.status).toBe(200);
@ -9,5 +21,4 @@ describe('GET /api/endpoint', () => {
// Ecrire d'autres tests ici // Ecrire d'autres tests ici
server.close()
}); });

@ -0,0 +1,71 @@
import request from 'supertest';
import app, { startServer } from '../src/server';
import { Server, IncomingMessage, ServerResponse } from 'http';
describe('GET /ingredients', () => {
let server: Server<typeof IncomingMessage, typeof ServerResponse>;
const port = 3001
beforeAll(() => {
server = startServer(port);
});
afterAll((done) => {
server.close(done);
});
// /ingredients/
it('should return a 200 status code', async () => {
const response = await request(app).get('/ingredients/');
expect(response.status).toBe(200);
});
// /ingredients/:id
it('should return a 200 status code', async () => {
const response = await request(app).get('/ingredients/1');
expect(response.status).toBe(200);
});
it('should return a 400 status code', async () => {
const response = await request(app).get('/ingredients/l');
expect(response.status).toBe(400);
});
it('should return a 404 status code', async () => {
const response = await request(app).get('/ingredients/8024');
expect(response.status).toBe(404);
});
// /ingredients/letter/:letter
it('should return a 200 status code', async () => {
const response = await request(app).get('/ingredients/letter/l');
expect(response.status).toBe(200);
});
it('should return a 404 status code', async () => {
const response = await request(app).get('/ingredients/letter/oui');
expect(response.status).toBe(404);
});
it('should return a 400 status code', async () => {
const response = await request(app).get('/ingredients/letter/');
expect(response.status).toBe(400);
});
// /ingredients/filter/:prompt
it('should return a 200 status code', async () => {
const response = await request(app).get('/ingredients/filter/car');
expect(response.status).toBe(200);
});
it('should return a 404 status code', async () => {
const response = await request(app).get('/ingredients/filter/slumaprottube');
expect(response.status).toBe(404);
});
it('should return a 400 status code', async () => {
const response = await request(app).get('/ingredients/filter/');
expect(response.status).toBe(400);
});
});

@ -0,0 +1,102 @@
import request from 'supertest';
import app, { startServer } from '../src/server';
import { Server, IncomingMessage, ServerResponse } from 'http';
describe('GET /recipes', () => {
let server: Server<typeof IncomingMessage, typeof ServerResponse>;
const port = 3002
beforeAll(() => {
server = startServer(port);
});
afterAll((done) => {
server.close(done);
});
// /recipes/
it('should return a 200 status code', async () => {
const response = await request(app).get('/recipes/');
expect(response.status).toBe(200);
}, 120000);
// /recipes/:id
it('should return a 200 status code', async () => {
const response = await request(app).get('/recipes/4444');
expect(response.status).toBe(200);
});
it('should return a 400 status code', async () => {
const response = await request(app).get('/recipes/oui');
expect(response.status).toBe(400);
});
it('should return a 404 status code', async () => {
const response = await request(app).get('/recipes/1');
expect(response.status).toBe(404);
});
// /recipes/withingr/:ids
it('should return a 200 status code', async () => {
const response = await request(app).get('/recipes/withingr/1928:2148:2809:2853:3723:6261:6335:7076');
expect(response.status).toBe(200);
});
it('should return a 400 status code', async () => {
const response = await request(app).get('/recipes/withingr/oui');
expect(response.status).toBe(400);
});
it('should return a 400 status code', async () => {
const response = await request(app).get('/recipes/withingr/2:oui:3');
expect(response.status).toBe(400);
});
it('should return a 404 status code', async () => {
const response = await request(app).get('/recipes/withingr/1');
expect(response.status).toBe(404);
});
// /recipes/getcommentsdictionary/:id
it('should return a 200 status code', async () => {
const response = await request(app).get('/recipes/getcommentsdictionary/4444');
expect(response.status).toBe(200);
});
it('should return a 400 status code', async () => {
const response = await request(app).get('/recipes/getcommentsdictionary/oui');
expect(response.status).toBe(400);
});
it('should return a 400 status code', async () => {
const response = await request(app).get('/recipes/getcommentsdictionary/');
expect(response.status).toBe(400);
});
it('should return a 404 status code', async () => {
const response = await request(app).get('/recipes/getcommentsdictionary/1');
expect(response.status).toBe(404);
});
// /recipes/getratinglist/:id
it('should return a 200 status code', async () => {
const response = await request(app).get('/recipes/getratinglist/4444');
expect(response.status).toBe(200);
});
it('should return a 400 status code', async () => {
const response = await request(app).get('/recipes/getratinglist/oui');
expect(response.status).toBe(400);
});
it('should return a 400 status code', async () => {
const response = await request(app).get('/recipes/getratinglist/');
expect(response.status).toBe(400);
});
it('should return a 404 status code', async () => {
const response = await request(app).get('/recipes/getratinglist/1');
expect(response.status).toBe(404);
});
});

@ -0,0 +1,33 @@
import request from 'supertest';
import app, { startServer } from '../src/server';
import { Server, IncomingMessage, ServerResponse } from 'http';
describe('GET /steps', () => {
let server: Server<typeof IncomingMessage, typeof ServerResponse>;
const port = 3003
beforeAll(() => {
server = startServer(port);
});
afterAll((done) => {
server.close(done);
});
// /steps/:id
it('should return a 200 status code', async () => {
const response = await request(app).get('/steps/4444');
expect(response.status).toBe(200);
});
it('should return a 400 status code', async () => {
const response = await request(app).get('/steps/hey');
expect(response.status).toBe(400);
});
it('should return a 404 status code', async () => {
const response = await request(app).get('/steps/1');
expect(response.status).toBe(404);
});
});

@ -1,3 +1,41 @@
# LeftOvers_Api <div align = center>
L'Api de LeftOvers permet de récupérer des aliments et recettes depuis une base de données. ![Image de l'application](Images/LeftOvers_Logo.jpg)
</div>
**Nom de lAPI** : LeftOvers_API :pizza:
</br>
**Thème de lAPI** : Permet le lien entre l'application et la base de données
</br>
**Récapitulation de notre API** : 👇
</br>
# Répartition du Repository Git
La racine de notre repo est composée de deux dossiers essentiels au projet:
[**LeftOvers**](LeftOvers) : **Toute la partie codage de l'application mobile**
[**Images**](Images) : **Images de l'application**
👉 [**Solution de l'application**](LeftOvers/App.tsx)
# Description des routes
# Technicien en charge de l'application
La composition pour le projet se voit réaliser par trois élèves de l'IUT d'Aubière:
<br>
⚙️ Louison PARANT
<br>
⚙️ Rayhan HASSOU
<br>
⚙️ Remi REGNAULT
<div align = center>
© FI Groupe 2
</div>
Loading…
Cancel
Save