mirror of
https://github.com/hknsh/project-knedita.git
synced 2024-11-28 09:31:16 +00:00
Added Cookies for authentication.
This commit is contained in:
parent
ffcb719da1
commit
2607bd56ff
35 changed files with 113 additions and 5152 deletions
|
@ -1,17 +0,0 @@
|
|||
import { pathsToModuleNameMapper } from 'ts-jest'
|
||||
import { compilerOptions } from './tsconfig.json'
|
||||
import type { JestConfigWithTsJest } from 'ts-jest'
|
||||
|
||||
const jestConfig: JestConfigWithTsJest = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
setupFilesAfterEnv: ['<rootDir>/setupTest.ts'],
|
||||
transform: {
|
||||
'^.+\\.(t|j)sx?$': '@swc/jest'
|
||||
},
|
||||
roots: ['<rootDir>'],
|
||||
modulePaths: [compilerOptions.baseUrl],
|
||||
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths)
|
||||
}
|
||||
|
||||
export default jestConfig
|
4735
package-lock.json
generated
4735
package-lock.json
generated
File diff suppressed because it is too large
Load diff
11
package.json
11
package.json
|
@ -16,8 +16,7 @@
|
|||
"prisma:generate": "npx prisma generate",
|
||||
"prisma:seed": "prisma db seed",
|
||||
"prisma:studio": "npx prisma studio",
|
||||
"prod:start": "npx prisma migrate deploy && pm2-runtime start dist/server.js",
|
||||
"test": "jest"
|
||||
"prod:start": "npx prisma migrate deploy && pm2-runtime start dist/server.js"
|
||||
},
|
||||
"ts-standard": {
|
||||
"project": "tsconfig.json",
|
||||
|
@ -32,13 +31,12 @@
|
|||
"@faker-js/faker": "^8.0.2",
|
||||
"@swc/cli": "^0.1.62",
|
||||
"@swc/core": "^1.3.66",
|
||||
"@swc/jest": "^0.2.26",
|
||||
"@types/bcrypt": "^5.0.0",
|
||||
"@types/compression": "^1.7.2",
|
||||
"@types/cookie-parser": "^1.4.3",
|
||||
"@types/cors": "^2.8.13",
|
||||
"@types/dotenv": "^8.2.0",
|
||||
"@types/express": "^4.17.17",
|
||||
"@types/jest": "^29.5.2",
|
||||
"@types/jsonwebtoken": "^9.0.2",
|
||||
"@types/morgan": "^1.9.4",
|
||||
"@types/multer-s3": "^3.0.0",
|
||||
|
@ -53,13 +51,11 @@
|
|||
"eslint-plugin-import": "^2.28.0",
|
||||
"eslint-plugin-n": "^16.0.1",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"jest": "^29.6.2",
|
||||
"nodemon": "^3.0.1",
|
||||
"pm2": "^4.2.3",
|
||||
"prettier": "^3.0.0",
|
||||
"prisma": "^5.0.0",
|
||||
"supertest": "^6.3.3",
|
||||
"ts-jest": "^29.1.0",
|
||||
"ts-node-dev": "^2.0.0",
|
||||
"tsconfig-paths": "^4.2.0",
|
||||
"typescript": "^5.1.6"
|
||||
|
@ -69,6 +65,7 @@
|
|||
"aws-sdk": "^2.1414.0",
|
||||
"bcrypt": "^5.1.0",
|
||||
"compression": "^1.7.4",
|
||||
"cookie-parser": "^1.4.6",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.3.1",
|
||||
"express": "^4.18.2",
|
||||
|
@ -85,4 +82,4 @@
|
|||
"validator": "^13.9.0",
|
||||
"winston": "^3.10.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
import prisma from './src/clients/prisma-client'
|
||||
import redis from './src/clients/redis-client'
|
||||
|
||||
process.env.NODE_ENV = 'development'
|
||||
|
||||
afterAll(async () => {
|
||||
await redis.disconnect()
|
||||
await prisma.$disconnect()
|
||||
})
|
4
src/@types/express.d.ts
vendored
4
src/@types/express.d.ts
vendored
|
@ -1,12 +1,8 @@
|
|||
/* eslint-disable */
|
||||
import * as express from 'express'
|
||||
import type jwtPayload from '../interfaces/jwt'
|
||||
|
||||
declare global {
|
||||
namespace Express {
|
||||
interface Request {
|
||||
user: jwtPayload | undefined
|
||||
}
|
||||
namespace Multer {
|
||||
interface File {
|
||||
location: string
|
||||
|
|
|
@ -6,6 +6,7 @@ import express from 'express'
|
|||
import limiter from 'middlewares/rate-limit'
|
||||
import morganMiddleware from 'middlewares/morgan'
|
||||
import router from './routes'
|
||||
import cookieParser from 'cookie-parser'
|
||||
|
||||
const app = express()
|
||||
|
||||
|
@ -16,6 +17,7 @@ const app = express()
|
|||
|
||||
app.use(express.json())
|
||||
app.use(express.urlencoded({ extended: true }))
|
||||
app.use(cookieParser())
|
||||
app.use(morganMiddleware)
|
||||
app.use(limiter)
|
||||
app.use(router)
|
||||
|
|
|
@ -15,7 +15,7 @@ const storageTypes = {
|
|||
filename: (req: Request, file: Express.Multer.File, callback) => {
|
||||
/* eslint-disable */
|
||||
const folder = req.body.isProfilePicture ? 'profile_images' : 'media'
|
||||
const fileName: string = `${folder}/${req.user!.id}.webp`
|
||||
const fileName: string = `${folder}/${req.res?.locals.user.id}.webp`
|
||||
|
||||
callback(null, fileName)
|
||||
},
|
||||
|
@ -35,7 +35,7 @@ const storageTypes = {
|
|||
folder = 'media'
|
||||
}
|
||||
|
||||
const fileName: string = `${folder}/${req.user!.id}.jpg`
|
||||
const fileName: string = `${folder}/${req.res?.locals.user.id}.jpg`
|
||||
callback(null, fileName)
|
||||
},
|
||||
}),
|
||||
|
|
|
@ -8,7 +8,7 @@ async function commentCreateController (
|
|||
res: Response
|
||||
): Promise<void> {
|
||||
const { content, postId } = req.body
|
||||
const id = req.user?.id ?? ''
|
||||
const id = res.locals.user.id
|
||||
|
||||
if (postId === undefined) {
|
||||
badRequest(res, 'Expected post id'); return
|
||||
|
|
|
@ -8,7 +8,7 @@ async function commentDeleteController (
|
|||
res: Response
|
||||
): Promise<void> {
|
||||
const { commentId } = req.body
|
||||
const id = req.user?.id ?? ''
|
||||
const id = res.locals.user.id
|
||||
|
||||
if (commentId === undefined) {
|
||||
badRequest(res, 'Expected comment id'); return
|
||||
|
|
|
@ -8,7 +8,7 @@ async function commentUpdateController (
|
|||
res: Response
|
||||
): Promise<void> {
|
||||
const { commentId, content } = req.body
|
||||
const id = req.user?.id ?? ''
|
||||
const id = res.locals.user.id
|
||||
|
||||
if (commentId === undefined) {
|
||||
badRequest(res, 'Expected comment content'); return
|
||||
|
|
|
@ -8,7 +8,7 @@ async function postCreateController (
|
|||
res: Response
|
||||
): Promise<void> {
|
||||
const { content } = req.body
|
||||
const id: string = req.user?.id ?? ''
|
||||
const id = res.locals.user.id
|
||||
|
||||
if (content === undefined) {
|
||||
badRequest(res, 'Expected post content'); return
|
||||
|
|
|
@ -7,7 +7,7 @@ async function postDeleteController (
|
|||
req: Request,
|
||||
res: Response
|
||||
): Promise<void> {
|
||||
const userId = req.user?.id ?? ''
|
||||
const userId = res.locals.user.id
|
||||
const postId = req.body.postId
|
||||
|
||||
if (postId === undefined) {
|
||||
|
|
|
@ -7,7 +7,7 @@ async function postUpdateController (
|
|||
res: Response
|
||||
): Promise<void> {
|
||||
const { postId, content } = req.body
|
||||
const userId = req.user?.id ?? ''
|
||||
const userId = res.locals.user.id
|
||||
|
||||
const result = await post.update(postId, content, userId)
|
||||
|
||||
|
|
|
@ -1,13 +1,21 @@
|
|||
import user from 'services/users'
|
||||
import type { Request, Response } from 'express'
|
||||
import handleResponse from 'helpers/handle-response'
|
||||
import { badRequest } from 'helpers/http-errors'
|
||||
|
||||
async function userAuthController (req: Request, res: Response): Promise<void> {
|
||||
const { email, password } = req.body
|
||||
|
||||
const result = await user.auth({ email, password })
|
||||
|
||||
handleResponse(res, result)
|
||||
if (result instanceof Error) {
|
||||
badRequest(res, result.message)
|
||||
} else {
|
||||
res.cookie('token', result.token, {
|
||||
httpOnly: true,
|
||||
secure: process.env.NODE_ENV === 'production'
|
||||
}).status(200)
|
||||
.json({ message: 'Logged in successfully' })
|
||||
}
|
||||
}
|
||||
|
||||
export default userAuthController
|
||||
|
|
|
@ -6,7 +6,7 @@ async function userDeleteController (
|
|||
req: Request,
|
||||
res: Response
|
||||
): Promise<void> {
|
||||
const userId = req.user?.id ?? ''
|
||||
const userId = res.locals.user.id
|
||||
const result = await user.delete(userId)
|
||||
|
||||
handleResponse(res, result)
|
||||
|
|
|
@ -6,7 +6,7 @@ async function userFollowController (
|
|||
req: Request,
|
||||
res: Response
|
||||
): Promise<void> {
|
||||
const userId = req.user?.id ?? ''
|
||||
const userId = res.locals.user.id
|
||||
const { userToFollow } = req.body
|
||||
|
||||
const result = await user.follow(userId, userToFollow)
|
||||
|
|
|
@ -6,7 +6,7 @@ async function userLikeCommentController (
|
|||
req: Request,
|
||||
res: Response
|
||||
): Promise<void> {
|
||||
const userId = req.user?.id ?? ''
|
||||
const userId = res.locals.user.id
|
||||
const { commentId } = req.body
|
||||
|
||||
const result = await user.likeComment(commentId, userId)
|
||||
|
|
|
@ -6,7 +6,7 @@ async function userLikePostController (
|
|||
req: Request,
|
||||
res: Response
|
||||
): Promise<void> {
|
||||
const userId = req.user?.id ?? ''
|
||||
const userId = res.locals.user.id
|
||||
const { postId } = req.body
|
||||
|
||||
const result = await user.likePost(postId, userId)
|
||||
|
|
|
@ -7,7 +7,7 @@ async function userUpdateEmailController (
|
|||
res: Response
|
||||
): Promise<void> {
|
||||
const { email } = req.body
|
||||
const id = req.user?.id ?? ''
|
||||
const id = res.locals.user.id
|
||||
|
||||
const result = await user.updateEmail({ id, email })
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ async function userUpdateNameController (
|
|||
res: Response
|
||||
): Promise<void> {
|
||||
const { displayName, username } = req.body
|
||||
const id = req.user?.id ?? ''
|
||||
const id = res.locals.user.id
|
||||
|
||||
const result = await user.updateName({ id, displayName, username })
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ async function userUpdatePasswordController (
|
|||
res: Response
|
||||
): Promise<void> {
|
||||
const { currentPassword, newPassword } = req.body
|
||||
const id = req.user?.id ?? ''
|
||||
const id = res.locals.user.id
|
||||
|
||||
const result = await user.updatePassword(id, currentPassword, newPassword)
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ async function userUploadPictureController (
|
|||
badRequest(res, 'Expected a JPG or PNG file'); return
|
||||
}
|
||||
|
||||
const userId = req.user?.id ?? ''
|
||||
const userId = res.locals.user.id
|
||||
|
||||
let url: string
|
||||
|
||||
|
|
|
@ -1,55 +1,41 @@
|
|||
import { verify } from 'jsonwebtoken'
|
||||
import prisma from 'clients/prisma-client'
|
||||
import type { Response, Request, NextFunction } from 'express'
|
||||
import type jwtPayload from 'interfaces/jwt'
|
||||
import { unauthorized } from 'helpers/http-errors'
|
||||
import type jwtPayload from 'interfaces/jwt'
|
||||
|
||||
async function authenticated (
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<void> {
|
||||
if (
|
||||
req.headers.authorization === undefined ||
|
||||
req.headers.authorization.length === 0
|
||||
) {
|
||||
unauthorized(res, 'Missing token'); return
|
||||
}
|
||||
|
||||
const token = req.headers.authorization.split(' ')[1]
|
||||
|
||||
try {
|
||||
const decoded = await new Promise<jwtPayload | undefined>(
|
||||
(resolve, reject) => {
|
||||
verify(token, process.env.JWT_ACCESS_SECRET ?? '', (error, decoded) => {
|
||||
if (error != null) {
|
||||
reject(error)
|
||||
} else {
|
||||
resolve(decoded as jwtPayload)
|
||||
}
|
||||
})
|
||||
}
|
||||
)
|
||||
const token = req.cookies.token
|
||||
|
||||
if (decoded == null) {
|
||||
if (token === undefined) {
|
||||
unauthorized(res, 'Missing token'); return
|
||||
}
|
||||
|
||||
const { id } = verify(token, process.env.JWT_ACCESS_SECRET ?? '') as jwtPayload
|
||||
|
||||
if (id === undefined) {
|
||||
unauthorized(res, 'Invalid token'); return
|
||||
}
|
||||
|
||||
const user = await prisma.user.findFirst({
|
||||
where: {
|
||||
id: decoded.id
|
||||
id
|
||||
}
|
||||
})
|
||||
|
||||
if (user == null) {
|
||||
if (user === undefined) {
|
||||
unauthorized(res, 'User does not exists'); return
|
||||
}
|
||||
|
||||
req.user = decoded
|
||||
|
||||
res.locals.user = user
|
||||
next()
|
||||
} catch (error) {
|
||||
unauthorized(res, `JWT Error: ${(error as Error).message}`)
|
||||
} catch (e) {
|
||||
unauthorized(res, `JWT Error: ${(e as Error).message}`)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ function uploadImage (req: Request, res: Response, next: NextFunction): void {
|
|||
const upload = multer(multerConfig).single('image')
|
||||
|
||||
upload(req, res, async (cb: multer.MulterError | Error | any) => {
|
||||
if (req.user == null) {
|
||||
if (req.res?.locals.user == null) {
|
||||
badRequest(
|
||||
res,
|
||||
'You must be logged in to upload a profile picture'
|
||||
|
|
|
@ -3,6 +3,9 @@ import { createServer } from 'http'
|
|||
import logger from 'helpers/logger'
|
||||
import createSocketIOInstance from './socket'
|
||||
|
||||
import prisma from 'clients/prisma-client'
|
||||
import redis from 'clients/redis-client'
|
||||
|
||||
const server = createServer(app)
|
||||
const io = createSocketIOInstance(server)
|
||||
|
||||
|
@ -15,3 +18,10 @@ app.use((req, res, next) => {
|
|||
server.listen(process.env.SERVER_PORT, () => {
|
||||
logger.info(`Server is running @ ${process.env.SERVER_PORT ?? ''}`)
|
||||
})
|
||||
|
||||
process.on('SIGINT', async () => {
|
||||
logger.warn('Closing server...')
|
||||
await prisma.$disconnect()
|
||||
await redis.disconnect()
|
||||
server.close()
|
||||
})
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
import app from '../../app'
|
||||
import request from 'supertest'
|
||||
import signUpNewUser from '../utils/create-user'
|
||||
import deleteUser from '../utils/delete-user'
|
||||
import type User from 'interfaces/user'
|
||||
|
||||
let user: User
|
||||
|
||||
describe('POST /post/create', () => {
|
||||
beforeAll(async () => {
|
||||
user = await signUpNewUser()
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
await deleteUser(user.username!)
|
||||
})
|
||||
|
||||
it('should respond with 200 status code if the user send the token and the content', async () => {
|
||||
const response = await request(app)
|
||||
.post('/post/create')
|
||||
.send({
|
||||
content: 'Hello world'
|
||||
})
|
||||
.set('Authorization', `Bearer ${user.token ?? ''}`)
|
||||
.expect(200)
|
||||
|
||||
expect(response.body).toEqual(
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
content: expect.any(String),
|
||||
authorId: expect.any(String),
|
||||
createdAt: expect.any(String),
|
||||
updatedAt: expect.any(String)
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it('should respond with 400 status code if the user send no token', async () => {
|
||||
const response = await request(app).post('/post/create').expect(401)
|
||||
|
||||
expect(response.body).toHaveProperty('error')
|
||||
})
|
||||
})
|
|
@ -1,36 +0,0 @@
|
|||
import app from '../../app'
|
||||
import request from 'supertest'
|
||||
import signUpNewUser from '../utils/create-user'
|
||||
import deleteUser from '../utils/delete-user'
|
||||
import type User from 'interfaces/user'
|
||||
|
||||
let user: User
|
||||
|
||||
describe('DELETE /post/delete', () => {
|
||||
beforeAll(async () => {
|
||||
user = await signUpNewUser()
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
await deleteUser(user.username!)
|
||||
})
|
||||
|
||||
it('should delete the post successfully', async () => {
|
||||
const response = await request(app)
|
||||
.post('/post/create')
|
||||
.send({
|
||||
content: 'lorem ipsum'
|
||||
})
|
||||
.set('Authorization', `Bearer ${user.token ?? ''}`)
|
||||
.expect(200)
|
||||
|
||||
await request(app)
|
||||
.post('/post/delete')
|
||||
.send({
|
||||
postId: response.body.id
|
||||
})
|
||||
.set('Authorization', `Bearer ${user.token ?? ''}`)
|
||||
.expect(200)
|
||||
})
|
||||
})
|
|
@ -1,54 +0,0 @@
|
|||
import app from '../../app'
|
||||
import request from 'supertest'
|
||||
import signUpNewUser from '../utils/create-user'
|
||||
import deleteUser from '../utils/delete-user'
|
||||
import type User from 'interfaces/user'
|
||||
|
||||
let postId: string
|
||||
|
||||
let user: User
|
||||
|
||||
describe('POST /post/info', () => {
|
||||
beforeAll(async () => {
|
||||
user = await signUpNewUser()
|
||||
|
||||
const token = user.token ?? ''
|
||||
|
||||
const post = await request(app)
|
||||
.post('/post/create')
|
||||
.send({
|
||||
content: 'Hello world'
|
||||
})
|
||||
.set('Authorization', `Bearer ${token}`)
|
||||
.expect(200)
|
||||
|
||||
postId = post.body.id
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
await deleteUser(user.username!)
|
||||
})
|
||||
|
||||
it('should respond with 200 status code and return some info about the post', async () => {
|
||||
const response = await request(app)
|
||||
.get(`/post/info?id=${postId}`)
|
||||
.expect(200)
|
||||
|
||||
expect(response.body).toEqual(
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
content: expect.any(String),
|
||||
createdAt: expect.any(String),
|
||||
updatedAt: expect.any(String),
|
||||
author: expect.any(Object)
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it('should respond with 400 status code if the post does not exists', async () => {
|
||||
const response = await request(app).get('/post/info?id=abc').expect(400)
|
||||
|
||||
expect(response.body).toHaveProperty('error')
|
||||
})
|
||||
})
|
|
@ -1,56 +0,0 @@
|
|||
import app from '../../app'
|
||||
import request from 'supertest'
|
||||
import signUpNewUser from '../utils/create-user'
|
||||
import deleteUser from '../utils/delete-user'
|
||||
import type User from 'interfaces/user'
|
||||
|
||||
let user: User
|
||||
|
||||
describe('PUT /post/update', () => {
|
||||
beforeAll(async () => {
|
||||
user = await signUpNewUser()
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
await deleteUser(user.username!)
|
||||
})
|
||||
|
||||
it('should create a new post and update the content of it', async () => {
|
||||
const post = await request(app)
|
||||
.post('/post/create')
|
||||
.send({
|
||||
content: 'Lorem'
|
||||
})
|
||||
.set('Authorization', `Bearer ${user.token ?? ''}`)
|
||||
.expect(200)
|
||||
|
||||
expect(post.body).toHaveProperty('id')
|
||||
|
||||
const fieldsToUpdate = {
|
||||
postId: post.body.id,
|
||||
content: 'Lorem ipsum'
|
||||
}
|
||||
|
||||
const response = await request(app)
|
||||
.put('/post/update')
|
||||
.send(fieldsToUpdate)
|
||||
.set('Authorization', `Bearer ${user.token ?? ''}`)
|
||||
.expect(200)
|
||||
|
||||
// Post content should be Lorem Ipsum
|
||||
if (post.body.content === response.body.content) {
|
||||
throw new Error("Post didn't update")
|
||||
}
|
||||
|
||||
expect(response.body).toEqual(
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
content: expect.any(String),
|
||||
createdAt: expect.any(String),
|
||||
updatedAt: expect.any(String),
|
||||
author: expect.any(Object)
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
|
@ -1,45 +0,0 @@
|
|||
import request from 'supertest'
|
||||
import app from '../../app'
|
||||
import deleteUser from '../utils/delete-user'
|
||||
import signUpNewUser from '../utils/create-user'
|
||||
import type User from 'interfaces/user'
|
||||
|
||||
let user: User
|
||||
|
||||
describe('POST /user/auth', () => {
|
||||
beforeAll(async () => {
|
||||
user = await signUpNewUser()
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
await deleteUser(user.username!)
|
||||
})
|
||||
|
||||
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('Invalid email or password')
|
||||
})
|
||||
|
||||
it('should respond with a error if receive an invalid email or password', async () => {
|
||||
const response = await request(app)
|
||||
.post('/user/auth')
|
||||
.send({ email: user.email, password: 'fake_pass' })
|
||||
.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')
|
||||
})
|
||||
})
|
|
@ -1,19 +0,0 @@
|
|||
import app from '../../app'
|
||||
import request from 'supertest'
|
||||
import signUpNewUser from '../utils/create-user'
|
||||
import type User from 'interfaces/user'
|
||||
|
||||
let user: User
|
||||
|
||||
describe('DELETE /user/delete', () => {
|
||||
beforeAll(async () => {
|
||||
user = await signUpNewUser()
|
||||
})
|
||||
|
||||
it('should delete the user successfully', async () => {
|
||||
await request(app)
|
||||
.post('/user/delete')
|
||||
.set('Authorization', `Bearer ${user.token ?? ''}`)
|
||||
.expect(200)
|
||||
})
|
||||
})
|
|
@ -1,36 +0,0 @@
|
|||
import app from '../../app'
|
||||
import request from 'supertest'
|
||||
import deleteUser from '../utils/delete-user'
|
||||
import signUpNewUser from '../utils/create-user'
|
||||
import type User from 'interfaces/user'
|
||||
|
||||
let user: User
|
||||
|
||||
describe('POST /user/info', () => {
|
||||
beforeAll(async () => {
|
||||
user = await signUpNewUser()
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
await deleteUser(user.username!)
|
||||
})
|
||||
|
||||
it('should respond with 200 status code and return the user data', async () => {
|
||||
const response = await request(app)
|
||||
.get(`/user/info?u=${user.username ?? ''}`)
|
||||
.expect(200)
|
||||
|
||||
expect(response.body).toHaveProperty('profileImage')
|
||||
expect(response.body).toHaveProperty('displayName')
|
||||
expect(response.body).toHaveProperty('username')
|
||||
expect(response.body).toHaveProperty('createdAt')
|
||||
expect(response.body).toHaveProperty('posts')
|
||||
})
|
||||
|
||||
it('should respond with 400 status code if the user send no username', async () => {
|
||||
const response = await request(app).get('/user/info?u=').expect(400)
|
||||
|
||||
expect(response.body).toHaveProperty('error')
|
||||
})
|
||||
})
|
|
@ -1,45 +0,0 @@
|
|||
import request from 'supertest'
|
||||
import app from '../../app'
|
||||
import deleteUser from '../utils/delete-user'
|
||||
import signUpNewUser from '../utils/create-user'
|
||||
import type User from 'interfaces/user'
|
||||
|
||||
let user: User
|
||||
|
||||
describe('POST /user/signup', () => {
|
||||
beforeAll(async () => {
|
||||
user = await signUpNewUser()
|
||||
delete user.token
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
await deleteUser(user.username!)
|
||||
})
|
||||
|
||||
it('should respond with a 400 status code if sent any invalid data', async () => {
|
||||
await request(app)
|
||||
.post('/user/signup')
|
||||
.send({
|
||||
username: 'username12@',
|
||||
email: user.email,
|
||||
password: user.password
|
||||
})
|
||||
.expect(400)
|
||||
})
|
||||
|
||||
it('should respond with a 400 status code for an existing username or email', async () => {
|
||||
await request(app)
|
||||
.post('/user/signup')
|
||||
.send({
|
||||
username: user.username,
|
||||
email: user.email,
|
||||
password: user.password
|
||||
})
|
||||
.expect(400)
|
||||
})
|
||||
|
||||
it('should respond with a 400 status code if receive an empty body', async () => {
|
||||
await request(app).post('/user/signup').send({}).expect(400)
|
||||
})
|
||||
})
|
|
@ -1,37 +0,0 @@
|
|||
import app from '../../app'
|
||||
import request from 'supertest'
|
||||
import { faker } from '@faker-js/faker'
|
||||
import type User from '../../interfaces/user'
|
||||
|
||||
async function signUpNewUser (): Promise<User> {
|
||||
// To avoid conflicts with existing usernames or emails
|
||||
const username = faker.internet.userName({ lastName: 'doe' }).toLowerCase()
|
||||
const email = faker.internet.email()
|
||||
const password = faker.internet.password() + '@1'
|
||||
|
||||
await request(app)
|
||||
.post('/user/signup')
|
||||
.send({
|
||||
username,
|
||||
email,
|
||||
password
|
||||
})
|
||||
.expect(200)
|
||||
|
||||
const response = await request(app)
|
||||
.post('/user/auth')
|
||||
.send({
|
||||
email,
|
||||
password
|
||||
})
|
||||
.expect(200)
|
||||
|
||||
return {
|
||||
username,
|
||||
email,
|
||||
password,
|
||||
token: response.body.token
|
||||
}
|
||||
}
|
||||
|
||||
export default signUpNewUser
|
|
@ -1,17 +0,0 @@
|
|||
import prisma from '../../clients/prisma-client'
|
||||
|
||||
export default async function deleteUser (username: string) {
|
||||
await prisma.post.deleteMany({
|
||||
where: {
|
||||
author: {
|
||||
username
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
await prisma.user.deleteMany({
|
||||
where: {
|
||||
username
|
||||
}
|
||||
})
|
||||
}
|
Loading…
Reference in a new issue