mirror of
https://github.com/hknsh/project-knedita.git
synced 2024-11-28 17:41:15 +00:00
fixinit10
This commit is contained in:
commit
e214f59fca
30 changed files with 9325 additions and 0 deletions
4
.dockerignore
Normal file
4
.dockerignore
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
.env
|
||||||
|
node_modules/
|
||||||
|
.vscode/
|
||||||
|
client/
|
5
.editorconfig
Normal file
5
.editorconfig
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[*.js]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
17
.env.example
Normal file
17
.env.example
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# Postgres config
|
||||||
|
POSTGRES_DB=<placeholder>
|
||||||
|
POSTGRES_USER=<placeholder>
|
||||||
|
POSTGRES_PASSWORD=<placeholder>
|
||||||
|
# POSTGRES CONTAINER NAME
|
||||||
|
DB_HOST=postgres
|
||||||
|
|
||||||
|
# Use this instead if you want to use locally
|
||||||
|
# DB_HOST=localhost
|
||||||
|
|
||||||
|
DATABASE_URL=postgresql://<placeholder>:<placeholder>@${DB_HOST}:5432/${POSTGRES_DB}?schema=
|
||||||
|
|
||||||
|
# Express
|
||||||
|
SERVER_PORT=<placeholder>
|
||||||
|
|
||||||
|
# Security
|
||||||
|
JWT_ACCESS_SECRET=<placeholder>
|
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
.git
|
||||||
|
node_modules
|
||||||
|
.env
|
||||||
|
prisma/*.db
|
||||||
|
.DS_Store
|
||||||
|
prisma/migrations/dev
|
15
Dockerfile
Normal file
15
Dockerfile
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
FROM node:16 as builder
|
||||||
|
|
||||||
|
# Create app dir
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY package*.json ./
|
||||||
|
COPY prisma ./prisma/
|
||||||
|
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
CMD ["npm", "run", "prod:start"]
|
21
LICENSE
Normal file
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2023 CookieDasora
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
1
README.md
Normal file
1
README.md
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# Social Media - Unnamed
|
17
docker-compose.db.yml
Normal file
17
docker-compose.db.yml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres:alpine
|
||||||
|
restart: unless-stopped
|
||||||
|
container_name: postgres
|
||||||
|
ports:
|
||||||
|
- 5432:5432
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
volumes:
|
||||||
|
- postgres:/var/lib/postgresql/data
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
postgres:
|
||||||
|
name: backend-db
|
30
docker-compose.yml
Normal file
30
docker-compose.yml
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
api:
|
||||||
|
container_name: api
|
||||||
|
restart: unless-stopped
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
ports:
|
||||||
|
- 8080:8080
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
|
||||||
|
postgres:
|
||||||
|
image: postgres:alpine
|
||||||
|
restart: unless-stopped
|
||||||
|
container_name: postgres
|
||||||
|
ports:
|
||||||
|
- 5432:5432
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
volumes:
|
||||||
|
- postgres:/var/lib/postgresql/data
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
postgres:
|
||||||
|
name: backend-db
|
8716
package-lock.json
generated
Normal file
8716
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
46
package.json
Normal file
46
package.json
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
{
|
||||||
|
"name": "social-media-app",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"description": "A social media",
|
||||||
|
"main": "src/server.js",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev:start": "nodemon src/server.js",
|
||||||
|
"docker": "docker compose up -d",
|
||||||
|
"docker:build": "docker build -t api . && docker compose up -d",
|
||||||
|
"docker:db": "docker compose -f docker-compose.db.yml up -d",
|
||||||
|
"docker:seed": "docker exec -it api npm run prisma:seed",
|
||||||
|
"migrate:dev": "prisma migrate dev",
|
||||||
|
"migrate:dev:create": "prisma migrate dev --create-only",
|
||||||
|
"migrate:reset": "prisma migrate reset",
|
||||||
|
"prisma:generate": "npx prisma generate",
|
||||||
|
"prisma:seed": "prisma db seed",
|
||||||
|
"prisma:studio": "npx prisma studio",
|
||||||
|
"prod:start": "pm2-runtime start src/server.js",
|
||||||
|
"test": "node --experimental-vm-modules --no-warnings node_modules/jest/bin/jest.js"
|
||||||
|
},
|
||||||
|
"standard": {
|
||||||
|
"ignore": [
|
||||||
|
"/src/tests/*.spec.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"author": "Cookie",
|
||||||
|
"license": "MIT",
|
||||||
|
"devDependencies": {
|
||||||
|
"jest": "^29.5.0",
|
||||||
|
"nodemon": "^2.0.22",
|
||||||
|
"pm2": "^5.3.0",
|
||||||
|
"prisma": "^4.16.0",
|
||||||
|
"standard": "^17.1.0",
|
||||||
|
"supertest": "^6.3.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@prisma/client": "^4.16.0",
|
||||||
|
"bcrypt": "^5.1.0",
|
||||||
|
"compression": "^1.7.4",
|
||||||
|
"dotenv": "^16.3.1",
|
||||||
|
"express": "^4.18.2",
|
||||||
|
"jsonwebtoken": "^9.0.0",
|
||||||
|
"validator": "^13.9.0"
|
||||||
|
}
|
||||||
|
}
|
11
prisma/Dockerfile
Normal file
11
prisma/Dockerfile
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
FROM node:14
|
||||||
|
RUN openssl version -v
|
||||||
|
RUN uname -a
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN npm install -g prisma --unsafe-perm
|
||||||
|
|
||||||
|
ADD . ./prisma/
|
||||||
|
|
||||||
|
CMD ["prisma", "migrate", "up"]
|
5
prisma/client.js
Normal file
5
prisma/client.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import { PrismaClient } from '@prisma/client'
|
||||||
|
|
||||||
|
const prisma = new PrismaClient()
|
||||||
|
|
||||||
|
export default prisma
|
17
prisma/migrations/20230620191117_init/migration.sql
Normal file
17
prisma/migrations/20230620191117_init/migration.sql
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "User" (
|
||||||
|
"id" TEXT NOT NULL,
|
||||||
|
"displayName" TEXT,
|
||||||
|
"username" TEXT NOT NULL,
|
||||||
|
"email" TEXT NOT NULL,
|
||||||
|
"password" TEXT NOT NULL,
|
||||||
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
|
||||||
|
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "User_username_key" ON "User"("username");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
|
3
prisma/migrations/migration_lock.toml
Normal file
3
prisma/migrations/migration_lock.toml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# Please do not edit this file manually
|
||||||
|
# It should be added in your version-control system (i.e. Git)
|
||||||
|
provider = "postgresql"
|
20
prisma/schema.prisma
Normal file
20
prisma/schema.prisma
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// This is your Prisma schema file,
|
||||||
|
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
||||||
|
|
||||||
|
generator client {
|
||||||
|
provider = "prisma-client-js"
|
||||||
|
}
|
||||||
|
|
||||||
|
datasource db {
|
||||||
|
provider = "postgresql"
|
||||||
|
url = env("DATABASE_URL")
|
||||||
|
}
|
||||||
|
|
||||||
|
model User {
|
||||||
|
id String @id @default(uuid())
|
||||||
|
displayName String?
|
||||||
|
username String @unique
|
||||||
|
email String @unique
|
||||||
|
password String
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
}
|
28
prisma/seed.js
Normal file
28
prisma/seed.js
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import { PrismaClient } from '@prisma/client'
|
||||||
|
|
||||||
|
const prisma = new PrismaClient()
|
||||||
|
|
||||||
|
async function main () {
|
||||||
|
await prisma.user.deleteMany({
|
||||||
|
where: {
|
||||||
|
username: 'cookie_'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log('Seeding database...')
|
||||||
|
|
||||||
|
await prisma.user.create({
|
||||||
|
data: {
|
||||||
|
displayName: 'Cookie_',
|
||||||
|
username: 'cookie_',
|
||||||
|
email: 'cookie@cookie.com',
|
||||||
|
password: '$2a$10$vBx5LkpZNMC3j1bHopUcp.ZcsMt5xfWlUJJGYIb4511aNccnHmMqi' // cookie
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
||||||
|
.catch((e) => console.error(e))
|
||||||
|
.finally(async () => {
|
||||||
|
await prisma.$disconnect()
|
||||||
|
})
|
20
src/app.js
Normal file
20
src/app.js
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import 'dotenv/config'
|
||||||
|
|
||||||
|
import express from 'express'
|
||||||
|
import router from './routes.js'
|
||||||
|
import compression from 'compression'
|
||||||
|
|
||||||
|
const app = express()
|
||||||
|
|
||||||
|
app.use(express.json())
|
||||||
|
app.use(express.urlencoded({ extended: true }))
|
||||||
|
app.use(router)
|
||||||
|
app.use(compression({ level: 9 }))
|
||||||
|
|
||||||
|
app.use((_req, res) => {
|
||||||
|
res.status(404).json({
|
||||||
|
error: 'Not found'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
export default app
|
17
src/controllers/user-auth.js
Normal file
17
src/controllers/user-auth.js
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import userAuthService from '../services/user-auth.js'
|
||||||
|
|
||||||
|
async function userAuthController (req, res) {
|
||||||
|
const { email, password } = req.body
|
||||||
|
|
||||||
|
const result = await userAuthService({ email, password })
|
||||||
|
|
||||||
|
if (result instanceof Error) {
|
||||||
|
return res.status(400).json({
|
||||||
|
error: result.message
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default userAuthController
|
15
src/controllers/user-info.js
Normal file
15
src/controllers/user-info.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import userInfoService from '../services/user-info.js'
|
||||||
|
|
||||||
|
async function userInfoController (req, res) {
|
||||||
|
const result = await userInfoService(req)
|
||||||
|
|
||||||
|
if (result instanceof Error) {
|
||||||
|
return res.status(400).json({
|
||||||
|
error: result.message
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default userInfoController
|
17
src/controllers/user-signup.js
Normal file
17
src/controllers/user-signup.js
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import userSignupService from '../services/user-signup.js'
|
||||||
|
|
||||||
|
async function userSignupController (req, res) {
|
||||||
|
const { username, email, password } = req.body
|
||||||
|
|
||||||
|
const result = await userSignupService({ username, email, password })
|
||||||
|
|
||||||
|
if (result instanceof Error) {
|
||||||
|
return res.status(400).json({
|
||||||
|
error: result.message
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.json(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default userSignupController
|
38
src/middlewares/ensure-authenticated.js
Normal file
38
src/middlewares/ensure-authenticated.js
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
import jsonwebtoken from 'jsonwebtoken'
|
||||||
|
import prisma from '../../prisma/client.js'
|
||||||
|
|
||||||
|
function ensureAuthenticated (req, res, next) {
|
||||||
|
if (!req.headers.authorization || req.headers.authorization.length === 0) {
|
||||||
|
return res.status(401).json({
|
||||||
|
error: 'Missing token'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const token = req.headers.authorization.split(' ')[1]
|
||||||
|
|
||||||
|
jsonwebtoken.verify(token, process.env.JWT_ACCESS_SECRET, async (err, decoded) => {
|
||||||
|
if (err || !decoded) {
|
||||||
|
return res.status(401).json({
|
||||||
|
error: err.message
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = await prisma.user.findFirst({
|
||||||
|
where: {
|
||||||
|
id: decoded.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
return res.status(401).json({
|
||||||
|
error: 'Invalid user'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
req.user = decoded
|
||||||
|
|
||||||
|
return next()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ensureAuthenticated
|
14
src/routes.js
Normal file
14
src/routes.js
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import { Router } from 'express'
|
||||||
|
|
||||||
|
import userSignupController from './controllers/user-signup.js'
|
||||||
|
import userAuthController from './controllers/user-auth.js'
|
||||||
|
import userInfoController from './controllers/user-info.js'
|
||||||
|
import ensureAuthenticated from './middlewares/ensure-authenticated.js'
|
||||||
|
|
||||||
|
const router = Router()
|
||||||
|
|
||||||
|
router.post('/user/create', userSignupController)
|
||||||
|
router.post('/user/auth', userAuthController)
|
||||||
|
router.get('/user/info', ensureAuthenticated, userInfoController)
|
||||||
|
|
||||||
|
export default router
|
5
src/server.js
Normal file
5
src/server.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import app from './app.js'
|
||||||
|
|
||||||
|
app.listen(process.env.SERVER_PORT, () => {
|
||||||
|
console.log(`Server is running @ ${process.env.SERVER_PORT}`)
|
||||||
|
})
|
35
src/services/user-auth.js
Normal file
35
src/services/user-auth.js
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import * as bcrypt from 'bcrypt'
|
||||||
|
import jsonwebtoken from 'jsonwebtoken'
|
||||||
|
import prisma from '../../prisma/client.js'
|
||||||
|
|
||||||
|
async function userAuthService ({ email, password }) {
|
||||||
|
const user = await prisma.user.findFirst({
|
||||||
|
where: {
|
||||||
|
email
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
return new Error('User does not exists')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (email === undefined || password === undefined) {
|
||||||
|
return new Error('Missing fields')
|
||||||
|
}
|
||||||
|
|
||||||
|
const validPassword = await bcrypt.compare(password, user.password)
|
||||||
|
|
||||||
|
if (validPassword === false) {
|
||||||
|
return new Error('Invalid email or password')
|
||||||
|
}
|
||||||
|
|
||||||
|
const { id } = user
|
||||||
|
|
||||||
|
const bearer = jsonwebtoken.sign({ id }, process.env.JWT_ACCESS_SECRET, { expiresIn: '1d' })
|
||||||
|
|
||||||
|
return {
|
||||||
|
token: bearer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default userAuthService
|
21
src/services/user-info.js
Normal file
21
src/services/user-info.js
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import prisma from '../../prisma/client.js'
|
||||||
|
|
||||||
|
async function userInfoService (req) {
|
||||||
|
const userId = req.user.id
|
||||||
|
|
||||||
|
const user = await prisma.user.findFirst({
|
||||||
|
where: {
|
||||||
|
id: userId
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
displayName: true,
|
||||||
|
username: true,
|
||||||
|
createdAt: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return user
|
||||||
|
}
|
||||||
|
|
||||||
|
export default userInfoService
|
40
src/services/user-signup.js
Normal file
40
src/services/user-signup.js
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
import * as bcrypt from 'bcrypt'
|
||||||
|
import prisma from '../../prisma/client.js'
|
||||||
|
|
||||||
|
async function userSignupService ({ username, email, password }) {
|
||||||
|
if (!username || !email || !password) {
|
||||||
|
return new Error('Missing fields')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (/^[a-zA-Z0-9_]{5,15}$/.test(username) === false) {
|
||||||
|
return new Error('Username not allowed. Only alphanumerics characters (uppercase and lowercase words), underscore and it must be between 5 and 15 characters')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (await prisma.user.findFirst({ where: { username } })) {
|
||||||
|
return new Error('Username already in use')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (await prisma.user.findFirst({ where: { email } })) {
|
||||||
|
return new Error('Email already in use')
|
||||||
|
}
|
||||||
|
|
||||||
|
const salt = await bcrypt.genSalt(15)
|
||||||
|
const hashedPassword = await bcrypt.hash(password, salt)
|
||||||
|
|
||||||
|
const user = await prisma.user.create({
|
||||||
|
data: {
|
||||||
|
username,
|
||||||
|
email,
|
||||||
|
password: hashedPassword
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
username: true,
|
||||||
|
createdAt: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return user
|
||||||
|
}
|
||||||
|
|
||||||
|
export default userSignupService
|
51
src/tests/user-auth.spec.js
Normal file
51
src/tests/user-auth.spec.js
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
import request from 'supertest'
|
||||||
|
import prisma from '../../prisma/client.js'
|
||||||
|
import app from '../app.js'
|
||||||
|
|
||||||
|
describe('POST /user/auth', () => {
|
||||||
|
beforeAll(async () => {
|
||||||
|
await prisma.user.create({
|
||||||
|
data: {
|
||||||
|
username: 'test',
|
||||||
|
email: 'test@test.com',
|
||||||
|
password: 'pass'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
await prisma.user.deleteMany({
|
||||||
|
where: {
|
||||||
|
username: 'test'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
await prisma.$disconnect()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should respond with a error if the user does not exists', async () => {
|
||||||
|
const response = await request(app)
|
||||||
|
.post('/user/auth')
|
||||||
|
.send({
|
||||||
|
email: 'mm@mm.com',
|
||||||
|
password: 'aa'
|
||||||
|
}).expect(400)
|
||||||
|
expect(response.body).toHaveProperty('error')
|
||||||
|
expect(response.body.error).toBe('User does not exists')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should respond with a error if receive an invalid email or password', async () => {
|
||||||
|
const response = await request(app)
|
||||||
|
.post('/user/auth').send({
|
||||||
|
email: 'test@test.com',
|
||||||
|
password: 'haha'
|
||||||
|
}).expect(400)
|
||||||
|
expect(response.body).toHaveProperty('error')
|
||||||
|
expect(response.body.error).toBe('Invalid email or password')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should respond with a error if receive an empty body', async () => {
|
||||||
|
const response = await request(app).post('/user/auth').send({}).expect(400)
|
||||||
|
expect(response.body).toHaveProperty('error')
|
||||||
|
expect(response.body.error).toBe('Missing fields')
|
||||||
|
})
|
||||||
|
})
|
7
src/tests/user-info.spec.js
Normal file
7
src/tests/user-info.spec.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import request from 'supertest'
|
||||||
|
|
||||||
|
describe('POST /user/info', () => {
|
||||||
|
it('TODO', async () => {
|
||||||
|
|
||||||
|
})
|
||||||
|
})
|
83
src/tests/user-signup.spec.js
Normal file
83
src/tests/user-signup.spec.js
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
import request from 'supertest'
|
||||||
|
import prisma from '../../prisma/client.js'
|
||||||
|
import app from '../app.js'
|
||||||
|
|
||||||
|
const mockUser = {
|
||||||
|
username: 'username11',
|
||||||
|
email: 'random@email.com',
|
||||||
|
password: 'totallysafepass'
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('POST /user/create', () => {
|
||||||
|
it('should respond with a 200 status code', async () => {
|
||||||
|
const response = await request(app).post('/user/create').send(mockUser).expect(200)
|
||||||
|
|
||||||
|
expect(response.body).toHaveProperty('id')
|
||||||
|
expect(response.body).toHaveProperty('username')
|
||||||
|
expect(response.body).toHaveProperty('createdAt')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should respond with a 400 status code if sent any invalid data', async () => {
|
||||||
|
await request(app).post('/user/create').send({
|
||||||
|
username: 'username12@',
|
||||||
|
email: mockUser.email,
|
||||||
|
password: mockUser.password
|
||||||
|
}).expect(400)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should respond with a 400 status code for an existing username', async () => {
|
||||||
|
await prisma.user.create({
|
||||||
|
data: {
|
||||||
|
username: 'username12',
|
||||||
|
email: 'user@email.com',
|
||||||
|
password: 'reallystrongpass'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const response = await request(app).post('/user/create').send({
|
||||||
|
username: 'username12',
|
||||||
|
email: 'user1@email.com',
|
||||||
|
password: 'reallystrongpass'
|
||||||
|
}).expect(400)
|
||||||
|
|
||||||
|
expect(response.body).toHaveProperty('error')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should respond with a 400 status code for an existing email', async () => {
|
||||||
|
await prisma.user.create({
|
||||||
|
data: {
|
||||||
|
username: 'username13',
|
||||||
|
email: 'user13@email.com',
|
||||||
|
password: '1234'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const response = await request(app).post('/user/create').send({
|
||||||
|
username: 'heythatscool',
|
||||||
|
email: 'user13@email.com',
|
||||||
|
password: '12345'
|
||||||
|
}).expect(400)
|
||||||
|
|
||||||
|
expect(response.body).toHaveProperty('error')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should respond with a 400 status code if receive an empty body', async () => {
|
||||||
|
const response = await request(app).post('/user/create').send({}).expect(400)
|
||||||
|
|
||||||
|
expect(response.body).toHaveProperty('error')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
const usersToDelete = ['username11', 'username12', 'username13']
|
||||||
|
|
||||||
|
await prisma.user.deleteMany({
|
||||||
|
where: {
|
||||||
|
username: {
|
||||||
|
in: usersToDelete
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
await prisma.$disconnect()
|
||||||
|
})
|
Loading…
Reference in a new issue