fix: update dependencies to latest
This commit is contained in:
		| @@ -1 +1 @@ | ||||
| FROM mcr.microsoft.com/devcontainers/javascript-node:18 | ||||
| FROM mcr.microsoft.com/devcontainers/javascript-node:20 | ||||
|   | ||||
| @@ -6,20 +6,19 @@ | ||||
|   "customizations": { | ||||
|     "vscode": { | ||||
|       "settings": { | ||||
|         "remote.autoForwardPorts": false | ||||
|       }, | ||||
|       "extensions": [ | ||||
|         "editorconfig.editorconfig", | ||||
|         "esbenp.prettier-vscode", | ||||
|         "dbaeumer.vscode-eslint", | ||||
|         "davidanson.vscode-markdownlint", | ||||
|         "prisma.prisma", | ||||
|         "mikestead.dotenv", | ||||
|         "ms-azuretools.vscode-docker" | ||||
|       ] | ||||
|     } | ||||
|         "remote.autoForwardPorts": false, | ||||
|         "remote.localPortHost": "allInterfaces" | ||||
|       } | ||||
|     }, | ||||
|     "extensions": [ | ||||
|       "editorconfig.editorconfig", | ||||
|       "esbenp.prettier-vscode", | ||||
|       "dbaeumer.vscode-eslint", | ||||
|       "davidanson.vscode-markdownlint", | ||||
|       "prisma.prisma", | ||||
|       "mikestead.dotenv", | ||||
|       "ms-azuretools.vscode-docker" | ||||
|     ] | ||||
|   }, | ||||
|   "forwardPorts": [8080, 5555, 5432, 1080], | ||||
|   "postAttachCommand": ["npm", "install"], | ||||
|   "remoteUser": "node" | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,3 @@ | ||||
| version: '3.0' | ||||
|  | ||||
| services: | ||||
|   workspace: | ||||
|     build: | ||||
| @@ -8,18 +6,18 @@ services: | ||||
|     volumes: | ||||
|       - '..:/workspace:cached' | ||||
|     command: 'sleep infinity' | ||||
|     extra_hosts: | ||||
|       - 'host.docker.internal:host-gateway' | ||||
|     network_mode: 'host' | ||||
|  | ||||
|   thream-database: | ||||
|     image: 'postgres:15.3' | ||||
|     environment: | ||||
|       POSTGRES_USER: 'user' | ||||
|       POSTGRES_USER: 'thream_user' | ||||
|       POSTGRES_PASSWORD: 'password' | ||||
|       POSTGRES_DB: 'thream' | ||||
|     volumes: | ||||
|       - 'postgres-data:/var/lib/postgresql/data' | ||||
|       - 'thream-postgres-data:/var/lib/postgresql/data' | ||||
|     restart: 'unless-stopped' | ||||
|     network_mode: 'host' | ||||
|  | ||||
| volumes: | ||||
|   postgres-data: | ||||
|   thream-postgres-data: | ||||
|   | ||||
							
								
								
									
										22
									
								
								.env.example
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								.env.example
									
									
									
									
									
								
							| @@ -1,14 +1,22 @@ | ||||
| API_URL=http://localhost:8080 | ||||
| API_URL=http://127.0.0.1:8080 | ||||
| COMPOSE_PROJECT_NAME=thream-api | ||||
| DATABASE_URL=postgresql://user:password@thream-database:5432/thream | ||||
|  | ||||
| DATABASE_USER=thream_user | ||||
| DATABASE_PASSWORD=password | ||||
| DATABASE_NAME=thream | ||||
| DATABASE_URL=postgresql://thream_user:password@127.0.0.1:5432/thream | ||||
|  | ||||
| EMAIL_HOST=0.0.0.0 | ||||
| EMAIL_PASSWORD=password | ||||
| EMAIL_PORT=1025 | ||||
| EMAIL_USER=no-reply@thream.fr | ||||
|  | ||||
| DISCORD_CLIENT_ID= | ||||
| DISCORD_CLIENT_SECRET= | ||||
| EMAIL_HOST=thream-maildev | ||||
| EMAIL_PASSWORD=password | ||||
| EMAIL_PORT=25 | ||||
| EMAIL_USER=no-reply@thream.fr | ||||
|  | ||||
| FILE_UPLOADS_API_KEY=apiKeySecret | ||||
| FILE_UPLOADS_API_URL=http://host.docker.internal:8000 | ||||
| FILE_UPLOADS_API_URL=http://127.0.0.1:8000 | ||||
|  | ||||
| GITHUB_CLIENT_ID= | ||||
| GITHUB_CLIENT_SECRET= | ||||
| GOOGLE_CLIENT_ID= | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| { | ||||
|   "extends": ["conventions", "prettier"], | ||||
|   "plugins": ["prettier", "import", "unicorn"], | ||||
|   "parser": "@typescript-eslint/parser", | ||||
|   "parserOptions": { | ||||
|     "project": "./tsconfig.json" | ||||
|   }, | ||||
|   | ||||
							
								
								
									
										2
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							| @@ -15,7 +15,7 @@ jobs: | ||||
|       - name: 'Setup Node.js' | ||||
|         uses: 'actions/setup-node@v3.6.0' | ||||
|         with: | ||||
|           node-version: '18.x' | ||||
|           node-version: '20.x' | ||||
|           cache: 'npm' | ||||
|  | ||||
|       - name: 'Install dependencies' | ||||
|   | ||||
							
								
								
									
										7
									
								
								.github/workflows/lint.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								.github/workflows/lint.yml
									
									
									
									
										vendored
									
									
								
							| @@ -15,7 +15,7 @@ jobs: | ||||
|       - name: 'Setup Node.js' | ||||
|         uses: 'actions/setup-node@v3.6.0' | ||||
|         with: | ||||
|           node-version: '18.x' | ||||
|           node-version: '20.x' | ||||
|           cache: 'npm' | ||||
|  | ||||
|       - name: 'Install dependencies' | ||||
| @@ -36,10 +36,5 @@ jobs: | ||||
|       - name: 'lint:prettier' | ||||
|         run: 'npm run lint:prettier' | ||||
|  | ||||
|       - name: 'lint:dotenv' | ||||
|         uses: 'dotenv-linter/action-dotenv-linter@v2' | ||||
|         with: | ||||
|           github_token: ${{ secrets.github_token }} | ||||
|  | ||||
|       - name: 'prisma:validate' | ||||
|         run: 'cp .env.example .env && npm run prisma:validate' | ||||
|   | ||||
							
								
								
									
										2
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							| @@ -23,7 +23,7 @@ jobs: | ||||
|       - name: 'Setup Node.js' | ||||
|         uses: 'actions/setup-node@v3.6.0' | ||||
|         with: | ||||
|           node-version: '18.x' | ||||
|           node-version: '20.x' | ||||
|           cache: 'npm' | ||||
|  | ||||
|       - name: 'Install dependencies' | ||||
|   | ||||
							
								
								
									
										2
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							| @@ -15,7 +15,7 @@ jobs: | ||||
|       - name: 'Setup Node.js' | ||||
|         uses: 'actions/setup-node@v3.6.0' | ||||
|         with: | ||||
|           node-version: '18.x' | ||||
|           node-version: '20.x' | ||||
|           cache: 'npm' | ||||
|  | ||||
|       - name: 'Install dependencies' | ||||
|   | ||||
| @@ -1,5 +0,0 @@ | ||||
| { | ||||
|   "reporter": ["text", "cobertura"], | ||||
|   "src": "./build", | ||||
|   "all": true | ||||
| } | ||||
							
								
								
									
										8
									
								
								.taprc
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								.taprc
									
									
									
									
									
								
							| @@ -1,8 +0,0 @@ | ||||
| ts: false | ||||
| jsx: false | ||||
| flow: false | ||||
| check-coverage: false | ||||
| coverage: false | ||||
|  | ||||
| files: | ||||
|   - 'build/**/*.test.js' | ||||
| @@ -67,7 +67,7 @@ git commit -m "fix: should emit events to connected users" | ||||
|  | ||||
| We have API REST services for the `channels`. | ||||
|  | ||||
| Here is what potentially look like a folder structure for this service : | ||||
| Here is what potentially look like a folder structure for this service: | ||||
|  | ||||
| ```text | ||||
| └── src | ||||
| @@ -86,7 +86,7 @@ Here is what potentially look like a folder structure for this service : | ||||
|             └── index.ts | ||||
| ``` | ||||
|  | ||||
| This folder structure will map to these REST API routes : | ||||
| This folder structure will map to these REST API routes: | ||||
|  | ||||
| - GET `/channels` | ||||
| - DELETE `/channels/:channelId` | ||||
|   | ||||
							
								
								
									
										11
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								Dockerfile
									
									
									
									
									
								
							| @@ -1,21 +1,22 @@ | ||||
| FROM node:18.16.1 AS dependencies | ||||
| FROM node:20.5.0 AS dependencies | ||||
| WORKDIR /usr/src/app | ||||
| COPY ./package*.json ./ | ||||
| RUN npm install | ||||
| RUN npm clean-install | ||||
|  | ||||
| FROM node:18.16.1 AS builder | ||||
| FROM node:20.5.0 AS builder | ||||
| WORKDIR /usr/src/app | ||||
| COPY --from=dependencies /usr/src/app/node_modules ./node_modules | ||||
| COPY ./ ./ | ||||
| RUN npm run prisma:generate && npm run build | ||||
|  | ||||
| FROM node:18.16.1 AS runner | ||||
| FROM node:20.5.0 AS runner | ||||
| WORKDIR /usr/src/app | ||||
| ENV NODE_ENV=production | ||||
| ENV NODE_OPTIONS=--enable-source-maps | ||||
| COPY --from=builder /usr/src/app/node_modules ./node_modules | ||||
| COPY --from=builder /usr/src/app/package.json ./package.json | ||||
| COPY --from=builder /usr/src/app/email ./email | ||||
| COPY --from=builder /usr/src/app/build ./build | ||||
| COPY --from=builder /usr/src/app/prisma ./prisma | ||||
| USER node | ||||
| CMD ["node", "build/index.js"] | ||||
| CMD npm run prisma:migrate:deploy && node build/index.js | ||||
|   | ||||
							
								
								
									
										69
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										69
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| <h1 align="center"><a href="https://api.thream.divlo.fr/documentation">Thream/api</a></h1> | ||||
| <h1 align="center"><a href="https://api.thream.theoludwig.fr/documentation">Thream/api</a></h1> | ||||
|  | ||||
| <p align="center"> | ||||
|   <a href="./CONTRIBUTING.md"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat" /></a> | ||||
| @@ -18,7 +18,7 @@ | ||||
|  | ||||
| Thream's Application Programming Interface (API) to stay close with your friends and communities. | ||||
|  | ||||
| It uses [Thream/file-uploads-api](https://github.com/Thream/file-uploads-api) [v1.1.5](https://github.com/Thream/file-uploads-api/releases/tag/v1.1.5). | ||||
| It uses [Thream/file-uploads-api](https://github.com/Thream/file-uploads-api) [v1.1.6](https://github.com/Thream/file-uploads-api/releases/tag/v1.1.6). | ||||
|  | ||||
| ## ⚙️ Getting Started | ||||
|  | ||||
| @@ -37,46 +37,75 @@ git clone git@github.com:Thream/api.git | ||||
| # Go to the project root | ||||
| cd api | ||||
|  | ||||
| # Install dependencies | ||||
| npm clean-install | ||||
|  | ||||
| # Configure environment variables | ||||
| cp .env.example .env | ||||
|  | ||||
| # Install | ||||
| npm install | ||||
| # Generate Prisma client types | ||||
| npm run prisma:generate | ||||
| ``` | ||||
|  | ||||
| You will need to configure the environment variables by creating an `.env` file at | ||||
| the root of the project (see `.env.example`). | ||||
| ### Database Setup | ||||
|  | ||||
| ```sh | ||||
| # Create a new user and database | ||||
| psql | ||||
| CREATE DATABASE thream; | ||||
| CREATE USER thream_user with encrypted password 'password'; | ||||
| ALTER USER thream_user WITH SUPERUSER; | ||||
| ``` | ||||
|  | ||||
| ### Database Production migration | ||||
|  | ||||
| ```sh | ||||
| npm run prisma:migrate:deploy | ||||
| ``` | ||||
|  | ||||
| ### Local Development environment | ||||
|  | ||||
| Recommended to use [VSCode: Remote development in Containers](https://code.visualstudio.com/docs/remote/containers-tutorial). | ||||
|  | ||||
| #### Setup the database | ||||
|  | ||||
| ```sh | ||||
| # Create a new user and database | ||||
| psql | ||||
| create database thream_database; | ||||
| create user thream_user with encrypted password 'password'; | ||||
| ALTER USER thream_user WITH SUPERUSER; | ||||
| ``` | ||||
|  | ||||
| Replace `DATABASE_URL` inside `.env` with `postgresql://thream_user:password@localhost:5432/thream_database` | ||||
| #### Database Development migration | ||||
|  | ||||
| ```sh | ||||
| # Run Prisma migrations | ||||
| npm run prisma:migrate:dev | ||||
|  | ||||
| # Reset the database (WARNING: This will delete all data) | ||||
| npm run prisma:migrate:reset | ||||
| ``` | ||||
|  | ||||
| #### Usage | ||||
|  | ||||
| ```sh | ||||
| # Run API | ||||
| npm run dev | ||||
| ``` | ||||
|  | ||||
| # Run Prisma Studio | ||||
| npm run prisma:studio | ||||
| ##### Services started | ||||
|  | ||||
| - `api`: <http://127.0.0.1:8080> | ||||
| - [Maildev](https://maildev.github.io/maildev/): <http://127.0.0.1:1080> | ||||
| - [Prisma Studio](https://www.prisma.io/studio): <http://127.0.0.1:5555> | ||||
|  | ||||
| ##### Commands | ||||
|  | ||||
| ```sh | ||||
| # Build, Lint and Test | ||||
| npm run build | ||||
| npm run build:typescript | ||||
| npm run lint:editorconfig | ||||
| npm run lint:markdown | ||||
| npm run lint:eslint | ||||
| npm run lint:prettier | ||||
| npm run test | ||||
| ``` | ||||
|  | ||||
| ### Production environment (with [Docker](https://www.docker.com/)) | ||||
|  | ||||
| ```sh | ||||
| docker compose up --build | ||||
| ``` | ||||
|  | ||||
| ## 💡 Contributing | ||||
|   | ||||
							
								
								
									
										27
									
								
								docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| services: | ||||
|   thream-api: | ||||
|     container_name: 'thream-api' | ||||
|     image: 'thream-api' | ||||
|     restart: 'unless-stopped' | ||||
|     network_mode: 'host' | ||||
|     build: | ||||
|       context: './' | ||||
|     env_file: '.env' | ||||
|     depends_on: | ||||
|       - 'thream-database' | ||||
|  | ||||
|   thream-database: | ||||
|     container_name: 'thream-database' | ||||
|     image: 'postgres:15.3' | ||||
|     restart: 'unless-stopped' | ||||
|     network_mode: 'host' | ||||
|     env_file: '.env' | ||||
|     environment: | ||||
|       POSTGRES_USER: ${DATABASE_USER} | ||||
|       POSTGRES_PASSWORD: ${DATABASE_PASSWORD} | ||||
|       POSTGRES_DB: ${DATABASE_NAME} | ||||
|     volumes: | ||||
|       - 'thream-postgres-data:/var/lib/postgresql/data' | ||||
|  | ||||
| volumes: | ||||
|   thream-postgres-data: | ||||
| @@ -1,18 +1,20 @@ | ||||
| import tap from 'tap' | ||||
| import test from 'node:test' | ||||
| import assert from 'node:assert/strict' | ||||
|  | ||||
| import sinon from 'sinon' | ||||
|  | ||||
| import { application } from 'application.js' | ||||
| import { application } from '#src/application.js' | ||||
| {{#if shouldBeAuthenticated}} | ||||
| import { authenticateUserTest } from '__test__/utils/authenticateUserTest.js' | ||||
| import { authenticateUserTest } from '#src/__test__/utils/authenticateUserTest.js' | ||||
| {{/if}} | ||||
| import prisma from 'tools/database/prisma.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
|  | ||||
| await tap.test('{{httpMethod}} {{url}}', async (t) => { | ||||
| await test('{{httpMethod}} {{url}}', async (t) => { | ||||
|   t.afterEach(() => { | ||||
|     sinon.restore() | ||||
|   }) | ||||
|  | ||||
|   await t.test('succeeds', async (t) => { | ||||
|   await t.test('succeeds', async () => { | ||||
|     {{#if shouldBeAuthenticated}} | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     {{/if}} | ||||
| @@ -32,6 +34,6 @@ await tap.test('{{httpMethod}} {{url}}', async (t) => { | ||||
|       payload: {} | ||||
|     }) | ||||
|     // const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 200) | ||||
|     assert.strictEqual(response.statusCode, 200) | ||||
|   }) | ||||
| }) | ||||
|   | ||||
| @@ -1,10 +1,10 @@ | ||||
| import { Static, Type } from '@sinclair/typebox' | ||||
| import { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import prisma from 'tools/database/prisma.js' | ||||
| import { fastifyErrors } from 'models/utils.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| {{#if shouldBeAuthenticated}} | ||||
| import authenticateUser from 'tools/plugins/authenticateUser.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
| {{/if}} | ||||
|  | ||||
| const body{{sentenceCase httpMethod}}ServiceSchema = Type.Object({ | ||||
|   | ||||
							
								
								
									
										5782
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										5782
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										60
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										60
									
								
								package.json
									
									
									
									
									
								
							| @@ -27,10 +27,10 @@ | ||||
|     "lint:commit": "commitlint", | ||||
|     "lint:editorconfig": "editorconfig-checker", | ||||
|     "lint:markdown": "markdownlint-cli2", | ||||
|     "lint:eslint": "eslint . --ignore-path .gitignore", | ||||
|     "lint:prettier": "prettier . --check --ignore-path .gitignore", | ||||
|     "lint:eslint": "eslint . --max-warnings 0 --report-unused-disable-directives --ignore-path .gitignore", | ||||
|     "lint:prettier": "prettier . --check", | ||||
|     "lint:staged": "lint-staged", | ||||
|     "test": "cross-env NODE_ENV=test c8 tap", | ||||
|     "test": "cross-env NODE_ENV=test node --enable-source-maps --test build/", | ||||
|     "prisma:validate": "prisma validate", | ||||
|     "prisma:generate": "prisma generate", | ||||
|     "prisma:studio": "prisma studio --browser=none", | ||||
| @@ -42,35 +42,35 @@ | ||||
|   "dependencies": { | ||||
|     "@fastify/cors": "8.3.0", | ||||
|     "@fastify/helmet": "11.0.0", | ||||
|     "@fastify/multipart": "7.7.0", | ||||
|     "@fastify/rate-limit": "8.0.1", | ||||
|     "@fastify/multipart": "7.6.0", | ||||
|     "@fastify/rate-limit": "8.0.3", | ||||
|     "@fastify/sensible": "5.2.0", | ||||
|     "@fastify/swagger": "8.6.0", | ||||
|     "@fastify/swagger": "8.8.0", | ||||
|     "@fastify/swagger-ui": "1.9.2", | ||||
|     "@prisma/client": "4.16.2", | ||||
|     "@sinclair/typebox": "0.29.0", | ||||
|     "@thream/socketio-jwt": "3.1.1", | ||||
|     "@prisma/client": "5.0.0", | ||||
|     "@sinclair/typebox": "0.29.6", | ||||
|     "@thream/socketio-jwt": "3.1.2", | ||||
|     "axios": "1.4.0", | ||||
|     "bcryptjs": "2.4.3", | ||||
|     "dotenv": "16.3.1", | ||||
|     "ejs": "3.1.9", | ||||
|     "fastify": "4.19.1", | ||||
|     "fastify-plugin": "4.5.0", | ||||
|     "fastify": "4.20.0", | ||||
|     "fastify-plugin": "4.5.1", | ||||
|     "form-data": "4.0.0", | ||||
|     "http-errors": "2.0.0", | ||||
|     "jsonwebtoken": "9.0.0", | ||||
|     "jsonwebtoken": "9.0.1", | ||||
|     "ms": "2.1.3", | ||||
|     "nodemailer": "6.9.3", | ||||
|     "nodemailer": "6.9.4", | ||||
|     "read-pkg": "8.0.0", | ||||
|     "socket.io": "4.7.1" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@commitlint/cli": "17.6.6", | ||||
|     "@commitlint/config-conventional": "17.6.6", | ||||
|     "@commitlint/cli": "17.6.7", | ||||
|     "@commitlint/config-conventional": "17.6.7", | ||||
|     "@saithodev/semantic-release-backmerge": "3.2.0", | ||||
|     "@semantic-release/git": "10.0.1", | ||||
|     "@swc/cli": "0.1.62", | ||||
|     "@swc/core": "1.3.67", | ||||
|     "@swc/core": "1.3.70", | ||||
|     "@tsconfig/strictest": "2.0.1", | ||||
|     "@types/bcryptjs": "2.4.2", | ||||
|     "@types/busboy": "1.5.0", | ||||
| @@ -78,35 +78,33 @@ | ||||
|     "@types/http-errors": "2.0.1", | ||||
|     "@types/jsonwebtoken": "9.0.2", | ||||
|     "@types/ms": "0.7.31", | ||||
|     "@types/node": "20.3.3", | ||||
|     "@types/node": "20.4.3", | ||||
|     "@types/nodemailer": "6.4.8", | ||||
|     "@types/sinon": "10.0.15", | ||||
|     "@types/tap": "15.0.8", | ||||
|     "@typescript-eslint/eslint-plugin": "5.60.1", | ||||
|     "@typescript-eslint/parser": "5.60.1", | ||||
|     "c8": "8.0.0", | ||||
|     "@typescript-eslint/eslint-plugin": "6.1.0", | ||||
|     "@typescript-eslint/parser": "6.1.0", | ||||
|     "chokidar": "3.5.3", | ||||
|     "concurrently": "8.2.0", | ||||
|     "cross-env": "7.0.3", | ||||
|     "editorconfig-checker": "5.1.1", | ||||
|     "eslint": "8.44.0", | ||||
|     "eslint-config-conventions": "10.0.0", | ||||
|     "eslint": "8.45.0", | ||||
|     "eslint-config-conventions": "11.0.1", | ||||
|     "eslint-config-prettier": "8.8.0", | ||||
|     "eslint-plugin-import": "2.27.5", | ||||
|     "eslint-plugin-prettier": "4.2.1", | ||||
|     "eslint-plugin-prettier": "5.0.0", | ||||
|     "eslint-plugin-promise": "6.1.1", | ||||
|     "eslint-plugin-unicorn": "47.0.0", | ||||
|     "eslint-plugin-unicorn": "48.0.0", | ||||
|     "husky": "8.0.3", | ||||
|     "lint-staged": "13.2.3", | ||||
|     "maildev": "2.0.5", | ||||
|     "maildev": "2.1.0", | ||||
|     "markdownlint-cli2": "0.8.1", | ||||
|     "markdownlint-rule-relative-links": "2.1.0", | ||||
|     "plop": "3.1.2", | ||||
|     "prettier": "2.8.8", | ||||
|     "prisma": "4.16.2", | ||||
|     "prettier": "3.0.0", | ||||
|     "prisma": "5.0.0", | ||||
|     "rimraf": "5.0.1", | ||||
|     "semantic-release": "21.0.6", | ||||
|     "semantic-release": "21.0.7", | ||||
|     "sinon": "15.2.0", | ||||
|     "tap": "16.3.7", | ||||
|     "typescript": "5.0.4" | ||||
|     "typescript": "5.1.6" | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1,45 +1,46 @@ | ||||
| import type { User } from '@prisma/client' | ||||
| import sinon from 'sinon' | ||||
|  | ||||
| import { refreshTokenExample } from '../../models/RefreshToken.js' | ||||
| import type { UserJWT } from '../../models/User.js' | ||||
| import { userExample } from '../../models/User.js' | ||||
| import { userSettingsExample } from '../../models/UserSettings.js' | ||||
| import { refreshTokenExample } from '#src/models/RefreshToken.js' | ||||
| import type { UserJWT } from '#src/models/User.js' | ||||
| import { userExample } from '#src/models/User.js' | ||||
| import { userSettingsExample } from '#src/models/UserSettings.js' | ||||
| import { | ||||
|   generateAccessToken, | ||||
|   generateRefreshToken | ||||
| } from '../../tools/utils/jwtToken.js' | ||||
| import prisma from '../../tools/database/prisma.js' | ||||
| } from '#src/tools/utils/jwtToken.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
|  | ||||
| const userStubValue = { | ||||
|   findUnique: async () => { | ||||
|     return userExample | ||||
|   } | ||||
| } | ||||
| const userSettingStubValue = { | ||||
|   findFirst: async () => { | ||||
|     return userSettingsExample | ||||
|   } | ||||
| } | ||||
| const oAuthStubValue = { | ||||
|   findMany: async () => { | ||||
|     return [] | ||||
|   } | ||||
| } | ||||
| const refreshTokenStubValue = { | ||||
|   create: async () => { | ||||
|     return refreshTokenExample | ||||
|   } | ||||
| } | ||||
|  | ||||
| export const authenticateUserTest = async (): Promise<{ | ||||
|   accessToken: string | ||||
|   refreshToken: string | ||||
|   user: User | ||||
|   userStubValue: any | ||||
|   userSettingStubValue: any | ||||
|   oAuthStubValue: any | ||||
|   refreshTokenStubValue: any | ||||
|   userStubValue: typeof userStubValue | ||||
|   userSettingStubValue: typeof userSettingStubValue | ||||
|   oAuthStubValue: typeof oAuthStubValue | ||||
|   refreshTokenStubValue: typeof refreshTokenStubValue | ||||
| }> => { | ||||
|   const userStubValue = { | ||||
|     findUnique: async () => { | ||||
|       return userExample | ||||
|     } | ||||
|   } | ||||
|   const userSettingStubValue = { | ||||
|     findFirst: async () => { | ||||
|       return userSettingsExample | ||||
|     } | ||||
|   } | ||||
|   const oAuthStubValue = { | ||||
|     findMany: async () => { | ||||
|       return [] | ||||
|     } | ||||
|   } | ||||
|   const refreshTokenStubValue = { | ||||
|     create: async () => { | ||||
|       return refreshTokenExample | ||||
|     } | ||||
|   } | ||||
|   sinon.stub(prisma, 'user').value(userStubValue) | ||||
|   sinon.stub(prisma, 'userSetting').value(userSettingStubValue) | ||||
|   sinon.stub(prisma, 'oAuth').value(oAuthStubValue) | ||||
|   | ||||
| @@ -8,8 +8,8 @@ import fastifyRateLimit from '@fastify/rate-limit' | ||||
| import fastifySensible from '@fastify/sensible' | ||||
| import { readPackage } from 'read-pkg' | ||||
|  | ||||
| import { services } from './services/index.js' | ||||
| import fastifySocketIo from './tools/plugins/socket-io.js' | ||||
| import { services } from '#src/services/index.js' | ||||
| import fastifySocketIo from '#src/tools/plugins/socket-io.js' | ||||
|  | ||||
| dotenv.config() | ||||
| const packageJSON = await readPackage() | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| import { application } from './application.js' | ||||
| import { application } from '#src/application.js' | ||||
| import { HOST, PORT } from '#src/tools/configurations.js' | ||||
|  | ||||
| const address = await application.listen({ | ||||
|   port: PORT, | ||||
|   host: HOST | ||||
| }) | ||||
| console.log('\u001B[36m%s\u001B[0m', `🚀  Server listening at ${address}`) | ||||
| console.log(`Server listening at ${address}`) | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { Channel } from '@prisma/client' | ||||
|  | ||||
| import { date, id } from './utils.js' | ||||
| import { guildExample } from './Guild.js' | ||||
| import { date, id } from '#src/models/utils.js' | ||||
| import { guildExample } from '#src/models/Guild.js' | ||||
|  | ||||
| export const types = [Type.Literal('text')] | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| import type { Guild } from '@prisma/client' | ||||
| import { Type } from '@sinclair/typebox' | ||||
|  | ||||
| import { date, id } from './utils.js' | ||||
| import { date, id } from '#src/models/utils.js' | ||||
|  | ||||
| export const guildSchema = { | ||||
|   id, | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { Member } from '@prisma/client' | ||||
|  | ||||
| import { date, id } from './utils.js' | ||||
| import { guildExample } from './Guild.js' | ||||
| import { userExample } from './User.js' | ||||
| import { date, id } from '#src/models/utils.js' | ||||
| import { guildExample } from '#src/models/Guild.js' | ||||
| import { userExample } from '#src/models/User.js' | ||||
|  | ||||
| export const memberSchema = { | ||||
|   id, | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| import type { Message } from '@prisma/client' | ||||
| import { Type } from '@sinclair/typebox' | ||||
|  | ||||
| import { date, id } from './utils.js' | ||||
| import { date, id } from '#src/models/utils.js' | ||||
|  | ||||
| export const types = [Type.Literal('text'), Type.Literal('file')] | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| import { Type } from '@sinclair/typebox' | ||||
|  | ||||
| import { date, id } from './utils.js' | ||||
| import { date, id } from '#src/models/utils.js' | ||||
|  | ||||
| export const providers = ['Google', 'GitHub', 'Discord'] as const | ||||
| export const strategies = [...providers, 'Local'] as const | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| import type { RefreshToken } from '@prisma/client' | ||||
| import { Type } from '@sinclair/typebox' | ||||
|  | ||||
| import { userExample } from './User.js' | ||||
| import { date, id } from './utils.js' | ||||
| import { userExample } from '#src/models/User.js' | ||||
| import { date, id } from '#src/models/utils.js' | ||||
|  | ||||
| export const refreshTokensSchema = { | ||||
|   id, | ||||
|   | ||||
| @@ -2,10 +2,10 @@ import type { User } from '@prisma/client' | ||||
| import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
|  | ||||
| import type { AuthenticationStrategy } from './OAuth.js' | ||||
| import { strategiesTypebox } from './OAuth.js' | ||||
| import { userSettingsSchema } from './UserSettings.js' | ||||
| import { date, id } from './utils.js' | ||||
| import type { AuthenticationStrategy } from '#src/models/OAuth.js' | ||||
| import { strategiesTypebox } from '#src/models/OAuth.js' | ||||
| import { userSettingsSchema } from '#src/models/UserSettings.js' | ||||
| import { date, id } from '#src/models/utils.js' | ||||
|  | ||||
| export interface UserJWT { | ||||
|   id: number | ||||
|   | ||||
| @@ -2,7 +2,7 @@ import type { UserSetting } from '@prisma/client' | ||||
| import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
|  | ||||
| import { date, id } from './utils.js' | ||||
| import { date, id } from '#src/models/utils.js' | ||||
|  | ||||
| export const languages = [Type.Literal('fr'), Type.Literal('en')] | ||||
| export const themes = [Type.Literal('light'), Type.Literal('dark')] | ||||
|   | ||||
| @@ -1,18 +1,20 @@ | ||||
| import tap from 'tap' | ||||
| import test from 'node:test' | ||||
| import assert from 'node:assert/strict' | ||||
|  | ||||
| import sinon from 'sinon' | ||||
|  | ||||
| import { application } from '../../../../application.js' | ||||
| import { authenticateUserTest } from '../../../../__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '../../../../tools/database/prisma.js' | ||||
| import { channelExample } from '../../../../models/Channel.js' | ||||
| import { memberExample } from '../../../../models/Member.js' | ||||
| import { application } from '#src/application.js' | ||||
| import { authenticateUserTest } from '#src/__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { channelExample } from '#src/models/Channel.js' | ||||
| import { memberExample } from '#src/models/Member.js' | ||||
|  | ||||
| await tap.test('DELETE /channels/[channelId]', async (t) => { | ||||
| await test('DELETE /channels/[channelId]', async (t) => { | ||||
|   t.afterEach(() => { | ||||
|     sinon.restore() | ||||
|   }) | ||||
|  | ||||
|   await t.test('succeeds', async (t) => { | ||||
|   await t.test('succeeds', async () => { | ||||
|     const defaultChannelId = 5 | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'channel').value({ | ||||
| @@ -45,14 +47,14 @@ await tap.test('DELETE /channels/[channelId]', async (t) => { | ||||
|       } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 200) | ||||
|     t.equal(responseJson.id, channelExample.id) | ||||
|     t.equal(responseJson.name, channelExample.name) | ||||
|     t.equal(responseJson.guildId, channelExample.guildId) | ||||
|     t.equal(responseJson.defaultChannelId, defaultChannelId) | ||||
|     assert.strictEqual(response.statusCode, 200) | ||||
|     assert.strictEqual(responseJson.id, channelExample.id) | ||||
|     assert.strictEqual(responseJson.name, channelExample.name) | ||||
|     assert.strictEqual(responseJson.guildId, channelExample.guildId) | ||||
|     assert.strictEqual(responseJson.defaultChannelId, defaultChannelId) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails if there is only one channel', async (t) => { | ||||
|   await t.test('fails if there is only one channel', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'channel').value({ | ||||
|       findUnique: async () => { | ||||
| @@ -74,10 +76,10 @@ await tap.test('DELETE /channels/[channelId]', async (t) => { | ||||
|         authorization: `Bearer ${accessToken}` | ||||
|       } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 400) | ||||
|     assert.strictEqual(response.statusCode, 400) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails if the channel is not found', async (t) => { | ||||
|   await t.test('fails if the channel is not found', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'channel').value({ | ||||
|       findUnique: async () => { | ||||
| @@ -91,10 +93,10 @@ await tap.test('DELETE /channels/[channelId]', async (t) => { | ||||
|         authorization: `Bearer ${accessToken}` | ||||
|       } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 404) | ||||
|     assert.strictEqual(response.statusCode, 404) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails if the member is not found', async (t) => { | ||||
|   await t.test('fails if the member is not found', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'channel').value({ | ||||
|       findUnique: async () => { | ||||
| @@ -113,10 +115,10 @@ await tap.test('DELETE /channels/[channelId]', async (t) => { | ||||
|         authorization: `Bearer ${accessToken}` | ||||
|       } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 404) | ||||
|     assert.strictEqual(response.statusCode, 404) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails if the member is not owner', async (t) => { | ||||
|   await t.test('fails if the member is not owner', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'channel').value({ | ||||
|       findUnique: async () => { | ||||
| @@ -138,6 +140,6 @@ await tap.test('DELETE /channels/[channelId]', async (t) => { | ||||
|         authorization: `Bearer ${accessToken}` | ||||
|       } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 400) | ||||
|     assert.strictEqual(response.statusCode, 400) | ||||
|   }) | ||||
| }) | ||||
|   | ||||
| @@ -1,18 +1,20 @@ | ||||
| import tap from 'tap' | ||||
| import test from 'node:test' | ||||
| import assert from 'node:assert/strict' | ||||
|  | ||||
| import sinon from 'sinon' | ||||
|  | ||||
| import { application } from '../../../../application.js' | ||||
| import { authenticateUserTest } from '../../../../__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '../../../../tools/database/prisma.js' | ||||
| import { channelExample } from '../../../../models/Channel.js' | ||||
| import { memberExample } from '../../../../models/Member.js' | ||||
| import { application } from '#src/application.js' | ||||
| import { authenticateUserTest } from '#src/__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { channelExample } from '#src/models/Channel.js' | ||||
| import { memberExample } from '#src/models/Member.js' | ||||
|  | ||||
| await tap.test('GET /channels/[channelId]', async (t) => { | ||||
| await test('GET /channels/[channelId]', async (t) => { | ||||
|   t.afterEach(() => { | ||||
|     sinon.restore() | ||||
|   }) | ||||
|  | ||||
|   await t.test('succeeds', async (t) => { | ||||
|   await t.test('succeeds', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'channel').value({ | ||||
|       findUnique: async () => { | ||||
| @@ -32,13 +34,13 @@ await tap.test('GET /channels/[channelId]', async (t) => { | ||||
|       } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 200) | ||||
|     t.equal(responseJson.channel.id, channelExample.id) | ||||
|     t.equal(responseJson.channel.name, channelExample.name) | ||||
|     t.equal(responseJson.channel.guildId, channelExample.guildId) | ||||
|     assert.strictEqual(response.statusCode, 200) | ||||
|     assert.strictEqual(responseJson.channel.id, channelExample.id) | ||||
|     assert.strictEqual(responseJson.channel.name, channelExample.name) | ||||
|     assert.strictEqual(responseJson.channel.guildId, channelExample.guildId) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails with not found member', async (t) => { | ||||
|   await t.test('fails with not found member', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'channel').value({ | ||||
|       findUnique: async () => { | ||||
| @@ -58,11 +60,11 @@ await tap.test('GET /channels/[channelId]', async (t) => { | ||||
|       } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 404) | ||||
|     t.equal(responseJson.message, 'Channel not found') | ||||
|     assert.strictEqual(response.statusCode, 404) | ||||
|     assert.strictEqual(responseJson.message, 'Channel not found') | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails with not found channel', async (t) => { | ||||
|   await t.test('fails with not found channel', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'channel').value({ | ||||
|       findUnique: async () => { | ||||
| @@ -82,15 +84,15 @@ await tap.test('GET /channels/[channelId]', async (t) => { | ||||
|       } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 404) | ||||
|     t.equal(responseJson.message, 'Channel not found') | ||||
|     assert.strictEqual(response.statusCode, 404) | ||||
|     assert.strictEqual(responseJson.message, 'Channel not found') | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails with unauthenticated user', async (t) => { | ||||
|   await t.test('fails with unauthenticated user', async () => { | ||||
|     const response = await application.inject({ | ||||
|       method: 'GET', | ||||
|       url: '/channels/1' | ||||
|     }) | ||||
|     t.equal(response.statusCode, 401) | ||||
|     assert.strictEqual(response.statusCode, 401) | ||||
|   }) | ||||
| }) | ||||
|   | ||||
| @@ -1,20 +1,22 @@ | ||||
| import tap from 'tap' | ||||
| import test from 'node:test' | ||||
| import assert from 'node:assert/strict' | ||||
|  | ||||
| import sinon from 'sinon' | ||||
|  | ||||
| import { application } from '../../../../application.js' | ||||
| import { authenticateUserTest } from '../../../../__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '../../../../tools/database/prisma.js' | ||||
| import { channelExample } from '../../../../models/Channel.js' | ||||
| import { memberExample } from '../../../../models/Member.js' | ||||
| import { application } from '#src/application.js' | ||||
| import { authenticateUserTest } from '#src/__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { channelExample } from '#src/models/Channel.js' | ||||
| import { memberExample } from '#src/models/Member.js' | ||||
|  | ||||
| const newName = 'new channel name' | ||||
|  | ||||
| await tap.test('PUT /channels/[channelId]', async (t) => { | ||||
| await test('PUT /channels/[channelId]', async (t) => { | ||||
|   t.afterEach(() => { | ||||
|     sinon.restore() | ||||
|   }) | ||||
|  | ||||
|   await t.test('succeeds', async (t) => { | ||||
|   await t.test('succeeds', async () => { | ||||
|     const defaultChannelId = 5 | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'channel').value({ | ||||
| @@ -48,14 +50,14 @@ await tap.test('PUT /channels/[channelId]', async (t) => { | ||||
|       payload: { name: newName } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 200) | ||||
|     t.equal(responseJson.id, channelExample.id) | ||||
|     t.equal(responseJson.name, newName) | ||||
|     t.equal(responseJson.guildId, channelExample.guildId) | ||||
|     t.equal(responseJson.defaultChannelId, defaultChannelId) | ||||
|     assert.strictEqual(response.statusCode, 200) | ||||
|     assert.strictEqual(responseJson.id, channelExample.id) | ||||
|     assert.strictEqual(responseJson.name, newName) | ||||
|     assert.strictEqual(responseJson.guildId, channelExample.guildId) | ||||
|     assert.strictEqual(responseJson.defaultChannelId, defaultChannelId) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails if the channel is not found', async (t) => { | ||||
|   await t.test('fails if the channel is not found', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'channel').value({ | ||||
|       findUnique: async () => { | ||||
| @@ -75,10 +77,10 @@ await tap.test('PUT /channels/[channelId]', async (t) => { | ||||
|       }, | ||||
|       payload: { name: newName } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 404) | ||||
|     assert.strictEqual(response.statusCode, 404) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails if the member is not found', async (t) => { | ||||
|   await t.test('fails if the member is not found', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'channel').value({ | ||||
|       findUnique: async () => { | ||||
| @@ -98,10 +100,10 @@ await tap.test('PUT /channels/[channelId]', async (t) => { | ||||
|       }, | ||||
|       payload: { name: newName } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 404) | ||||
|     assert.strictEqual(response.statusCode, 404) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails if the member is not owner', async (t) => { | ||||
|   await t.test('fails if the member is not owner', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'channel').value({ | ||||
|       findUnique: async () => { | ||||
| @@ -124,6 +126,6 @@ await tap.test('PUT /channels/[channelId]', async (t) => { | ||||
|       }, | ||||
|       payload: { name: newName } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 400) | ||||
|     assert.strictEqual(response.statusCode, 400) | ||||
|   }) | ||||
| }) | ||||
|   | ||||
| @@ -2,10 +2,10 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import prisma from '../../../tools/database/prisma.js' | ||||
| import { fastifyErrors } from '../../../models/utils.js' | ||||
| import authenticateUser from '../../../tools/plugins/authenticateUser.js' | ||||
| import { channelSchema } from '../../../models/Channel.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
| import { channelSchema } from '#src/models/Channel.js' | ||||
|  | ||||
| const parametersSchema = Type.Object({ | ||||
|   channelId: channelSchema.id | ||||
| @@ -48,8 +48,8 @@ export const deleteChannelService: FastifyPluginAsync = async (fastify) => { | ||||
|       if (request.user == null) { | ||||
|         throw fastify.httpErrors.forbidden() | ||||
|       } | ||||
|       const { user } = request | ||||
|       const { channelId } = request.params | ||||
|       const { user, params } = request | ||||
|       const { channelId } = params | ||||
|       const channelCheck = await prisma.channel.findUnique({ | ||||
|         where: { id: channelId } | ||||
|       }) | ||||
|   | ||||
| @@ -2,10 +2,10 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import prisma from '../../../tools/database/prisma.js' | ||||
| import { fastifyErrors } from '../../../models/utils.js' | ||||
| import authenticateUser from '../../../tools/plugins/authenticateUser.js' | ||||
| import { channelSchema } from '../../../models/Channel.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
| import { channelSchema } from '#src/models/Channel.js' | ||||
|  | ||||
| const parametersSchema = Type.Object({ | ||||
|   channelId: channelSchema.id | ||||
|   | ||||
| @@ -1,20 +1,22 @@ | ||||
| import tap from 'tap' | ||||
| import test from 'node:test' | ||||
| import assert from 'node:assert/strict' | ||||
|  | ||||
| import sinon from 'sinon' | ||||
|  | ||||
| import { application } from '../../../../../application.js' | ||||
| import { authenticateUserTest } from '../../../../../__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '../../../../../tools/database/prisma.js' | ||||
| import { channelExample } from '../../../../../models/Channel.js' | ||||
| import { memberExample } from '../../../../../models/Member.js' | ||||
| import { userExample } from '../../../../../models/User.js' | ||||
| import { messageExample } from '../../../../../models/Message.js' | ||||
| import { application } from '#src/application.js' | ||||
| import { authenticateUserTest } from '#src/__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { channelExample } from '#src/models/Channel.js' | ||||
| import { memberExample } from '#src/models/Member.js' | ||||
| import { userExample } from '#src/models/User.js' | ||||
| import { messageExample } from '#src/models/Message.js' | ||||
|  | ||||
| await tap.test('GET /channels/[channelId]/messages', async (t) => { | ||||
| await test('GET /channels/[channelId]/messages', async (t) => { | ||||
|   t.afterEach(() => { | ||||
|     sinon.restore() | ||||
|   }) | ||||
|  | ||||
|   await t.test('succeeds', async (t) => { | ||||
|   await t.test('succeeds', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'channel').value({ | ||||
|       findUnique: async () => { | ||||
| @@ -42,19 +44,19 @@ await tap.test('GET /channels/[channelId]/messages', async (t) => { | ||||
|       } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 200) | ||||
|     t.equal(responseJson.length, 1) | ||||
|     t.equal(responseJson[0].id, messageExample.id) | ||||
|     t.equal(responseJson[0].value, messageExample.value) | ||||
|     t.equal(responseJson[0].type, messageExample.type) | ||||
|     t.equal(responseJson[0].mimetype, messageExample.mimetype) | ||||
|     t.equal(responseJson[0].member.id, memberExample.id) | ||||
|     t.equal(responseJson[0].member.isOwner, memberExample.isOwner) | ||||
|     t.equal(responseJson[0].member.user.id, userExample.id) | ||||
|     t.equal(responseJson[0].member.user.name, userExample.name) | ||||
|     assert.strictEqual(response.statusCode, 200) | ||||
|     assert.strictEqual(responseJson.length, 1) | ||||
|     assert.strictEqual(responseJson[0].id, messageExample.id) | ||||
|     assert.strictEqual(responseJson[0].value, messageExample.value) | ||||
|     assert.strictEqual(responseJson[0].type, messageExample.type) | ||||
|     assert.strictEqual(responseJson[0].mimetype, messageExample.mimetype) | ||||
|     assert.strictEqual(responseJson[0].member.id, memberExample.id) | ||||
|     assert.strictEqual(responseJson[0].member.isOwner, memberExample.isOwner) | ||||
|     assert.strictEqual(responseJson[0].member.user.id, userExample.id) | ||||
|     assert.strictEqual(responseJson[0].member.user.name, userExample.name) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails with not found channel', async (t) => { | ||||
|   await t.test('fails with not found channel', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'channel').value({ | ||||
|       findUnique: async () => { | ||||
| @@ -77,11 +79,11 @@ await tap.test('GET /channels/[channelId]/messages', async (t) => { | ||||
|       } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 404) | ||||
|     t.equal(responseJson.message, 'Channel not found') | ||||
|     assert.strictEqual(response.statusCode, 404) | ||||
|     assert.strictEqual(responseJson.message, 'Channel not found') | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails with not found member', async (t) => { | ||||
|   await t.test('fails with not found member', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'channel').value({ | ||||
|       findUnique: async () => { | ||||
| @@ -101,15 +103,15 @@ await tap.test('GET /channels/[channelId]/messages', async (t) => { | ||||
|       } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 404) | ||||
|     t.equal(responseJson.message, 'Channel not found') | ||||
|     assert.strictEqual(response.statusCode, 404) | ||||
|     assert.strictEqual(responseJson.message, 'Channel not found') | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails with unauthenticated user', async (t) => { | ||||
|   await t.test('fails with unauthenticated user', async () => { | ||||
|     const response = await application.inject({ | ||||
|       method: 'GET', | ||||
|       url: `/channels/1/messages` | ||||
|     }) | ||||
|     t.equal(response.statusCode, 401) | ||||
|     assert.strictEqual(response.statusCode, 401) | ||||
|   }) | ||||
| }) | ||||
|   | ||||
| @@ -1,20 +1,22 @@ | ||||
| import tap from 'tap' | ||||
| import test from 'node:test' | ||||
| import assert from 'node:assert/strict' | ||||
|  | ||||
| import sinon from 'sinon' | ||||
|  | ||||
| import { application } from '../../../../../application.js' | ||||
| import { authenticateUserTest } from '../../../../../__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '../../../../../tools/database/prisma.js' | ||||
| import { channelExample } from '../../../../../models/Channel.js' | ||||
| import { memberExample } from '../../../../../models/Member.js' | ||||
| import { userExample } from '../../../../../models/User.js' | ||||
| import { messageExample } from '../../../../../models/Message.js' | ||||
| import { application } from '#src/application.js' | ||||
| import { authenticateUserTest } from '#src/__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { channelExample } from '#src/models/Channel.js' | ||||
| import { memberExample } from '#src/models/Member.js' | ||||
| import { userExample } from '#src/models/User.js' | ||||
| import { messageExample } from '#src/models/Message.js' | ||||
|  | ||||
| await tap.test('POST /channels/[channelId]/messages', async (t) => { | ||||
| await test('POST /channels/[channelId]/messages', async (t) => { | ||||
|   t.afterEach(() => { | ||||
|     sinon.restore() | ||||
|   }) | ||||
|  | ||||
|   await t.test('succeeds', async (t) => { | ||||
|   await t.test('succeeds', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'channel').value({ | ||||
|       findUnique: async () => { | ||||
| @@ -43,18 +45,18 @@ await tap.test('POST /channels/[channelId]/messages', async (t) => { | ||||
|       payload: { value: messageExample.value } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 201) | ||||
|     t.equal(responseJson.id, messageExample.id) | ||||
|     t.equal(responseJson.value, messageExample.value) | ||||
|     t.equal(responseJson.type, messageExample.type) | ||||
|     t.equal(responseJson.mimetype, messageExample.mimetype) | ||||
|     t.equal(responseJson.member.id, memberExample.id) | ||||
|     t.equal(responseJson.member.isOwner, memberExample.isOwner) | ||||
|     t.equal(responseJson.member.user.id, userExample.id) | ||||
|     t.equal(responseJson.member.user.name, userExample.name) | ||||
|     assert.strictEqual(response.statusCode, 201) | ||||
|     assert.strictEqual(responseJson.id, messageExample.id) | ||||
|     assert.strictEqual(responseJson.value, messageExample.value) | ||||
|     assert.strictEqual(responseJson.type, messageExample.type) | ||||
|     assert.strictEqual(responseJson.mimetype, messageExample.mimetype) | ||||
|     assert.strictEqual(responseJson.member.id, memberExample.id) | ||||
|     assert.strictEqual(responseJson.member.isOwner, memberExample.isOwner) | ||||
|     assert.strictEqual(responseJson.member.user.id, userExample.id) | ||||
|     assert.strictEqual(responseJson.member.user.name, userExample.name) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails with no message value', async (t) => { | ||||
|   await t.test('fails with no message value', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'channel').value({ | ||||
|       findUnique: async () => { | ||||
| @@ -77,10 +79,10 @@ await tap.test('POST /channels/[channelId]/messages', async (t) => { | ||||
|       }, | ||||
|       payload: {} | ||||
|     }) | ||||
|     t.equal(response.statusCode, 400) | ||||
|     assert.strictEqual(response.statusCode, 400) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails with not found channel', async (t) => { | ||||
|   await t.test('fails with not found channel', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'channel').value({ | ||||
|       findUnique: async () => { | ||||
| @@ -104,11 +106,11 @@ await tap.test('POST /channels/[channelId]/messages', async (t) => { | ||||
|       payload: { value: messageExample.value } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 404) | ||||
|     t.equal(responseJson.message, 'Channel not found') | ||||
|     assert.strictEqual(response.statusCode, 404) | ||||
|     assert.strictEqual(responseJson.message, 'Channel not found') | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails with not found member', async (t) => { | ||||
|   await t.test('fails with not found member', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'channel').value({ | ||||
|       findUnique: async () => { | ||||
| @@ -129,7 +131,7 @@ await tap.test('POST /channels/[channelId]/messages', async (t) => { | ||||
|       payload: { value: messageExample.value } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 404) | ||||
|     t.equal(responseJson.message, 'Channel not found') | ||||
|     assert.strictEqual(response.statusCode, 404) | ||||
|     assert.strictEqual(responseJson.message, 'Channel not found') | ||||
|   }) | ||||
| }) | ||||
|   | ||||
| @@ -2,17 +2,17 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import prisma from '../../../../tools/database/prisma.js' | ||||
| import { fastifyErrors } from '../../../../models/utils.js' | ||||
| import authenticateUser from '../../../../tools/plugins/authenticateUser.js' | ||||
| import { messageSchema } from '../../../../models/Message.js' | ||||
| import { memberSchema } from '../../../../models/Member.js' | ||||
| import { userPublicWithoutSettingsSchema } from '../../../../models/User.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
| import { messageSchema } from '#src/models/Message.js' | ||||
| import { memberSchema } from '#src/models/Member.js' | ||||
| import { userPublicWithoutSettingsSchema } from '#src/models/User.js' | ||||
| import { | ||||
|   getPaginationOptions, | ||||
|   queryPaginationObjectSchema | ||||
| } from '../../../../tools/database/pagination.js' | ||||
| import { channelSchema } from '../../../../models/Channel.js' | ||||
| } from '#src/tools/database/pagination.js' | ||||
| import { channelSchema } from '#src/models/Channel.js' | ||||
|  | ||||
| type QuerySchemaType = Static<typeof queryPaginationObjectSchema> | ||||
|  | ||||
|   | ||||
| @@ -2,13 +2,13 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import prisma from '../../../../tools/database/prisma.js' | ||||
| import { fastifyErrors } from '../../../../models/utils.js' | ||||
| import authenticateUser from '../../../../tools/plugins/authenticateUser.js' | ||||
| import { messageSchema } from '../../../../models/Message.js' | ||||
| import { channelSchema } from '../../../../models/Channel.js' | ||||
| import { memberSchema } from '../../../../models/Member.js' | ||||
| import { userPublicWithoutSettingsSchema } from '../../../../models/User.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
| import { messageSchema } from '#src/models/Message.js' | ||||
| import { channelSchema } from '#src/models/Channel.js' | ||||
| import { memberSchema } from '#src/models/Member.js' | ||||
| import { userPublicWithoutSettingsSchema } from '#src/models/User.js' | ||||
|  | ||||
| const parametersSchema = Type.Object({ | ||||
|   channelId: channelSchema.id | ||||
|   | ||||
| @@ -3,14 +3,14 @@ import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
| import fastifyMultipart from '@fastify/multipart' | ||||
|  | ||||
| import prisma from '../../../../../tools/database/prisma.js' | ||||
| import { fastifyErrors } from '../../../../../models/utils.js' | ||||
| import authenticateUser from '../../../../../tools/plugins/authenticateUser.js' | ||||
| import { messageSchema } from '../../../../../models/Message.js' | ||||
| import { memberSchema } from '../../../../../models/Member.js' | ||||
| import { userPublicWithoutSettingsSchema } from '../../../../../models/User.js' | ||||
| import { channelSchema } from '../../../../../models/Channel.js' | ||||
| import { uploadFile } from '../../../../../tools/utils/uploadFile.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
| import { messageSchema } from '#src/models/Message.js' | ||||
| import { memberSchema } from '#src/models/Member.js' | ||||
| import { userPublicWithoutSettingsSchema } from '#src/models/User.js' | ||||
| import { channelSchema } from '#src/models/Channel.js' | ||||
| import { uploadFile } from '#src/tools/utils/uploadFile.js' | ||||
|  | ||||
| const parametersSchema = Type.Object({ | ||||
|   channelId: channelSchema.id | ||||
|   | ||||
| @@ -2,10 +2,10 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import prisma from '../../../tools/database/prisma.js' | ||||
| import { fastifyErrors } from '../../../models/utils.js' | ||||
| import authenticateUser from '../../../tools/plugins/authenticateUser.js' | ||||
| import { channelSchema } from '../../../models/Channel.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
| import { channelSchema } from '#src/models/Channel.js' | ||||
|  | ||||
| const bodyPutServiceSchema = Type.Object({ | ||||
|   name: channelSchema.name | ||||
| @@ -56,9 +56,9 @@ export const putChannelService: FastifyPluginAsync = async (fastify) => { | ||||
|       if (request.user == null) { | ||||
|         throw fastify.httpErrors.forbidden() | ||||
|       } | ||||
|       const { user } = request | ||||
|       const { channelId } = request.params | ||||
|       const { name } = request.body | ||||
|       const { user, params, body } = request | ||||
|       const { channelId } = params | ||||
|       const { name } = body | ||||
|       const channelCheck = await prisma.channel.findUnique({ | ||||
|         where: { id: channelId } | ||||
|       }) | ||||
|   | ||||
| @@ -1,18 +1,20 @@ | ||||
| import tap from 'tap' | ||||
| import test from 'node:test' | ||||
| import assert from 'node:assert/strict' | ||||
|  | ||||
| import sinon from 'sinon' | ||||
|  | ||||
| import { application } from '../../../../application.js' | ||||
| import { authenticateUserTest } from '../../../../__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '../../../../tools/database/prisma.js' | ||||
| import { memberExample } from '../../../../models/Member.js' | ||||
| import { guildExample } from '../../../../models/Guild.js' | ||||
| import { application } from '#src/application.js' | ||||
| import { authenticateUserTest } from '#src/__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { memberExample } from '#src/models/Member.js' | ||||
| import { guildExample } from '#src/models/Guild.js' | ||||
|  | ||||
| await tap.test('DELETE /guilds/[guildId]', async (t) => { | ||||
| await test('DELETE /guilds/[guildId]', async (t) => { | ||||
|   t.afterEach(() => { | ||||
|     sinon.restore() | ||||
|   }) | ||||
|  | ||||
|   await t.test('succeeds and delete the guild', async (t) => { | ||||
|   await t.test('succeeds and delete the guild', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'member').value({ | ||||
|       findFirst: async () => { | ||||
| @@ -36,13 +38,13 @@ await tap.test('DELETE /guilds/[guildId]', async (t) => { | ||||
|       } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 200) | ||||
|     t.equal(responseJson.id, guildExample.id) | ||||
|     t.equal(responseJson.name, guildExample.name) | ||||
|     t.equal(responseJson.description, guildExample.description) | ||||
|     assert.strictEqual(response.statusCode, 200) | ||||
|     assert.strictEqual(responseJson.id, guildExample.id) | ||||
|     assert.strictEqual(responseJson.name, guildExample.name) | ||||
|     assert.strictEqual(responseJson.description, guildExample.description) | ||||
|   }) | ||||
|  | ||||
|   await t.test("fails if the guild doesn't exist", async (t) => { | ||||
|   await t.test("fails if the guild doesn't exist", async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'member').value({ | ||||
|       findFirst: async () => { | ||||
| @@ -56,10 +58,10 @@ await tap.test('DELETE /guilds/[guildId]', async (t) => { | ||||
|         authorization: `Bearer ${accessToken}` | ||||
|       } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 404) | ||||
|     assert.strictEqual(response.statusCode, 404) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails if the user is not the owner', async (t) => { | ||||
|   await t.test('fails if the user is not the owner', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'member').value({ | ||||
|       findFirst: async () => { | ||||
| @@ -78,7 +80,10 @@ await tap.test('DELETE /guilds/[guildId]', async (t) => { | ||||
|       } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 400) | ||||
|     t.equal(responseJson.message, 'You should be an owner of the guild') | ||||
|     assert.strictEqual(response.statusCode, 400) | ||||
|     assert.strictEqual( | ||||
|       responseJson.message, | ||||
|       'You should be an owner of the guild' | ||||
|     ) | ||||
|   }) | ||||
| }) | ||||
|   | ||||
| @@ -1,22 +1,24 @@ | ||||
| import tap from 'tap' | ||||
| import test from 'node:test' | ||||
| import assert from 'node:assert/strict' | ||||
|  | ||||
| import sinon from 'sinon' | ||||
|  | ||||
| import { application } from '../../../../application.js' | ||||
| import { authenticateUserTest } from '../../../../__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '../../../../tools/database/prisma.js' | ||||
| import { memberExample } from '../../../../models/Member.js' | ||||
| import { guildExample } from '../../../../models/Guild.js' | ||||
| import { userExample } from '../../../../models/User.js' | ||||
| import { channelExample } from '../../../../models/Channel.js' | ||||
| import { application } from '#src/application.js' | ||||
| import { authenticateUserTest } from '#src/__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { memberExample } from '#src/models/Member.js' | ||||
| import { guildExample } from '#src/models/Guild.js' | ||||
| import { userExample } from '#src/models/User.js' | ||||
| import { channelExample } from '#src/models/Channel.js' | ||||
|  | ||||
| const defaultChannelId = 5 | ||||
|  | ||||
| await tap.test('GET /guilds/[guildId]', async (t) => { | ||||
| await test('GET /guilds/[guildId]', async (t) => { | ||||
|   t.afterEach(() => { | ||||
|     sinon.restore() | ||||
|   }) | ||||
|  | ||||
|   await t.test('succeeds', async (t) => { | ||||
|   await t.test('succeeds', async () => { | ||||
|     const { accessToken, user } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'member').value({ | ||||
|       findFirst: async () => { | ||||
| @@ -43,17 +45,17 @@ await tap.test('GET /guilds/[guildId]', async (t) => { | ||||
|       } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 200) | ||||
|     t.equal(responseJson.member.id, memberExample.id) | ||||
|     t.equal(responseJson.member.isOwner, memberExample.isOwner) | ||||
|     t.equal(responseJson.member.user.name, user.name) | ||||
|     t.equal(responseJson.member.user.email, null) | ||||
|     t.equal(responseJson.guild.id, guildExample.id) | ||||
|     t.equal(responseJson.guild.name, guildExample.name) | ||||
|     t.equal(responseJson.guild.defaultChannelId, defaultChannelId) | ||||
|     assert.strictEqual(response.statusCode, 200) | ||||
|     assert.strictEqual(responseJson.member.id, memberExample.id) | ||||
|     assert.strictEqual(responseJson.member.isOwner, memberExample.isOwner) | ||||
|     assert.strictEqual(responseJson.member.user.name, user.name) | ||||
|     assert.strictEqual(responseJson.member.user.email, null) | ||||
|     assert.strictEqual(responseJson.guild.id, guildExample.id) | ||||
|     assert.strictEqual(responseJson.guild.name, guildExample.name) | ||||
|     assert.strictEqual(responseJson.guild.defaultChannelId, defaultChannelId) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails with not found member/guild', async (t) => { | ||||
|   await t.test('fails with not found member/guild', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'member').value({ | ||||
|       findFirst: async () => { | ||||
| @@ -68,15 +70,15 @@ await tap.test('GET /guilds/[guildId]', async (t) => { | ||||
|       } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 404) | ||||
|     t.equal(responseJson.message, 'Member not found') | ||||
|     assert.strictEqual(response.statusCode, 404) | ||||
|     assert.strictEqual(responseJson.message, 'Member not found') | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails with unauthenticated user', async (t) => { | ||||
|   await t.test('fails with unauthenticated user', async () => { | ||||
|     const response = await application.inject({ | ||||
|       method: 'GET', | ||||
|       url: '/guilds/1' | ||||
|     }) | ||||
|     t.equal(response.statusCode, 401) | ||||
|     assert.strictEqual(response.statusCode, 401) | ||||
|   }) | ||||
| }) | ||||
|   | ||||
| @@ -1,23 +1,25 @@ | ||||
| import tap from 'tap' | ||||
| import test from 'node:test' | ||||
| import assert from 'node:assert/strict' | ||||
|  | ||||
| import sinon from 'sinon' | ||||
|  | ||||
| import { application } from '../../../../application.js' | ||||
| import { authenticateUserTest } from '../../../../__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '../../../../tools/database/prisma.js' | ||||
| import { memberExample } from '../../../../models/Member.js' | ||||
| import { guildExample } from '../../../../models/Guild.js' | ||||
| import { channelExample } from '../../../../models/Channel.js' | ||||
| import { application } from '#src/application.js' | ||||
| import { authenticateUserTest } from '#src/__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { memberExample } from '#src/models/Member.js' | ||||
| import { guildExample } from '#src/models/Guild.js' | ||||
| import { channelExample } from '#src/models/Channel.js' | ||||
|  | ||||
| const defaultChannelId = 5 | ||||
| const newName = 'New guild name' | ||||
| const newDescription = 'New guild description' | ||||
|  | ||||
| await tap.test('PUT /guilds/[guildId]', async (t) => { | ||||
| await test('PUT /guilds/[guildId]', async (t) => { | ||||
|   t.afterEach(() => { | ||||
|     sinon.restore() | ||||
|   }) | ||||
|  | ||||
|   await t.test('succeeds and edit the guild', async (t) => { | ||||
|   await t.test('succeeds and edit the guild', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'member').value({ | ||||
|       findFirst: async () => { | ||||
| @@ -57,13 +59,13 @@ await tap.test('PUT /guilds/[guildId]', async (t) => { | ||||
|       } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 200) | ||||
|     t.equal(responseJson.name, newName) | ||||
|     t.equal(responseJson.description, newDescription) | ||||
|     t.equal(responseJson.defaultChannelId, defaultChannelId) | ||||
|     assert.strictEqual(response.statusCode, 200) | ||||
|     assert.strictEqual(responseJson.name, newName) | ||||
|     assert.strictEqual(responseJson.description, newDescription) | ||||
|     assert.strictEqual(responseJson.defaultChannelId, defaultChannelId) | ||||
|   }) | ||||
|  | ||||
|   await t.test("fails if the guild doesn't exist", async (t) => { | ||||
|   await t.test("fails if the guild doesn't exist", async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'member').value({ | ||||
|       findFirst: async () => { | ||||
| @@ -81,10 +83,10 @@ await tap.test('PUT /guilds/[guildId]', async (t) => { | ||||
|         description: newDescription | ||||
|       } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 404) | ||||
|     assert.strictEqual(response.statusCode, 404) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails if the user is not the owner', async (t) => { | ||||
|   await t.test('fails if the user is not the owner', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'member').value({ | ||||
|       findFirst: async () => { | ||||
| @@ -107,7 +109,10 @@ await tap.test('PUT /guilds/[guildId]', async (t) => { | ||||
|       } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 400) | ||||
|     t.equal(responseJson.message, 'You should be an owner of the guild') | ||||
|     assert.strictEqual(response.statusCode, 400) | ||||
|     assert.strictEqual( | ||||
|       responseJson.message, | ||||
|       'You should be an owner of the guild' | ||||
|     ) | ||||
|   }) | ||||
| }) | ||||
|   | ||||
| @@ -1,19 +1,21 @@ | ||||
| import tap from 'tap' | ||||
| import test from 'node:test' | ||||
| import assert from 'node:assert/strict' | ||||
|  | ||||
| import sinon from 'sinon' | ||||
|  | ||||
| import { application } from '../../../../../application.js' | ||||
| import { authenticateUserTest } from '../../../../../__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '../../../../../tools/database/prisma.js' | ||||
| import { memberExample } from '../../../../../models/Member.js' | ||||
| import { guildExample } from '../../../../../models/Guild.js' | ||||
| import { channelExample } from '../../../../../models/Channel.js' | ||||
| import { application } from '#src/application.js' | ||||
| import { authenticateUserTest } from '#src/__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { memberExample } from '#src/models/Member.js' | ||||
| import { guildExample } from '#src/models/Guild.js' | ||||
| import { channelExample } from '#src/models/Channel.js' | ||||
|  | ||||
| await tap.test('GET /guilds/[guildId]/channels', async (t) => { | ||||
| await test('GET /guilds/[guildId]/channels', async (t) => { | ||||
|   t.afterEach(() => { | ||||
|     sinon.restore() | ||||
|   }) | ||||
|  | ||||
|   await t.test('succeeds', async (t) => { | ||||
|   await t.test('succeeds', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'member').value({ | ||||
|       findFirst: async () => { | ||||
| @@ -33,14 +35,14 @@ await tap.test('GET /guilds/[guildId]/channels', async (t) => { | ||||
|       } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 200) | ||||
|     t.equal(responseJson.length, 1) | ||||
|     t.equal(responseJson[0].id, channelExample.id) | ||||
|     t.equal(responseJson[0].name, channelExample.name) | ||||
|     t.equal(responseJson[0].guildId, channelExample.guildId) | ||||
|     assert.strictEqual(response.statusCode, 200) | ||||
|     assert.strictEqual(responseJson.length, 1) | ||||
|     assert.strictEqual(responseJson[0].id, channelExample.id) | ||||
|     assert.strictEqual(responseJson[0].name, channelExample.name) | ||||
|     assert.strictEqual(responseJson[0].guildId, channelExample.guildId) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails with not found member/guild', async (t) => { | ||||
|   await t.test('fails with not found member/guild', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'member').value({ | ||||
|       findFirst: async () => { | ||||
| @@ -55,15 +57,15 @@ await tap.test('GET /guilds/[guildId]/channels', async (t) => { | ||||
|       } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 404) | ||||
|     t.equal(responseJson.message, 'Member not found') | ||||
|     assert.strictEqual(response.statusCode, 404) | ||||
|     assert.strictEqual(responseJson.message, 'Member not found') | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails with unauthenticated user', async (t) => { | ||||
|   await t.test('fails with unauthenticated user', async () => { | ||||
|     const response = await application.inject({ | ||||
|       method: 'GET', | ||||
|       url: '/guilds/1/channels' | ||||
|     }) | ||||
|     t.equal(response.statusCode, 401) | ||||
|     assert.strictEqual(response.statusCode, 401) | ||||
|   }) | ||||
| }) | ||||
|   | ||||
| @@ -1,21 +1,23 @@ | ||||
| import tap from 'tap' | ||||
| import test from 'node:test' | ||||
| import assert from 'node:assert/strict' | ||||
|  | ||||
| import sinon from 'sinon' | ||||
|  | ||||
| import { application } from '../../../../../application.js' | ||||
| import { authenticateUserTest } from '../../../../../__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '../../../../../tools/database/prisma.js' | ||||
| import { memberExample } from '../../../../../models/Member.js' | ||||
| import { guildExample } from '../../../../../models/Guild.js' | ||||
| import { channelExample } from '../../../../../models/Channel.js' | ||||
| import { application } from '#src/application.js' | ||||
| import { authenticateUserTest } from '#src/__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { memberExample } from '#src/models/Member.js' | ||||
| import { guildExample } from '#src/models/Guild.js' | ||||
| import { channelExample } from '#src/models/Channel.js' | ||||
|  | ||||
| const defaultChannelId = 5 | ||||
|  | ||||
| await tap.test('POST /guilds/[guildId]/channels', async (t) => { | ||||
| await test('POST /guilds/[guildId]/channels', async (t) => { | ||||
|   t.afterEach(() => { | ||||
|     sinon.restore() | ||||
|   }) | ||||
|  | ||||
|   await t.test('succeeds', async (t) => { | ||||
|   await t.test('succeeds', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'member').value({ | ||||
|       findFirst: async () => { | ||||
| @@ -42,14 +44,14 @@ await tap.test('POST /guilds/[guildId]/channels', async (t) => { | ||||
|       payload: { name: channelExample.name } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 201) | ||||
|     t.equal(responseJson.id, channelExample.id) | ||||
|     t.equal(responseJson.name, channelExample.name) | ||||
|     t.equal(responseJson.guildId, channelExample.guildId) | ||||
|     t.equal(responseJson.defaultChannelId, defaultChannelId) | ||||
|     assert.strictEqual(response.statusCode, 201) | ||||
|     assert.strictEqual(responseJson.id, channelExample.id) | ||||
|     assert.strictEqual(responseJson.name, channelExample.name) | ||||
|     assert.strictEqual(responseJson.guildId, channelExample.guildId) | ||||
|     assert.strictEqual(responseJson.defaultChannelId, defaultChannelId) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails if the member is not found', async (t) => { | ||||
|   await t.test('fails if the member is not found', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'member').value({ | ||||
|       findFirst: async () => { | ||||
| @@ -64,10 +66,10 @@ await tap.test('POST /guilds/[guildId]/channels', async (t) => { | ||||
|       }, | ||||
|       payload: { name: channelExample.name } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 404) | ||||
|     assert.strictEqual(response.statusCode, 404) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails if the member is not owner', async (t) => { | ||||
|   await t.test('fails if the member is not owner', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'member').value({ | ||||
|       findFirst: async () => { | ||||
| @@ -85,6 +87,6 @@ await tap.test('POST /guilds/[guildId]/channels', async (t) => { | ||||
|       }, | ||||
|       payload: { name: channelExample.name } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 400) | ||||
|     assert.strictEqual(response.statusCode, 400) | ||||
|   }) | ||||
| }) | ||||
|   | ||||
| @@ -2,15 +2,15 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import prisma from '../../../../tools/database/prisma.js' | ||||
| import { fastifyErrors } from '../../../../models/utils.js' | ||||
| import authenticateUser from '../../../../tools/plugins/authenticateUser.js' | ||||
| import { guildSchema } from '../../../../models/Guild.js' | ||||
| import { channelSchema } from '../../../../models/Channel.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
| import { guildSchema } from '#src/models/Guild.js' | ||||
| import { channelSchema } from '#src/models/Channel.js' | ||||
| import { | ||||
|   getPaginationOptions, | ||||
|   queryPaginationObjectSchema | ||||
| } from '../../../../tools/database/pagination.js' | ||||
| } from '#src/tools/database/pagination.js' | ||||
|  | ||||
| type QuerySchemaType = Static<typeof queryPaginationObjectSchema> | ||||
|  | ||||
|   | ||||
| @@ -2,11 +2,11 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import prisma from '../../../../tools/database/prisma.js' | ||||
| import { fastifyErrors } from '../../../../models/utils.js' | ||||
| import authenticateUser from '../../../../tools/plugins/authenticateUser.js' | ||||
| import { channelSchema } from '../../../../models/Channel.js' | ||||
| import { guildSchema } from '../../../../models/Guild.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
| import { channelSchema } from '#src/models/Channel.js' | ||||
| import { guildSchema } from '#src/models/Guild.js' | ||||
|  | ||||
| const bodyPostServiceSchema = Type.Object({ | ||||
|   name: channelSchema.name | ||||
| @@ -57,9 +57,9 @@ export const postChannelService: FastifyPluginAsync = async (fastify) => { | ||||
|       if (request.user == null) { | ||||
|         throw fastify.httpErrors.forbidden() | ||||
|       } | ||||
|       const { user } = request | ||||
|       const { guildId } = request.params | ||||
|       const { name } = request.body | ||||
|       const { user, params, body } = request | ||||
|       const { guildId } = params | ||||
|       const { name } = body | ||||
|       const member = await prisma.member.findFirst({ | ||||
|         where: { guildId, userId: user.current.id } | ||||
|       }) | ||||
|   | ||||
| @@ -2,10 +2,10 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import prisma from '../../../tools/database/prisma.js' | ||||
| import { fastifyErrors } from '../../../models/utils.js' | ||||
| import authenticateUser from '../../../tools/plugins/authenticateUser.js' | ||||
| import { guildSchema } from '../../../models/Guild.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
| import { guildSchema } from '#src/models/Guild.js' | ||||
|  | ||||
| const parametersSchema = Type.Object({ | ||||
|   guildId: guildSchema.id | ||||
|   | ||||
| @@ -2,13 +2,13 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import prisma from '../../../tools/database/prisma.js' | ||||
| import { fastifyErrors } from '../../../models/utils.js' | ||||
| import authenticateUser from '../../../tools/plugins/authenticateUser.js' | ||||
| import { guildSchema } from '../../../models/Guild.js' | ||||
| import { memberSchema } from '../../../models/Member.js' | ||||
| import { userPublicWithoutSettingsSchema } from '../../../models/User.js' | ||||
| import { channelSchema } from '../../../models/Channel.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
| import { guildSchema } from '#src/models/Guild.js' | ||||
| import { memberSchema } from '#src/models/Member.js' | ||||
| import { userPublicWithoutSettingsSchema } from '#src/models/User.js' | ||||
| import { channelSchema } from '#src/models/Channel.js' | ||||
|  | ||||
| const parametersSchema = Type.Object({ | ||||
|   guildId: guildSchema.id | ||||
|   | ||||
| @@ -3,12 +3,12 @@ import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
| import fastifyMultipart from '@fastify/multipart' | ||||
|  | ||||
| import authenticateUser from '../../../../tools/plugins/authenticateUser.js' | ||||
| import { fastifyErrors } from '../../../../models/utils.js' | ||||
| import prisma from '../../../../tools/database/prisma.js' | ||||
| import { uploadFile } from '../../../../tools/utils/uploadFile.js' | ||||
| import { guildSchema } from '../../../../models/Guild.js' | ||||
| import { channelSchema } from '../../../../models/Channel.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { uploadFile } from '#src/tools/utils/uploadFile.js' | ||||
| import { guildSchema } from '#src/models/Guild.js' | ||||
| import { channelSchema } from '#src/models/Channel.js' | ||||
|  | ||||
| const parametersSchema = Type.Object({ | ||||
|   guildId: guildSchema.id | ||||
|   | ||||
| @@ -1,19 +1,21 @@ | ||||
| import tap from 'tap' | ||||
| import test from 'node:test' | ||||
| import assert from 'node:assert/strict' | ||||
|  | ||||
| import sinon from 'sinon' | ||||
|  | ||||
| import { application } from '../../../../../application.js' | ||||
| import { authenticateUserTest } from '../../../../../__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '../../../../../tools/database/prisma.js' | ||||
| import { memberExample } from '../../../../../models/Member.js' | ||||
| import { guildExample } from '../../../../../models/Guild.js' | ||||
| import { userExample } from '../../../../../models/User.js' | ||||
| import { application } from '#src/application.js' | ||||
| import { authenticateUserTest } from '#src/__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { memberExample } from '#src/models/Member.js' | ||||
| import { guildExample } from '#src/models/Guild.js' | ||||
| import { userExample } from '#src/models/User.js' | ||||
|  | ||||
| await tap.test('GET /guilds/[guildId]/members', async (t) => { | ||||
| await test('GET /guilds/[guildId]/members', async (t) => { | ||||
|   t.afterEach(() => { | ||||
|     sinon.restore() | ||||
|   }) | ||||
|  | ||||
|   await t.test('succeeds', async (t) => { | ||||
|   await t.test('succeeds', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'member').value({ | ||||
|       findFirst: async () => { | ||||
| @@ -31,16 +33,16 @@ await tap.test('GET /guilds/[guildId]/members', async (t) => { | ||||
|       } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 200) | ||||
|     t.equal(responseJson.length, 1) | ||||
|     t.equal(responseJson[0].id, memberExample.id) | ||||
|     t.equal(responseJson[0].isOwner, memberExample.isOwner) | ||||
|     t.equal(responseJson[0].user.id, userExample.id) | ||||
|     t.equal(responseJson[0].user.name, userExample.name) | ||||
|     t.equal(responseJson[0].user.email, null) | ||||
|     assert.strictEqual(response.statusCode, 200) | ||||
|     assert.strictEqual(responseJson.length, 1) | ||||
|     assert.strictEqual(responseJson[0].id, memberExample.id) | ||||
|     assert.strictEqual(responseJson[0].isOwner, memberExample.isOwner) | ||||
|     assert.strictEqual(responseJson[0].user.id, userExample.id) | ||||
|     assert.strictEqual(responseJson[0].user.name, userExample.name) | ||||
|     assert.strictEqual(responseJson[0].user.email, null) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails with not found member/guild', async (t) => { | ||||
|   await t.test('fails with not found member/guild', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'member').value({ | ||||
|       findFirst: async () => { | ||||
| @@ -55,15 +57,15 @@ await tap.test('GET /guilds/[guildId]/members', async (t) => { | ||||
|       } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 404) | ||||
|     t.equal(responseJson.message, 'Member not found') | ||||
|     assert.strictEqual(response.statusCode, 404) | ||||
|     assert.strictEqual(responseJson.message, 'Member not found') | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails with unauthenticated user', async (t) => { | ||||
|   await t.test('fails with unauthenticated user', async () => { | ||||
|     const response = await application.inject({ | ||||
|       method: 'GET', | ||||
|       url: '/guilds/1/members' | ||||
|     }) | ||||
|     t.equal(response.statusCode, 401) | ||||
|     assert.strictEqual(response.statusCode, 401) | ||||
|   }) | ||||
| }) | ||||
|   | ||||
| @@ -2,16 +2,16 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import prisma from '../../../../tools/database/prisma.js' | ||||
| import { fastifyErrors } from '../../../../models/utils.js' | ||||
| import authenticateUser from '../../../../tools/plugins/authenticateUser.js' | ||||
| import { guildSchema } from '../../../../models/Guild.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
| import { guildSchema } from '#src/models/Guild.js' | ||||
| import { | ||||
|   getPaginationOptions, | ||||
|   queryPaginationObjectSchema | ||||
| } from '../../../../tools/database/pagination.js' | ||||
| import { memberSchema } from '../../../../models/Member.js' | ||||
| import { userPublicWithoutSettingsSchema } from '../../../../models/User.js' | ||||
| } from '#src/tools/database/pagination.js' | ||||
| import { memberSchema } from '#src/models/Member.js' | ||||
| import { userPublicWithoutSettingsSchema } from '#src/models/User.js' | ||||
|  | ||||
| type QuerySchemaType = Static<typeof queryPaginationObjectSchema> | ||||
|  | ||||
|   | ||||
| @@ -1,22 +1,24 @@ | ||||
| import tap from 'tap' | ||||
| import test from 'node:test' | ||||
| import assert from 'node:assert/strict' | ||||
|  | ||||
| import sinon from 'sinon' | ||||
|  | ||||
| import { application } from '../../../../../../application.js' | ||||
| import { authenticateUserTest } from '../../../../../../__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '../../../../../../tools/database/prisma.js' | ||||
| import { memberExample } from '../../../../../../models/Member.js' | ||||
| import { guildExample } from '../../../../../../models/Guild.js' | ||||
| import { userExample } from '../../../../../../models/User.js' | ||||
| import { channelExample } from '../../../../../../models/Channel.js' | ||||
| import { application } from '#src/application.js' | ||||
| import { authenticateUserTest } from '#src/__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { memberExample } from '#src/models/Member.js' | ||||
| import { guildExample } from '#src/models/Guild.js' | ||||
| import { userExample } from '#src/models/User.js' | ||||
| import { channelExample } from '#src/models/Channel.js' | ||||
|  | ||||
| const defaultChannelId = 5 | ||||
|  | ||||
| await tap.test('POST /guilds/[guildId]/members/join', async (t) => { | ||||
| await test('POST /guilds/[guildId]/members/join', async (t) => { | ||||
|   t.afterEach(() => { | ||||
|     sinon.restore() | ||||
|   }) | ||||
|  | ||||
|   await t.test('succeeds', async (t) => { | ||||
|   await t.test('succeeds', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'member').value({ | ||||
|       findFirst: async () => { | ||||
| @@ -44,17 +46,17 @@ await tap.test('POST /guilds/[guildId]/members/join', async (t) => { | ||||
|       } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 201) | ||||
|     t.equal(responseJson.id, memberExample.id) | ||||
|     t.equal(responseJson.userId, memberExample.userId) | ||||
|     t.equal(responseJson.user.name, userExample.name) | ||||
|     t.equal(responseJson.user.email, null) | ||||
|     t.equal(responseJson.guild.id, guildExample.id) | ||||
|     t.equal(responseJson.guild.name, guildExample.name) | ||||
|     t.equal(responseJson.guild.defaultChannelId, channelExample.id) | ||||
|     assert.strictEqual(response.statusCode, 201) | ||||
|     assert.strictEqual(responseJson.id, memberExample.id) | ||||
|     assert.strictEqual(responseJson.userId, memberExample.userId) | ||||
|     assert.strictEqual(responseJson.user.name, userExample.name) | ||||
|     assert.strictEqual(responseJson.user.email, null) | ||||
|     assert.strictEqual(responseJson.guild.id, guildExample.id) | ||||
|     assert.strictEqual(responseJson.guild.name, guildExample.name) | ||||
|     assert.strictEqual(responseJson.guild.defaultChannelId, channelExample.id) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails if the guild is not found', async (t) => { | ||||
|   await t.test('fails if the guild is not found', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'member').value({ | ||||
|       findFirst: async () => { | ||||
| @@ -78,10 +80,10 @@ await tap.test('POST /guilds/[guildId]/members/join', async (t) => { | ||||
|         authorization: `Bearer ${accessToken}` | ||||
|       } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 404) | ||||
|     assert.strictEqual(response.statusCode, 404) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails if the user is already in the guild', async (t) => { | ||||
|   await t.test('fails if the user is already in the guild', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'member').value({ | ||||
|       findFirst: async () => { | ||||
| @@ -109,7 +111,7 @@ await tap.test('POST /guilds/[guildId]/members/join', async (t) => { | ||||
|       } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 400) | ||||
|     t.equal(responseJson.defaultChannelId, defaultChannelId) | ||||
|     assert.strictEqual(response.statusCode, 400) | ||||
|     assert.strictEqual(responseJson.defaultChannelId, defaultChannelId) | ||||
|   }) | ||||
| }) | ||||
|   | ||||
| @@ -2,17 +2,13 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import prisma from '../../../../../tools/database/prisma.js' | ||||
| import { | ||||
|   fastifyErrors, | ||||
|   fastifyErrorsSchema, | ||||
|   id | ||||
| } from '../../../../../models/utils.js' | ||||
| import authenticateUser from '../../../../../tools/plugins/authenticateUser.js' | ||||
| import { guildSchema } from '../../../../../models/Guild.js' | ||||
| import { memberSchema } from '../../../../../models/Member.js' | ||||
| import { userPublicWithoutSettingsSchema } from '../../../../../models/User.js' | ||||
| import { channelSchema } from '../../../../../models/Channel.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { fastifyErrors, fastifyErrorsSchema, id } from '#src/models/utils.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
| import { guildSchema } from '#src/models/Guild.js' | ||||
| import { memberSchema } from '#src/models/Member.js' | ||||
| import { userPublicWithoutSettingsSchema } from '#src/models/User.js' | ||||
| import { channelSchema } from '#src/models/Channel.js' | ||||
|  | ||||
| const parametersSchema = Type.Object({ | ||||
|   guildId: guildSchema.id | ||||
| @@ -62,8 +58,8 @@ export const postMemberService: FastifyPluginAsync = async (fastify) => { | ||||
|       if (request.user == null) { | ||||
|         throw fastify.httpErrors.forbidden() | ||||
|       } | ||||
|       const { user } = request | ||||
|       const { guildId } = request.params | ||||
|       const { user, params } = request | ||||
|       const { guildId } = params | ||||
|       const guild = await prisma.guild.findUnique({ | ||||
|         where: { | ||||
|           id: guildId | ||||
|   | ||||
| @@ -1,18 +1,20 @@ | ||||
| import tap from 'tap' | ||||
| import test from 'node:test' | ||||
| import assert from 'node:assert/strict' | ||||
|  | ||||
| import sinon from 'sinon' | ||||
|  | ||||
| import { application } from '../../../../../../application.js' | ||||
| import { authenticateUserTest } from '../../../../../../__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '../../../../../../tools/database/prisma.js' | ||||
| import { memberExample } from '../../../../../../models/Member.js' | ||||
| import { guildExample } from '../../../../../../models/Guild.js' | ||||
| import { application } from '#src/application.js' | ||||
| import { authenticateUserTest } from '#src/__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { memberExample } from '#src/models/Member.js' | ||||
| import { guildExample } from '#src/models/Guild.js' | ||||
|  | ||||
| await tap.test('DELETE /guilds/[guildId]/members/leave', async (t) => { | ||||
| await test('DELETE /guilds/[guildId]/members/leave', async (t) => { | ||||
|   t.afterEach(() => { | ||||
|     sinon.restore() | ||||
|   }) | ||||
|  | ||||
|   await t.test('succeeds', async (t) => { | ||||
|   await t.test('succeeds', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     const member = { | ||||
|       ...memberExample, | ||||
| @@ -34,13 +36,13 @@ await tap.test('DELETE /guilds/[guildId]/members/leave', async (t) => { | ||||
|       } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 200) | ||||
|     t.equal(responseJson.id, member.id) | ||||
|     t.equal(responseJson.isOwner, member.isOwner) | ||||
|     t.equal(responseJson.userId, member.userId) | ||||
|     assert.strictEqual(response.statusCode, 200) | ||||
|     assert.strictEqual(responseJson.id, member.id) | ||||
|     assert.strictEqual(responseJson.isOwner, member.isOwner) | ||||
|     assert.strictEqual(responseJson.userId, member.userId) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails if the member is not found', async (t) => { | ||||
|   await t.test('fails if the member is not found', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'member').value({ | ||||
|       findFirst: async () => { | ||||
| @@ -54,10 +56,10 @@ await tap.test('DELETE /guilds/[guildId]/members/leave', async (t) => { | ||||
|         authorization: `Bearer ${accessToken}` | ||||
|       } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 404) | ||||
|     assert.strictEqual(response.statusCode, 404) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails if the member is owner', async (t) => { | ||||
|   await t.test('fails if the member is owner', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     const member = { | ||||
|       ...memberExample, | ||||
| @@ -75,6 +77,6 @@ await tap.test('DELETE /guilds/[guildId]/members/leave', async (t) => { | ||||
|         authorization: `Bearer ${accessToken}` | ||||
|       } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 400) | ||||
|     assert.strictEqual(response.statusCode, 400) | ||||
|   }) | ||||
| }) | ||||
|   | ||||
| @@ -2,11 +2,11 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import prisma from '../../../../../tools/database/prisma.js' | ||||
| import { fastifyErrors } from '../../../../../models/utils.js' | ||||
| import authenticateUser from '../../../../../tools/plugins/authenticateUser.js' | ||||
| import { guildSchema } from '../../../../../models/Guild.js' | ||||
| import { memberSchema } from '../../../../../models/Member.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
| import { guildSchema } from '#src/models/Guild.js' | ||||
| import { memberSchema } from '#src/models/Member.js' | ||||
|  | ||||
| const parametersSchema = Type.Object({ | ||||
|   guildId: guildSchema.id | ||||
| @@ -46,8 +46,8 @@ export const deleteMemberService: FastifyPluginAsync = async (fastify) => { | ||||
|       if (request.user == null) { | ||||
|         throw fastify.httpErrors.forbidden() | ||||
|       } | ||||
|       const { user } = request | ||||
|       const { guildId } = request.params | ||||
|       const { user, params } = request | ||||
|       const { guildId } = params | ||||
|       const member = await prisma.member.findFirst({ | ||||
|         where: { guildId, userId: user.current.id } | ||||
|       }) | ||||
|   | ||||
| @@ -2,12 +2,12 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import prisma from '../../../tools/database/prisma.js' | ||||
| import { fastifyErrors } from '../../../models/utils.js' | ||||
| import authenticateUser from '../../../tools/plugins/authenticateUser.js' | ||||
| import { guildSchema } from '../../../models/Guild.js' | ||||
| import { parseStringNullish } from '../../../tools/utils/parseStringNullish.js' | ||||
| import { channelSchema } from '../../../models/Channel.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
| import { guildSchema } from '#src/models/Guild.js' | ||||
| import { parseStringNullish } from '#src/tools/utils/parseStringNullish.js' | ||||
| import { channelSchema } from '#src/models/Channel.js' | ||||
|  | ||||
| const parametersSchema = Type.Object({ | ||||
|   guildId: guildSchema.id | ||||
|   | ||||
| @@ -1,19 +1,21 @@ | ||||
| import tap from 'tap' | ||||
| import test from 'node:test' | ||||
| import assert from 'node:assert/strict' | ||||
|  | ||||
| import sinon from 'sinon' | ||||
|  | ||||
| import { application } from '../../../application.js' | ||||
| import { authenticateUserTest } from '../../../__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '../../../tools/database/prisma.js' | ||||
| import { memberExample } from '../../../models/Member.js' | ||||
| import { guildExample } from '../../../models/Guild.js' | ||||
| import { channelExample } from '../../../models/Channel.js' | ||||
| import { application } from '#src/application.js' | ||||
| import { authenticateUserTest } from '#src/__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { memberExample } from '#src/models/Member.js' | ||||
| import { guildExample } from '#src/models/Guild.js' | ||||
| import { channelExample } from '#src/models/Channel.js' | ||||
|  | ||||
| await tap.test('GET /guilds', async (t) => { | ||||
| await test('GET /guilds', async (t) => { | ||||
|   t.afterEach(() => { | ||||
|     sinon.restore() | ||||
|   }) | ||||
|  | ||||
|   await t.test('succeeds', async (t) => { | ||||
|   await t.test('succeeds', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'guild').value({ | ||||
|       findUnique: async () => { | ||||
| @@ -38,10 +40,10 @@ await tap.test('GET /guilds', async (t) => { | ||||
|       } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 200) | ||||
|     t.equal(responseJson.length, 1) | ||||
|     t.equal(responseJson[0].name, guildExample.name) | ||||
|     t.equal(responseJson[0].description, guildExample.description) | ||||
|     t.equal(responseJson[0].defaultChannelId, channelExample.id) | ||||
|     assert.strictEqual(response.statusCode, 200) | ||||
|     assert.strictEqual(responseJson.length, 1) | ||||
|     assert.strictEqual(responseJson[0].name, guildExample.name) | ||||
|     assert.strictEqual(responseJson[0].description, guildExample.description) | ||||
|     assert.strictEqual(responseJson[0].defaultChannelId, channelExample.id) | ||||
|   }) | ||||
| }) | ||||
|   | ||||
| @@ -1,20 +1,22 @@ | ||||
| import tap from 'tap' | ||||
| import test from 'node:test' | ||||
| import assert from 'node:assert/strict' | ||||
|  | ||||
| import sinon from 'sinon' | ||||
|  | ||||
| import { application } from '../../../application.js' | ||||
| import { authenticateUserTest } from '../../../__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '../../../tools/database/prisma.js' | ||||
| import { memberExample } from '../../../models/Member.js' | ||||
| import { guildExample } from '../../../models/Guild.js' | ||||
| import { channelExample } from '../../../models/Channel.js' | ||||
| import { userExample } from '../../../models/User.js' | ||||
| import { application } from '#src/application.js' | ||||
| import { authenticateUserTest } from '#src/__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { memberExample } from '#src/models/Member.js' | ||||
| import { guildExample } from '#src/models/Guild.js' | ||||
| import { channelExample } from '#src/models/Channel.js' | ||||
| import { userExample } from '#src/models/User.js' | ||||
|  | ||||
| await tap.test('POST /guilds', async (t) => { | ||||
| await test('POST /guilds', async (t) => { | ||||
|   t.afterEach(() => { | ||||
|     sinon.restore() | ||||
|   }) | ||||
|  | ||||
|   await t.test('succeeds', async (t) => { | ||||
|   await t.test('succeeds', async () => { | ||||
|     const { accessToken, user } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'guild').value({ | ||||
|       create: async () => { | ||||
| @@ -49,21 +51,24 @@ await tap.test('POST /guilds', async (t) => { | ||||
|       } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 201) | ||||
|     t.equal(responseJson.guild.id, guildExample.id) | ||||
|     t.equal(responseJson.guild.name, guildExample.name) | ||||
|     t.equal(responseJson.guild.description, guildExample.description) | ||||
|     t.equal(responseJson.guild.members.length, 1) | ||||
|     t.equal(responseJson.guild.members[0].userId, user.id) | ||||
|     t.equal(responseJson.guild.members[0].user.name, user.name) | ||||
|     t.equal(responseJson.guild.members[0].guildId, guildExample.id) | ||||
|     t.equal(responseJson.guild.members[0].isOwner, memberExample.isOwner) | ||||
|     t.equal(responseJson.guild.channels.length, 1) | ||||
|     t.equal(responseJson.guild.channels[0].id, channelExample.id) | ||||
|     t.equal(responseJson.guild.channels[0].guildId, guildExample.id) | ||||
|     assert.strictEqual(response.statusCode, 201) | ||||
|     assert.strictEqual(responseJson.guild.id, guildExample.id) | ||||
|     assert.strictEqual(responseJson.guild.name, guildExample.name) | ||||
|     assert.strictEqual(responseJson.guild.description, guildExample.description) | ||||
|     assert.strictEqual(responseJson.guild.members.length, 1) | ||||
|     assert.strictEqual(responseJson.guild.members[0].userId, user.id) | ||||
|     assert.strictEqual(responseJson.guild.members[0].user.name, user.name) | ||||
|     assert.strictEqual(responseJson.guild.members[0].guildId, guildExample.id) | ||||
|     assert.strictEqual( | ||||
|       responseJson.guild.members[0].isOwner, | ||||
|       memberExample.isOwner | ||||
|     ) | ||||
|     assert.strictEqual(responseJson.guild.channels.length, 1) | ||||
|     assert.strictEqual(responseJson.guild.channels[0].id, channelExample.id) | ||||
|     assert.strictEqual(responseJson.guild.channels[0].guildId, guildExample.id) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails with empty name and description', async (t) => { | ||||
|   await t.test('fails with empty name and description', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     const response = await application.inject({ | ||||
|       method: 'POST', | ||||
| @@ -72,6 +77,6 @@ await tap.test('POST /guilds', async (t) => { | ||||
|         authorization: `Bearer ${accessToken}` | ||||
|       } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 400) | ||||
|     assert.strictEqual(response.statusCode, 400) | ||||
|   }) | ||||
| }) | ||||
|   | ||||
| @@ -2,14 +2,14 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import prisma from '../../tools/database/prisma.js' | ||||
| import { fastifyErrors, id } from '../../models/utils.js' | ||||
| import authenticateUser from '../../tools/plugins/authenticateUser.js' | ||||
| import { guildSchema } from '../../models/Guild.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { fastifyErrors, id } from '#src/models/utils.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
| import { guildSchema } from '#src/models/Guild.js' | ||||
| import { | ||||
|   getPaginationOptions, | ||||
|   queryPaginationObjectSchema | ||||
| } from '../../tools/database/pagination.js' | ||||
| } from '#src/tools/database/pagination.js' | ||||
|  | ||||
| type QuerySchemaType = Static<typeof queryPaginationObjectSchema> | ||||
|  | ||||
|   | ||||
| @@ -2,14 +2,14 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import prisma from '../../tools/database/prisma.js' | ||||
| import { fastifyErrors } from '../../models/utils.js' | ||||
| import authenticateUser from '../../tools/plugins/authenticateUser.js' | ||||
| import { guildSchema } from '../../models/Guild.js' | ||||
| import { channelSchema } from '../../models/Channel.js' | ||||
| import { memberSchema } from '../../models/Member.js' | ||||
| import { userPublicWithoutSettingsSchema } from '../../models/User.js' | ||||
| import { parseStringNullish } from '../../tools/utils/parseStringNullish.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
| import { guildSchema } from '#src/models/Guild.js' | ||||
| import { channelSchema } from '#src/models/Channel.js' | ||||
| import { memberSchema } from '#src/models/Member.js' | ||||
| import { userPublicWithoutSettingsSchema } from '#src/models/User.js' | ||||
| import { parseStringNullish } from '#src/tools/utils/parseStringNullish.js' | ||||
|  | ||||
| const bodyPostServiceSchema = Type.Object({ | ||||
|   name: guildSchema.name, | ||||
|   | ||||
| @@ -1,17 +1,19 @@ | ||||
| import tap from 'tap' | ||||
| import test from 'node:test' | ||||
| import assert from 'node:assert/strict' | ||||
|  | ||||
| import sinon from 'sinon' | ||||
|  | ||||
| import { application } from '../../../../application.js' | ||||
| import { authenticateUserTest } from '../../../../__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '../../../../tools/database/prisma.js' | ||||
| import { guildExample } from '../../../../models/Guild.js' | ||||
| import { application } from '#src/application.js' | ||||
| import { authenticateUserTest } from '#src/__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { guildExample } from '#src/models/Guild.js' | ||||
|  | ||||
| await tap.test('GET /guilds/public', async (t) => { | ||||
| await test('GET /guilds/public', async (t) => { | ||||
|   t.afterEach(() => { | ||||
|     sinon.restore() | ||||
|   }) | ||||
|  | ||||
|   await t.test('succeeds', async (t) => { | ||||
|   await t.test('succeeds', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'guild').value({ | ||||
|       findMany: async () => { | ||||
| @@ -31,9 +33,9 @@ await tap.test('GET /guilds/public', async (t) => { | ||||
|       } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 200) | ||||
|     t.equal(responseJson.length, 1) | ||||
|     t.equal(responseJson[0].name, guildExample.name) | ||||
|     t.equal(responseJson[0].membersCount, 2) | ||||
|     assert.strictEqual(response.statusCode, 200) | ||||
|     assert.strictEqual(responseJson.length, 1) | ||||
|     assert.strictEqual(responseJson[0].name, guildExample.name) | ||||
|     assert.strictEqual(responseJson[0].membersCount, 2) | ||||
|   }) | ||||
| }) | ||||
|   | ||||
| @@ -2,14 +2,14 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import prisma from '../../../tools/database/prisma.js' | ||||
| import { fastifyErrors } from '../../../models/utils.js' | ||||
| import authenticateUser from '../../../tools/plugins/authenticateUser.js' | ||||
| import { guildSchema } from '../../../models/Guild.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
| import { guildSchema } from '#src/models/Guild.js' | ||||
| import { | ||||
|   getPaginationOptions, | ||||
|   queryPaginationSchema | ||||
| } from '../../../tools/database/pagination.js' | ||||
| } from '#src/tools/database/pagination.js' | ||||
|  | ||||
| const querySchema = Type.Object({ | ||||
|   search: Type.Optional(Type.String()), | ||||
|   | ||||
| @@ -1,20 +1,22 @@ | ||||
| import tap from 'tap' | ||||
| import test from 'node:test' | ||||
| import assert from 'node:assert/strict' | ||||
|  | ||||
| import sinon from 'sinon' | ||||
|  | ||||
| import { application } from '../../../../application.js' | ||||
| import { authenticateUserTest } from '../../../../__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '../../../../tools/database/prisma.js' | ||||
| import { messageExample } from '../../../../models/Message.js' | ||||
| import { memberExample } from '../../../../models/Member.js' | ||||
| import { userExample } from '../../../../models/User.js' | ||||
| import { channelExample } from '../../../../models/Channel.js' | ||||
| import { application } from '#src/application.js' | ||||
| import { authenticateUserTest } from '#src/__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { messageExample } from '#src/models/Message.js' | ||||
| import { memberExample } from '#src/models/Member.js' | ||||
| import { userExample } from '#src/models/User.js' | ||||
| import { channelExample } from '#src/models/Channel.js' | ||||
|  | ||||
| await tap.test('DELETE /messsages/[messageId]', async (t) => { | ||||
| await test('DELETE /messsages/[messageId]', async (t) => { | ||||
|   t.afterEach(() => { | ||||
|     sinon.restore() | ||||
|   }) | ||||
|  | ||||
|   await t.test('succeeds', async (t) => { | ||||
|   await t.test('succeeds', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'message').value({ | ||||
|       findFirst: async () => { | ||||
| @@ -43,18 +45,18 @@ await tap.test('DELETE /messsages/[messageId]', async (t) => { | ||||
|       } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 200) | ||||
|     t.equal(responseJson.id, messageExample.id) | ||||
|     t.equal(responseJson.value, messageExample.value) | ||||
|     t.equal(responseJson.type, messageExample.type) | ||||
|     t.equal(responseJson.mimetype, messageExample.mimetype) | ||||
|     t.equal(responseJson.member.id, memberExample.id) | ||||
|     t.equal(responseJson.member.isOwner, memberExample.isOwner) | ||||
|     t.equal(responseJson.member.user.id, userExample.id) | ||||
|     t.equal(responseJson.member.user.name, userExample.name) | ||||
|     assert.strictEqual(response.statusCode, 200) | ||||
|     assert.strictEqual(responseJson.id, messageExample.id) | ||||
|     assert.strictEqual(responseJson.value, messageExample.value) | ||||
|     assert.strictEqual(responseJson.type, messageExample.type) | ||||
|     assert.strictEqual(responseJson.mimetype, messageExample.mimetype) | ||||
|     assert.strictEqual(responseJson.member.id, memberExample.id) | ||||
|     assert.strictEqual(responseJson.member.isOwner, memberExample.isOwner) | ||||
|     assert.strictEqual(responseJson.member.user.id, userExample.id) | ||||
|     assert.strictEqual(responseJson.member.user.name, userExample.name) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails if the message is not found', async (t) => { | ||||
|   await t.test('fails if the message is not found', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'message').value({ | ||||
|       findFirst: async () => { | ||||
| @@ -68,10 +70,10 @@ await tap.test('DELETE /messsages/[messageId]', async (t) => { | ||||
|         authorization: `Bearer ${accessToken}` | ||||
|       } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 404) | ||||
|     assert.strictEqual(response.statusCode, 404) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails if the member is not found', async (t) => { | ||||
|   await t.test('fails if the member is not found', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'message').value({ | ||||
|       findFirst: async () => { | ||||
| @@ -93,10 +95,10 @@ await tap.test('DELETE /messsages/[messageId]', async (t) => { | ||||
|         authorization: `Bearer ${accessToken}` | ||||
|       } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 404) | ||||
|     assert.strictEqual(response.statusCode, 404) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails if the member is not owner of the message', async (t) => { | ||||
|   await t.test('fails if the member is not owner of the message', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     const randomUserIdOwnerOfMessage = 14 | ||||
|     sinon.stub(prisma, 'message').value({ | ||||
| @@ -122,6 +124,6 @@ await tap.test('DELETE /messsages/[messageId]', async (t) => { | ||||
|         authorization: `Bearer ${accessToken}` | ||||
|       } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 400) | ||||
|     assert.strictEqual(response.statusCode, 400) | ||||
|   }) | ||||
| }) | ||||
|   | ||||
| @@ -1,20 +1,22 @@ | ||||
| import tap from 'tap' | ||||
| import test from 'node:test' | ||||
| import assert from 'node:assert/strict' | ||||
|  | ||||
| import sinon from 'sinon' | ||||
|  | ||||
| import { application } from '../../../../application.js' | ||||
| import { authenticateUserTest } from '../../../../__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '../../../../tools/database/prisma.js' | ||||
| import { messageExample } from '../../../../models/Message.js' | ||||
| import { memberExample } from '../../../../models/Member.js' | ||||
| import { userExample } from '../../../../models/User.js' | ||||
| import { channelExample } from '../../../../models/Channel.js' | ||||
| import { application } from '#src/application.js' | ||||
| import { authenticateUserTest } from '#src/__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { messageExample } from '#src/models/Message.js' | ||||
| import { memberExample } from '#src/models/Member.js' | ||||
| import { userExample } from '#src/models/User.js' | ||||
| import { channelExample } from '#src/models/Channel.js' | ||||
|  | ||||
| await tap.test('PUT /messsages/[messageId]', async (t) => { | ||||
| await test('PUT /messsages/[messageId]', async (t) => { | ||||
|   t.afterEach(() => { | ||||
|     sinon.restore() | ||||
|   }) | ||||
|  | ||||
|   await t.test('succeeds', async (t) => { | ||||
|   await t.test('succeeds', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     const newValue = 'some message' | ||||
|     sinon.stub(prisma, 'message').value({ | ||||
| @@ -48,18 +50,18 @@ await tap.test('PUT /messsages/[messageId]', async (t) => { | ||||
|       payload: { value: newValue } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 200) | ||||
|     t.equal(responseJson.id, messageExample.id) | ||||
|     t.equal(responseJson.value, newValue) | ||||
|     t.equal(responseJson.type, messageExample.type) | ||||
|     t.equal(responseJson.mimetype, messageExample.mimetype) | ||||
|     t.equal(responseJson.member.id, memberExample.id) | ||||
|     t.equal(responseJson.member.isOwner, memberExample.isOwner) | ||||
|     t.equal(responseJson.member.user.id, userExample.id) | ||||
|     t.equal(responseJson.member.user.name, userExample.name) | ||||
|     assert.strictEqual(response.statusCode, 200) | ||||
|     assert.strictEqual(responseJson.id, messageExample.id) | ||||
|     assert.strictEqual(responseJson.value, newValue) | ||||
|     assert.strictEqual(responseJson.type, messageExample.type) | ||||
|     assert.strictEqual(responseJson.mimetype, messageExample.mimetype) | ||||
|     assert.strictEqual(responseJson.member.id, memberExample.id) | ||||
|     assert.strictEqual(responseJson.member.isOwner, memberExample.isOwner) | ||||
|     assert.strictEqual(responseJson.member.user.id, userExample.id) | ||||
|     assert.strictEqual(responseJson.member.user.name, userExample.name) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails if the message is not found', async (t) => { | ||||
|   await t.test('fails if the message is not found', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     const newValue = 'some message' | ||||
|     sinon.stub(prisma, 'message').value({ | ||||
| @@ -75,10 +77,10 @@ await tap.test('PUT /messsages/[messageId]', async (t) => { | ||||
|       }, | ||||
|       payload: { value: newValue } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 404) | ||||
|     assert.strictEqual(response.statusCode, 404) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails if the member is not found', async (t) => { | ||||
|   await t.test('fails if the member is not found', async () => { | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     const newValue = 'some message' | ||||
|     sinon.stub(prisma, 'message').value({ | ||||
| @@ -102,12 +104,12 @@ await tap.test('PUT /messsages/[messageId]', async (t) => { | ||||
|       }, | ||||
|       payload: { value: newValue } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 404) | ||||
|     assert.strictEqual(response.statusCode, 404) | ||||
|   }) | ||||
|  | ||||
|   await t.test( | ||||
|     'fails if the member is not the owner of the message', | ||||
|     async (t) => { | ||||
|     async () => { | ||||
|       const { accessToken } = await authenticateUserTest() | ||||
|       const newValue = 'some message' | ||||
|       const randomUserIdOwnerOfMessage = 14 | ||||
| @@ -135,7 +137,7 @@ await tap.test('PUT /messsages/[messageId]', async (t) => { | ||||
|         }, | ||||
|         payload: { value: newValue } | ||||
|       }) | ||||
|       t.equal(response.statusCode, 400) | ||||
|       assert.strictEqual(response.statusCode, 400) | ||||
|     } | ||||
|   ) | ||||
| }) | ||||
|   | ||||
| @@ -2,12 +2,12 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import prisma from '../../../tools/database/prisma.js' | ||||
| import { fastifyErrors } from '../../../models/utils.js' | ||||
| import authenticateUser from '../../../tools/plugins/authenticateUser.js' | ||||
| import { messageSchema } from '../../../models/Message.js' | ||||
| import { memberSchema } from '../../../models/Member.js' | ||||
| import { userPublicWithoutSettingsSchema } from '../../../models/User.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
| import { messageSchema } from '#src/models/Message.js' | ||||
| import { memberSchema } from '#src/models/Member.js' | ||||
| import { userPublicWithoutSettingsSchema } from '#src/models/User.js' | ||||
|  | ||||
| const parametersSchema = Type.Object({ | ||||
|   messageId: messageSchema.id | ||||
| @@ -53,8 +53,8 @@ export const deleteMessageService: FastifyPluginAsync = async (fastify) => { | ||||
|       if (request.user == null) { | ||||
|         throw fastify.httpErrors.forbidden() | ||||
|       } | ||||
|       const { user } = request | ||||
|       const { messageId } = request.params | ||||
|       const { user, params } = request | ||||
|       const { messageId } = params | ||||
|       const messageCheck = await prisma.message.findFirst({ | ||||
|         where: { id: messageId }, | ||||
|         include: { | ||||
|   | ||||
| @@ -2,12 +2,12 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import prisma from '../../../tools/database/prisma.js' | ||||
| import { fastifyErrors } from '../../../models/utils.js' | ||||
| import authenticateUser from '../../../tools/plugins/authenticateUser.js' | ||||
| import { messageSchema } from '../../../models/Message.js' | ||||
| import { memberSchema } from '../../../models/Member.js' | ||||
| import { userPublicWithoutSettingsSchema } from '../../../models/User.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
| import { messageSchema } from '#src/models/Message.js' | ||||
| import { memberSchema } from '#src/models/Member.js' | ||||
| import { userPublicWithoutSettingsSchema } from '#src/models/User.js' | ||||
|  | ||||
| const bodyPutServiceSchema = Type.Object({ | ||||
|   value: messageSchema.value | ||||
| @@ -61,9 +61,9 @@ export const putMessageService: FastifyPluginAsync = async (fastify) => { | ||||
|       if (request.user == null) { | ||||
|         throw fastify.httpErrors.forbidden() | ||||
|       } | ||||
|       const { user } = request | ||||
|       const { messageId } = request.params | ||||
|       const { value } = request.body | ||||
|       const { user, params, body } = request | ||||
|       const { messageId } = params | ||||
|       const { value } = body | ||||
|       const messageCheck = await prisma.message.findFirst({ | ||||
|         where: { id: messageId, type: 'text' }, | ||||
|         include: { | ||||
|   | ||||
| @@ -1,17 +1,19 @@ | ||||
| import tap from 'tap' | ||||
| import test from 'node:test' | ||||
| import assert from 'node:assert/strict' | ||||
|  | ||||
| import sinon from 'sinon' | ||||
|  | ||||
| import { application } from '../../../../application.js' | ||||
| import prisma from '../../../../tools/database/prisma.js' | ||||
| import { userExample } from '../../../../models/User.js' | ||||
| import { userSettingsExample } from '../../../../models/UserSettings.js' | ||||
| import { application } from '#src/application.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { userExample } from '#src/models/User.js' | ||||
| import { userSettingsExample } from '#src/models/UserSettings.js' | ||||
|  | ||||
| await tap.test('GET /users/[userId]', async (t) => { | ||||
| await test('GET /users/[userId]', async (t) => { | ||||
|   t.afterEach(() => { | ||||
|     sinon.restore() | ||||
|   }) | ||||
|  | ||||
|   await t.test('succeeds', async (t) => { | ||||
|   await t.test('succeeds', async () => { | ||||
|     sinon.stub(prisma, 'guild').value({ | ||||
|       findMany: async () => { | ||||
|         return [] | ||||
| @@ -32,12 +34,12 @@ await tap.test('GET /users/[userId]', async (t) => { | ||||
|       url: `/users/${userExample.id}` | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 200) | ||||
|     t.equal(responseJson.user.id, userExample.id) | ||||
|     t.equal(responseJson.user.name, userExample.name) | ||||
|     assert.strictEqual(response.statusCode, 200) | ||||
|     assert.strictEqual(responseJson.user.id, userExample.id) | ||||
|     assert.strictEqual(responseJson.user.name, userExample.name) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails with not found user', async (t) => { | ||||
|   await t.test('fails with not found user', async () => { | ||||
|     sinon.stub(prisma, 'userSetting').value({ | ||||
|       findFirst: async () => { | ||||
|         return null | ||||
| @@ -48,7 +50,7 @@ await tap.test('GET /users/[userId]', async (t) => { | ||||
|       url: `/users/1` | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 404) | ||||
|     t.equal(responseJson.message, 'User not found') | ||||
|     assert.strictEqual(response.statusCode, 404) | ||||
|     assert.strictEqual(responseJson.message, 'User not found') | ||||
|   }) | ||||
| }) | ||||
|   | ||||
| @@ -2,10 +2,10 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import prisma from '../../../tools/database/prisma.js' | ||||
| import { fastifyErrors } from '../../../models/utils.js' | ||||
| import { userPublicSchema } from '../../../models/User.js' | ||||
| import { guildSchema } from '../../../models/Guild.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import { userPublicSchema } from '#src/models/User.js' | ||||
| import { guildSchema } from '#src/models/Guild.js' | ||||
|  | ||||
| const parametersGetUserSchema = Type.Object({ | ||||
|   userId: userPublicSchema.id | ||||
|   | ||||
| @@ -1,16 +1,18 @@ | ||||
| import tap from 'tap' | ||||
| import test from 'node:test' | ||||
| import assert from 'node:assert/strict' | ||||
|  | ||||
| import sinon from 'sinon' | ||||
|  | ||||
| import { application } from '../../../../application.js' | ||||
| import prisma from '../../../../tools/database/prisma.js' | ||||
| import { userExample } from '../../../../models/User.js' | ||||
| import { application } from '#src/application.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { userExample } from '#src/models/User.js' | ||||
|  | ||||
| await tap.test('GET /users/confirm-email', async (t) => { | ||||
| await test('GET /users/confirm-email', async (t) => { | ||||
|   t.afterEach(() => { | ||||
|     sinon.restore() | ||||
|   }) | ||||
|  | ||||
|   await t.test('succeeds', async (t) => { | ||||
|   await t.test('succeeds', async () => { | ||||
|     sinon.stub(prisma, 'user').value({ | ||||
|       findFirst: async () => { | ||||
|         return userExample | ||||
| @@ -26,10 +28,10 @@ await tap.test('GET /users/confirm-email', async (t) => { | ||||
|         temporaryToken: userExample.temporaryToken ?? '' | ||||
|       } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 200) | ||||
|     assert.strictEqual(response.statusCode, 200) | ||||
|   }) | ||||
|  | ||||
|   await t.test('should fails with invalid `temporaryToken`', async (t) => { | ||||
|   await t.test('should fails with invalid `temporaryToken`', async () => { | ||||
|     sinon.stub(prisma, 'user').value({ | ||||
|       findFirst: async () => { | ||||
|         return null | ||||
| @@ -45,6 +47,6 @@ await tap.test('GET /users/confirm-email', async (t) => { | ||||
|         temporaryToken: userExample.temporaryToken ?? '' | ||||
|       } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 403) | ||||
|     assert.strictEqual(response.statusCode, 403) | ||||
|   }) | ||||
| }) | ||||
|   | ||||
| @@ -2,9 +2,9 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import prisma from '../../../tools/database/prisma.js' | ||||
| import { fastifyErrors } from '../../../models/utils.js' | ||||
| import { userSchema } from '../../../models/User.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import { userSchema } from '#src/models/User.js' | ||||
|  | ||||
| const queryGetConfirmEmailSchema = Type.Object({ | ||||
|   redirectURI: Type.Optional(Type.String({ format: 'uri-reference' })), | ||||
|   | ||||
| @@ -1,15 +1,17 @@ | ||||
| import tap from 'tap' | ||||
| import test from 'node:test' | ||||
| import assert from 'node:assert/strict' | ||||
|  | ||||
| import sinon from 'sinon' | ||||
|  | ||||
| import { application } from '../../../../application.js' | ||||
| import { authenticateUserTest } from '../../../../__test__/utils/authenticateUserTest.js' | ||||
| import { application } from '#src/application.js' | ||||
| import { authenticateUserTest } from '#src/__test__/utils/authenticateUserTest.js' | ||||
|  | ||||
| await tap.test('GET /users/current', async (t) => { | ||||
| await test('GET /users/current', async (t) => { | ||||
|   t.afterEach(() => { | ||||
|     sinon.restore() | ||||
|   }) | ||||
|  | ||||
|   await t.test('succeeds', async (t) => { | ||||
|   await t.test('succeeds', async () => { | ||||
|     const { accessToken, user } = await authenticateUserTest() | ||||
|     const response = await application.inject({ | ||||
|       method: 'GET', | ||||
| @@ -19,16 +21,16 @@ await tap.test('GET /users/current', async (t) => { | ||||
|       } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 200) | ||||
|     t.equal(responseJson.user.name, user.name) | ||||
|     t.strictSame(responseJson.user.strategies, ['Local']) | ||||
|     assert.strictEqual(response.statusCode, 200) | ||||
|     assert.strictEqual(responseJson.user.name, user.name) | ||||
|     assert.deepStrictEqual(responseJson.user.strategies, ['Local']) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails with unauthenticated user', async (t) => { | ||||
|   await t.test('fails with unauthenticated user', async () => { | ||||
|     const response = await application.inject({ | ||||
|       method: 'GET', | ||||
|       url: '/users/current' | ||||
|     }) | ||||
|     t.equal(response.statusCode, 401) | ||||
|     assert.strictEqual(response.statusCode, 401) | ||||
|   }) | ||||
| }) | ||||
|   | ||||
| @@ -1,16 +1,18 @@ | ||||
| import tap from 'tap' | ||||
| import test from 'node:test' | ||||
| import assert from 'node:assert/strict' | ||||
|  | ||||
| import sinon from 'sinon' | ||||
|  | ||||
| import { application } from '../../../../application.js' | ||||
| import prisma from '../../../../tools/database/prisma.js' | ||||
| import { authenticateUserTest } from '../../../../__test__/utils/authenticateUserTest.js' | ||||
| import { application } from '#src/application.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { authenticateUserTest } from '#src/__test__/utils/authenticateUserTest.js' | ||||
|  | ||||
| await tap.test('PUT /users/current', async (t) => { | ||||
| await test('PUT /users/current', async (t) => { | ||||
|   t.afterEach(() => { | ||||
|     sinon.restore() | ||||
|   }) | ||||
|  | ||||
|   await t.test('succeeds with valid accessToken and valid name', async (t) => { | ||||
|   await t.test('succeeds with valid accessToken and valid name', async () => { | ||||
|     const newName = 'John Doe' | ||||
|     const { accessToken, user, userStubValue } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'user').value({ | ||||
| @@ -36,11 +38,11 @@ await tap.test('PUT /users/current', async (t) => { | ||||
|       } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 200) | ||||
|     t.equal(responseJson.user.name, newName) | ||||
|     assert.strictEqual(response.statusCode, 200) | ||||
|     assert.strictEqual(responseJson.user.name, newName) | ||||
|   }) | ||||
|  | ||||
|   await t.test('succeeds and only update the status', async (t) => { | ||||
|   await t.test('succeeds and only update the status', async () => { | ||||
|     const newStatus = '👀 Working on secret projects...' | ||||
|     const { accessToken, user, userStubValue } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'user').value({ | ||||
| @@ -66,12 +68,12 @@ await tap.test('PUT /users/current', async (t) => { | ||||
|       } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 200) | ||||
|     t.equal(responseJson.user.name, user.name) | ||||
|     t.equal(responseJson.user.status, newStatus) | ||||
|     assert.strictEqual(response.statusCode, 200) | ||||
|     assert.strictEqual(responseJson.user.name, user.name) | ||||
|     assert.strictEqual(responseJson.user.status, newStatus) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails with name already used', async (t) => { | ||||
|   await t.test('fails with name already used', async () => { | ||||
|     const newName = 'John Doe' | ||||
|     const { accessToken, user, userStubValue } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'user').value({ | ||||
| @@ -90,10 +92,10 @@ await tap.test('PUT /users/current', async (t) => { | ||||
|         name: newName | ||||
|       } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 400) | ||||
|     assert.strictEqual(response.statusCode, 400) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails with invalid website url', async (t) => { | ||||
|   await t.test('fails with invalid website url', async () => { | ||||
|     const newWebsite = 'invalid website url' | ||||
|     const { accessToken } = await authenticateUserTest() | ||||
|     const response = await application.inject({ | ||||
| @@ -106,10 +108,10 @@ await tap.test('PUT /users/current', async (t) => { | ||||
|         website: newWebsite | ||||
|       } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 400) | ||||
|     assert.strictEqual(response.statusCode, 400) | ||||
|   }) | ||||
|  | ||||
|   await t.test('succeeds with valid website url', async (t) => { | ||||
|   await t.test('succeeds with valid website url', async () => { | ||||
|     const newWebsite = 'https://somerandomwebsite.com' | ||||
|     const { accessToken, user, userStubValue } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'user').value({ | ||||
| @@ -135,8 +137,8 @@ await tap.test('PUT /users/current', async (t) => { | ||||
|       } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 200) | ||||
|     t.equal(responseJson.user.name, user.name) | ||||
|     t.equal(responseJson.user.website, newWebsite) | ||||
|     assert.strictEqual(response.statusCode, 200) | ||||
|     assert.strictEqual(responseJson.user.name, user.name) | ||||
|     assert.strictEqual(responseJson.user.website, newWebsite) | ||||
|   }) | ||||
| }) | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import prisma from '../../../tools/database/prisma.js' | ||||
| import { fastifyErrors } from '../../../models/utils.js' | ||||
| import authenticateUser from '../../../tools/plugins/authenticateUser.js' | ||||
| import { userCurrentSchema } from '../../../models/User.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
| import { userCurrentSchema } from '#src/models/User.js' | ||||
|  | ||||
| const getCurrentUserSchema: FastifySchema = { | ||||
|   description: 'GET the current connected user', | ||||
|   | ||||
| @@ -2,10 +2,10 @@ import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
| import fastifyMultipart from '@fastify/multipart' | ||||
|  | ||||
| import authenticateUser from '../../../../tools/plugins/authenticateUser.js' | ||||
| import { fastifyErrors } from '../../../../models/utils.js' | ||||
| import prisma from '../../../../tools/database/prisma.js' | ||||
| import { uploadFile } from '../../../../tools/utils/uploadFile.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { uploadFile } from '#src/tools/utils/uploadFile.js' | ||||
|  | ||||
| const putServiceSchema: FastifySchema = { | ||||
|   description: 'Edit the current connected user logo', | ||||
|   | ||||
| @@ -4,14 +4,14 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import prisma from '../../../tools/database/prisma.js' | ||||
| import { fastifyErrors } from '../../../models/utils.js' | ||||
| import authenticateUser from '../../../tools/plugins/authenticateUser.js' | ||||
| import { userCurrentSchema, userSchema } from '../../../models/User.js' | ||||
| import { sendEmail } from '../../../tools/email/sendEmail.js' | ||||
| import { API_URL } from '../../../tools/configurations.js' | ||||
| import type { Language, Theme } from '../../../models/UserSettings.js' | ||||
| import { parseStringNullish } from '../../../tools/utils/parseStringNullish.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
| import { userCurrentSchema, userSchema } from '#src/models/User.js' | ||||
| import { sendEmail } from '#src/tools/email/sendEmail.js' | ||||
| import { API_URL } from '#src/tools/configurations.js' | ||||
| import type { Language, Theme } from '#src/models/UserSettings.js' | ||||
| import { parseStringNullish } from '#src/tools/utils/parseStringNullish.js' | ||||
|  | ||||
| const bodyPutServiceSchema = Type.Object({ | ||||
|   name: Type.Optional(userSchema.name), | ||||
|   | ||||
| @@ -1,19 +1,21 @@ | ||||
| import tap from 'tap' | ||||
| import test from 'node:test' | ||||
| import assert from 'node:assert/strict' | ||||
|  | ||||
| import sinon from 'sinon' | ||||
|  | ||||
| import { application } from '../../../../../application.js' | ||||
| import { authenticateUserTest } from '../../../../../__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '../../../../../tools/database/prisma.js' | ||||
| import { userSettingsExample } from '../../../../../models/UserSettings.js' | ||||
| import { application } from '#src/application.js' | ||||
| import { authenticateUserTest } from '#src/__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { userSettingsExample } from '#src/models/UserSettings.js' | ||||
|  | ||||
| await tap.test('PUT /users/current/settings', async (t) => { | ||||
| await test('PUT /users/current/settings', async (t) => { | ||||
|   t.afterEach(() => { | ||||
|     sinon.restore() | ||||
|   }) | ||||
|  | ||||
|   await t.test( | ||||
|     'succeeds and edit the theme, language, isPublicEmail and isPublicGuilds', | ||||
|     async (t) => { | ||||
|     async () => { | ||||
|       const newSettings = { | ||||
|         theme: 'light', | ||||
|         language: 'fr', | ||||
| @@ -42,15 +44,21 @@ await tap.test('PUT /users/current/settings', async (t) => { | ||||
|         payload: newSettings | ||||
|       }) | ||||
|       const responseJson = response.json() | ||||
|       t.equal(response.statusCode, 200) | ||||
|       t.equal(responseJson.settings.theme, newSettings.theme) | ||||
|       t.equal(responseJson.settings.language, newSettings.language) | ||||
|       t.equal(responseJson.settings.isPublicEmail, newSettings.isPublicEmail) | ||||
|       t.equal(responseJson.settings.isPublicGuilds, newSettings.isPublicGuilds) | ||||
|       assert.strictEqual(response.statusCode, 200) | ||||
|       assert.strictEqual(responseJson.settings.theme, newSettings.theme) | ||||
|       assert.strictEqual(responseJson.settings.language, newSettings.language) | ||||
|       assert.strictEqual( | ||||
|         responseJson.settings.isPublicEmail, | ||||
|         newSettings.isPublicEmail | ||||
|       ) | ||||
|       assert.strictEqual( | ||||
|         responseJson.settings.isPublicGuilds, | ||||
|         newSettings.isPublicGuilds | ||||
|       ) | ||||
|     } | ||||
|   ) | ||||
|  | ||||
|   await t.test('fails with invalid language', async (t) => { | ||||
|   await t.test('fails with invalid language', async () => { | ||||
|     const newSettings = { | ||||
|       language: 'somerandomlanguage' | ||||
|     } | ||||
| @@ -75,6 +83,6 @@ await tap.test('PUT /users/current/settings', async (t) => { | ||||
|       }, | ||||
|       payload: newSettings | ||||
|     }) | ||||
|     t.equal(response.statusCode, 400) | ||||
|     assert.strictEqual(response.statusCode, 400) | ||||
|   }) | ||||
| }) | ||||
|   | ||||
| @@ -2,10 +2,10 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import prisma from '../../../../tools/database/prisma.js' | ||||
| import { fastifyErrors } from '../../../../models/utils.js' | ||||
| import authenticateUser from '../../../../tools/plugins/authenticateUser.js' | ||||
| import { userSettingsSchema } from '../../../../models/UserSettings.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
| import { userSettingsSchema } from '#src/models/UserSettings.js' | ||||
|  | ||||
| const bodyPutServiceSchema = Type.Object({ | ||||
|   theme: Type.Optional(userSettingsSchema.theme), | ||||
|   | ||||
| @@ -2,10 +2,10 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import prisma from '../../../../tools/database/prisma.js' | ||||
| import { fastifyErrors } from '../../../../models/utils.js' | ||||
| import authenticateUser from '../../../../tools/plugins/authenticateUser.js' | ||||
| import { oauthSchema } from '../../../../models/OAuth.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
| import { oauthSchema } from '#src/models/OAuth.js' | ||||
|  | ||||
| const parametersSchema = Type.Object({ | ||||
|   provider: oauthSchema.provider | ||||
| @@ -45,8 +45,8 @@ export const deleteProviderService: FastifyPluginAsync = async (fastify) => { | ||||
|       if (request.user == null) { | ||||
|         throw fastify.httpErrors.forbidden() | ||||
|       } | ||||
|       const { user } = request | ||||
|       const { provider } = request.params | ||||
|       const { user, params } = request | ||||
|       const { provider } = params | ||||
|       const OAuths = await prisma.oAuth.findMany({ | ||||
|         where: { userId: user.current.id } | ||||
|       }) | ||||
|   | ||||
| @@ -2,7 +2,7 @@ import querystring from 'node:querystring' | ||||
|  | ||||
| import axios from 'axios' | ||||
|  | ||||
| import { OAuthStrategy } from '../../../../../tools/utils/OAuthStrategy.js' | ||||
| import { OAuthStrategy } from '#src/tools/utils/OAuthStrategy.js' | ||||
|  | ||||
| export const DISCORD_PROVIDER = 'Discord' | ||||
| export const DISCORD_BASE_URL = 'https://discord.com/api/v10' | ||||
|   | ||||
| @@ -2,10 +2,10 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import { API_URL } from '../../../../../tools/configurations.js' | ||||
| import { fastifyErrors } from '../../../../../models/utils.js' | ||||
| import { API_URL } from '#src/tools/configurations.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import { DISCORD_BASE_URL, DISCORD_CLIENT_ID } from '../__utils__/utils.js' | ||||
| import authenticateUser from '../../../../../tools/plugins/authenticateUser.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
|  | ||||
| const querySchema = Type.Object({ | ||||
|   redirectURI: Type.String({ format: 'uri-reference' }) | ||||
|   | ||||
| @@ -2,11 +2,11 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import { API_URL } from '../../../../../tools/configurations.js' | ||||
| import { fastifyErrors } from '../../../../../models/utils.js' | ||||
| import { API_URL } from '#src/tools/configurations.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import { discordStrategy, getDiscordUserData } from '../__utils__/utils.js' | ||||
| import { buildQueryURL } from '../../../../../tools/utils/buildQueryURL.js' | ||||
| import { getUserWithBearerToken } from '../../../../../tools/plugins/authenticateUser.js' | ||||
| import { buildQueryURL } from '#src/tools/utils/buildQueryURL.js' | ||||
| import { getUserWithBearerToken } from '#src/tools/plugins/authenticateUser.js' | ||||
|  | ||||
| const querySchema = Type.Object({ | ||||
|   code: Type.String(), | ||||
|   | ||||
| @@ -2,10 +2,10 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import { API_URL } from '../../../../../tools/configurations.js' | ||||
| import { fastifyErrors } from '../../../../../models/utils.js' | ||||
| import { API_URL } from '#src/tools/configurations.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import { discordStrategy, getDiscordUserData } from '../__utils__/utils.js' | ||||
| import { buildQueryURL } from '../../../../../tools/utils/buildQueryURL.js' | ||||
| import { buildQueryURL } from '#src/tools/utils/buildQueryURL.js' | ||||
|  | ||||
| const querySchema = Type.Object({ | ||||
|   code: Type.String(), | ||||
|   | ||||
| @@ -2,8 +2,8 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import { API_URL } from '../../../../../tools/configurations.js' | ||||
| import { fastifyErrors } from '../../../../../models/utils.js' | ||||
| import { API_URL } from '#src/tools/configurations.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import { DISCORD_BASE_URL, DISCORD_CLIENT_ID } from '../__utils__/utils.js' | ||||
|  | ||||
| const querySchema = Type.Object({ | ||||
|   | ||||
| @@ -2,7 +2,7 @@ import querystring from 'node:querystring' | ||||
|  | ||||
| import axios from 'axios' | ||||
|  | ||||
| import { OAuthStrategy } from '../../../../../tools/utils/OAuthStrategy.js' | ||||
| import { OAuthStrategy } from '#src/tools/utils/OAuthStrategy.js' | ||||
|  | ||||
| export const GITHUB_PROVIDER = 'GitHub' | ||||
| export const GITHUB_BASE_URL = 'https://github.com' | ||||
|   | ||||
| @@ -2,10 +2,10 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import { API_URL } from '../../../../../tools/configurations.js' | ||||
| import { fastifyErrors } from '../../../../../models/utils.js' | ||||
| import { API_URL } from '#src/tools/configurations.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import { GITHUB_BASE_URL, GITHUB_CLIENT_ID } from '../__utils__/utils.js' | ||||
| import authenticateUser from '../../../../../tools/plugins/authenticateUser.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
|  | ||||
| const querySchema = Type.Object({ | ||||
|   redirectURI: Type.String({ format: 'uri-reference' }) | ||||
|   | ||||
| @@ -2,11 +2,11 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import { API_URL } from '../../../../../tools/configurations.js' | ||||
| import { fastifyErrors } from '../../../../../models/utils.js' | ||||
| import { API_URL } from '#src/tools/configurations.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import { githubStrategy, getGitHubUserData } from '../__utils__/utils.js' | ||||
| import { buildQueryURL } from '../../../../../tools/utils/buildQueryURL.js' | ||||
| import { getUserWithBearerToken } from '../../../../../tools/plugins/authenticateUser.js' | ||||
| import { buildQueryURL } from '#src/tools/utils/buildQueryURL.js' | ||||
| import { getUserWithBearerToken } from '#src/tools/plugins/authenticateUser.js' | ||||
|  | ||||
| const querySchema = Type.Object({ | ||||
|   code: Type.String(), | ||||
|   | ||||
| @@ -2,10 +2,10 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import { API_URL } from '../../../../../tools/configurations.js' | ||||
| import { fastifyErrors } from '../../../../../models/utils.js' | ||||
| import { API_URL } from '#src/tools/configurations.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import { githubStrategy, getGitHubUserData } from '../__utils__/utils.js' | ||||
| import { buildQueryURL } from '../../../../../tools/utils/buildQueryURL.js' | ||||
| import { buildQueryURL } from '#src/tools/utils/buildQueryURL.js' | ||||
|  | ||||
| const querySchema = Type.Object({ | ||||
|   code: Type.String(), | ||||
|   | ||||
| @@ -2,8 +2,8 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import { API_URL } from '../../../../../tools/configurations.js' | ||||
| import { fastifyErrors } from '../../../../../models/utils.js' | ||||
| import { API_URL } from '#src/tools/configurations.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import { GITHUB_BASE_URL, GITHUB_CLIENT_ID } from '../__utils__/utils.js' | ||||
|  | ||||
| const querySchema = Type.Object({ | ||||
|   | ||||
| @@ -2,7 +2,7 @@ import querystring from 'node:querystring' | ||||
|  | ||||
| import axios from 'axios' | ||||
|  | ||||
| import { OAuthStrategy } from '../../../../../tools/utils/OAuthStrategy.js' | ||||
| import { OAuthStrategy } from '#src/tools/utils/OAuthStrategy.js' | ||||
|  | ||||
| export const GOOGLE_PROVIDER = 'Google' | ||||
| export const GOOGLE_BASE_URL = 'https://accounts.google.com/o/oauth2/v2/auth' | ||||
|   | ||||
| @@ -2,10 +2,10 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import { API_URL } from '../../../../../tools/configurations.js' | ||||
| import { fastifyErrors } from '../../../../../models/utils.js' | ||||
| import { API_URL } from '#src/tools/configurations.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import { GOOGLE_BASE_URL, GOOGLE_CLIENT_ID } from '../__utils__/utils.js' | ||||
| import authenticateUser from '../../../../../tools/plugins/authenticateUser.js' | ||||
| import authenticateUser from '#src/tools/plugins/authenticateUser.js' | ||||
|  | ||||
| const querySchema = Type.Object({ | ||||
|   redirectURI: Type.String({ format: 'uri-reference' }) | ||||
|   | ||||
| @@ -2,11 +2,11 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import { API_URL } from '../../../../../tools/configurations.js' | ||||
| import { fastifyErrors } from '../../../../../models/utils.js' | ||||
| import { API_URL } from '#src/tools/configurations.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import { googleStrategy, getGoogleUserData } from '../__utils__/utils.js' | ||||
| import { buildQueryURL } from '../../../../../tools/utils/buildQueryURL.js' | ||||
| import { getUserWithBearerToken } from '../../../../../tools/plugins/authenticateUser.js' | ||||
| import { buildQueryURL } from '#src/tools/utils/buildQueryURL.js' | ||||
| import { getUserWithBearerToken } from '#src/tools/plugins/authenticateUser.js' | ||||
|  | ||||
| const querySchema = Type.Object({ | ||||
|   code: Type.String(), | ||||
|   | ||||
| @@ -2,10 +2,10 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import { API_URL } from '../../../../../tools/configurations.js' | ||||
| import { fastifyErrors } from '../../../../../models/utils.js' | ||||
| import { API_URL } from '#src/tools/configurations.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import { googleStrategy, getGoogleUserData } from '../__utils__/utils.js' | ||||
| import { buildQueryURL } from '../../../../../tools/utils/buildQueryURL.js' | ||||
| import { buildQueryURL } from '#src/tools/utils/buildQueryURL.js' | ||||
|  | ||||
| const querySchema = Type.Object({ | ||||
|   code: Type.String(), | ||||
|   | ||||
| @@ -2,8 +2,8 @@ import type { Static } from '@sinclair/typebox' | ||||
| import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
|  | ||||
| import { API_URL } from '../../../../../tools/configurations.js' | ||||
| import { fastifyErrors } from '../../../../../models/utils.js' | ||||
| import { API_URL } from '#src/tools/configurations.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import { GOOGLE_BASE_URL, GOOGLE_CLIENT_ID } from '../__utils__/utils.js' | ||||
|  | ||||
| const querySchema = Type.Object({ | ||||
|   | ||||
| @@ -1,19 +1,21 @@ | ||||
| import tap from 'tap' | ||||
| import test from 'node:test' | ||||
| import assert from 'node:assert/strict' | ||||
|  | ||||
| import sinon from 'sinon' | ||||
| import jwt from 'jsonwebtoken' | ||||
|  | ||||
| import { application } from '../../../../application.js' | ||||
| import { authenticateUserTest } from '../../../../__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '../../../../tools/database/prisma.js' | ||||
| import { refreshTokenExample } from '../../../../models/RefreshToken.js' | ||||
| import { expiresIn } from '../../../../tools/utils/jwtToken.js' | ||||
| import { application } from '#src/application.js' | ||||
| import { authenticateUserTest } from '#src/__test__/utils/authenticateUserTest.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { refreshTokenExample } from '#src/models/RefreshToken.js' | ||||
| import { expiresIn } from '#src/tools/utils/jwtToken.js' | ||||
|  | ||||
| await tap.test('POST /users/refresh-token', async (t) => { | ||||
| await test('POST /users/refresh-token', async (t) => { | ||||
|   t.afterEach(() => { | ||||
|     sinon.restore() | ||||
|   }) | ||||
|  | ||||
|   await t.test('succeeds', async (t) => { | ||||
|   await t.test('succeeds', async () => { | ||||
|     const { refreshToken, refreshTokenStubValue } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'refreshToken').value({ | ||||
|       ...refreshTokenStubValue, | ||||
| @@ -31,13 +33,13 @@ await tap.test('POST /users/refresh-token', async (t) => { | ||||
|       payload: { refreshToken } | ||||
|     }) | ||||
|     const responseJson = response.json() | ||||
|     t.equal(response.statusCode, 200) | ||||
|     t.equal(responseJson.type, 'Bearer') | ||||
|     t.equal(responseJson.expiresIn, expiresIn) | ||||
|     t.type(responseJson.accessToken, 'string') | ||||
|     assert.strictEqual(response.statusCode, 200) | ||||
|     assert.strictEqual(responseJson.type, 'Bearer') | ||||
|     assert.strictEqual(responseJson.expiresIn, expiresIn) | ||||
|     assert.strictEqual(typeof responseJson.accessToken, 'string') | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails with refreshToken not saved in database', async (t) => { | ||||
|   await t.test('fails with refreshToken not saved in database', async () => { | ||||
|     sinon.stub(prisma, 'refreshToken').value({ | ||||
|       findFirst: async () => { | ||||
|         return null | ||||
| @@ -48,10 +50,10 @@ await tap.test('POST /users/refresh-token', async (t) => { | ||||
|       url: '/users/refresh-token', | ||||
|       payload: { refreshToken: 'somerandomtoken' } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 403) | ||||
|     assert.strictEqual(response.statusCode, 403) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails with invalid jwt refreshToken', async (t) => { | ||||
|   await t.test('fails with invalid jwt refreshToken', async () => { | ||||
|     const { refreshToken, refreshTokenStubValue } = await authenticateUserTest() | ||||
|     sinon.stub(prisma, 'refreshToken').value({ | ||||
|       ...refreshTokenStubValue, | ||||
| @@ -67,6 +69,6 @@ await tap.test('POST /users/refresh-token', async (t) => { | ||||
|       url: '/users/refresh-token', | ||||
|       payload: { refreshToken } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 403) | ||||
|     assert.strictEqual(response.statusCode, 403) | ||||
|   }) | ||||
| }) | ||||
|   | ||||
| @@ -3,15 +3,15 @@ import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
| import jwt from 'jsonwebtoken' | ||||
|  | ||||
| import prisma from '../../../tools/database/prisma.js' | ||||
| import { fastifyErrors } from '../../../models/utils.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import { | ||||
|   generateAccessToken, | ||||
|   jwtSchema, | ||||
|   expiresIn | ||||
| } from '../../../tools/utils/jwtToken.js' | ||||
| import type { UserRefreshJWT } from '../../../models/User.js' | ||||
| import { JWT_REFRESH_SECRET } from '../../../tools/configurations.js' | ||||
| } from '#src/tools/utils/jwtToken.js' | ||||
| import type { UserRefreshJWT } from '#src/models/User.js' | ||||
| import { JWT_REFRESH_SECRET } from '#src/tools/configurations.js' | ||||
|  | ||||
| const bodyPostRefreshTokenSchema = Type.Object({ | ||||
|   refreshToken: jwtSchema.refreshToken | ||||
|   | ||||
| @@ -1,19 +1,21 @@ | ||||
| import tap from 'tap' | ||||
| import test from 'node:test' | ||||
| import assert from 'node:assert/strict' | ||||
|  | ||||
| import sinon from 'sinon' | ||||
| import ms from 'ms' | ||||
|  | ||||
| import { application } from '../../../../application.js' | ||||
| import prisma from '../../../../tools/database/prisma.js' | ||||
| import { userExample } from '../../../../models/User.js' | ||||
| import { userSettingsExample } from '../../../../models/UserSettings.js' | ||||
| import { emailTransporter } from '../../../../tools/email/emailTransporter.js' | ||||
| import { application } from '#src/application.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { userExample } from '#src/models/User.js' | ||||
| import { userSettingsExample } from '#src/models/UserSettings.js' | ||||
| import { emailTransporter } from '#src/tools/email/emailTransporter.js' | ||||
|  | ||||
| await tap.test('POST /users/reset-password', async (t) => { | ||||
| await test('POST /users/reset-password', async (t) => { | ||||
|   t.afterEach(() => { | ||||
|     sinon.restore() | ||||
|   }) | ||||
|  | ||||
|   await t.test('succeeds', async (t) => { | ||||
|   await t.test('succeeds', async () => { | ||||
|     sinon.stub(prisma, 'user').value({ | ||||
|       findUnique: async () => { | ||||
|         return userExample | ||||
| @@ -37,10 +39,10 @@ await tap.test('POST /users/reset-password', async (t) => { | ||||
|       url: '/users/reset-password?redirectURI=https://redirecturi.com', | ||||
|       payload: { email: userExample.email } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 200) | ||||
|     assert.strictEqual(response.statusCode, 200) | ||||
|   }) | ||||
|  | ||||
|   await t.test("fails with email that doesn't exist", async (t) => { | ||||
|   await t.test("fails with email that doesn't exist", async () => { | ||||
|     sinon.stub(prisma, 'user').value({ | ||||
|       findUnique: async () => { | ||||
|         return null | ||||
| @@ -51,10 +53,10 @@ await tap.test('POST /users/reset-password', async (t) => { | ||||
|       url: '/users/reset-password?redirectURI=https://redirecturi.com', | ||||
|       payload: { email: userExample.email } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 400) | ||||
|     assert.strictEqual(response.statusCode, 400) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails with unconfirmed account', async (t) => { | ||||
|   await t.test('fails with unconfirmed account', async () => { | ||||
|     sinon.stub(prisma, 'user').value({ | ||||
|       findUnique: async () => { | ||||
|         return { | ||||
| @@ -68,10 +70,10 @@ await tap.test('POST /users/reset-password', async (t) => { | ||||
|       url: '/users/reset-password?redirectURI=https://redirecturi.com', | ||||
|       payload: { email: userExample.email } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 400) | ||||
|     assert.strictEqual(response.statusCode, 400) | ||||
|   }) | ||||
|  | ||||
|   await t.test("fails if userSettings doesn't exist", async (t) => { | ||||
|   await t.test("fails if userSettings doesn't exist", async () => { | ||||
|     sinon.stub(prisma, 'user').value({ | ||||
|       findUnique: async () => { | ||||
|         return userExample | ||||
| @@ -87,10 +89,10 @@ await tap.test('POST /users/reset-password', async (t) => { | ||||
|       url: '/users/reset-password?redirectURI=https://redirecturi.com', | ||||
|       payload: { email: userExample.email } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 400) | ||||
|     assert.strictEqual(response.statusCode, 400) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails with a request already in progress', async (t) => { | ||||
|   await t.test('fails with a request already in progress', async () => { | ||||
|     sinon.stub(prisma, 'user').value({ | ||||
|       findUnique: async () => { | ||||
|         return { | ||||
| @@ -110,6 +112,6 @@ await tap.test('POST /users/reset-password', async (t) => { | ||||
|       url: '/users/reset-password?redirectURI=https://redirecturi.com', | ||||
|       payload: { email: userExample.email } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 400) | ||||
|     assert.strictEqual(response.statusCode, 400) | ||||
|   }) | ||||
| }) | ||||
|   | ||||
| @@ -1,17 +1,19 @@ | ||||
| import tap from 'tap' | ||||
| import test from 'node:test' | ||||
| import assert from 'node:assert/strict' | ||||
|  | ||||
| import sinon from 'sinon' | ||||
| import ms from 'ms' | ||||
|  | ||||
| import { application } from '../../../../application.js' | ||||
| import prisma from '../../../../tools/database/prisma.js' | ||||
| import { userExample } from '../../../../models/User.js' | ||||
| import { application } from '#src/application.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { userExample } from '#src/models/User.js' | ||||
|  | ||||
| await tap.test('PUT /users/reset-password', async (t) => { | ||||
| await test('PUT /users/reset-password', async (t) => { | ||||
|   t.afterEach(() => { | ||||
|     sinon.restore() | ||||
|   }) | ||||
|  | ||||
|   await t.test('succeeds', async (t) => { | ||||
|   await t.test('succeeds', async () => { | ||||
|     const temporaryToken = 'random-token' | ||||
|     sinon.stub(prisma, 'user').value({ | ||||
|       findFirst: async () => { | ||||
| @@ -38,10 +40,10 @@ await tap.test('PUT /users/reset-password', async (t) => { | ||||
|         temporaryToken: userExample.temporaryToken | ||||
|       } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 200) | ||||
|     assert.strictEqual(response.statusCode, 200) | ||||
|   }) | ||||
|  | ||||
|   await t.test('fails with expired temporaryToken', async (t) => { | ||||
|   await t.test('fails with expired temporaryToken', async () => { | ||||
|     const temporaryToken = 'random-token' | ||||
|     sinon.stub(prisma, 'user').value({ | ||||
|       findFirst: async () => { | ||||
| @@ -63,6 +65,6 @@ await tap.test('PUT /users/reset-password', async (t) => { | ||||
|         temporaryToken: userExample.temporaryToken | ||||
|       } | ||||
|     }) | ||||
|     t.equal(response.statusCode, 400) | ||||
|     assert.strictEqual(response.statusCode, 400) | ||||
|   }) | ||||
| }) | ||||
|   | ||||
| @@ -5,11 +5,11 @@ import { Type } from '@sinclair/typebox' | ||||
| import type { FastifyPluginAsync, FastifySchema } from 'fastify' | ||||
| import ms from 'ms' | ||||
|  | ||||
| import prisma from '../../../tools/database/prisma.js' | ||||
| import { fastifyErrors } from '../../../models/utils.js' | ||||
| import { userSchema } from '../../../models/User.js' | ||||
| import { sendEmail } from '../../../tools/email/sendEmail.js' | ||||
| import type { Language, Theme } from '../../../models/UserSettings.js' | ||||
| import prisma from '#src/tools/database/prisma.js' | ||||
| import { fastifyErrors } from '#src/models/utils.js' | ||||
| import { userSchema } from '#src/models/User.js' | ||||
| import { sendEmail } from '#src/tools/email/sendEmail.js' | ||||
| import type { Language, Theme } from '#src/models/UserSettings.js' | ||||
|  | ||||
| const queryPostResetPasswordSchema = Type.Object({ | ||||
|   redirectURI: Type.String({ format: 'uri-reference' }) | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user