This commit is contained in:
Ulises Gascón
2024-02-07 12:29:54 +01:00
committed by Ulises Gascon
parent 91ba1f5054
commit 9dd233c371
143 changed files with 68070 additions and 1 deletions
+290
View File
@@ -0,0 +1,290 @@
import supertest from 'supertest'
import { app } from '../server'
import { getById } from '../stores/whisper'
import { restoreDb, populateDb, getFixtures, ensureDbConnection, normalize, closeDbConnection } from './utils.js'
let whispers
let inventedId
let existingId
let firstUser
let secondUser
describe('Server', () => {
beforeAll(ensureDbConnection)
beforeEach(async () => {
await restoreDb()
await populateDb(whispers)
const fixtures = await getFixtures()
whispers = fixtures.whispers
inventedId = fixtures.inventedId
existingId = fixtures.existingId
firstUser = fixtures.firstUser
secondUser = fixtures.secondUser
})
afterAll(closeDbConnection)
describe('GET /login', () => {
it('Should return a 200 with a login page', async () => {
const response = await supertest(app).get('/login')
expect(response.status).toBe(200)
expect(response.text).toContain('Welcome Back!')
})
})
describe('GET /signup', () => {
it('Should return a 200 with a signup page', async () => {
const response = await supertest(app).get('/signup')
expect(response.status).toBe(200)
expect(response.text).toContain('Create your account!')
})
})
describe('POST /signup', () => {
const newUser = {
username: 'jane_doe2',
password: '123456ASDasd@#',
email: 'jane_doe2@demo.foo'
}
it('Should return a 400 when the body is empty', async () => {
const response = await supertest(app)
.post('/signup')
.send({})
expect(response.status).toBe(400)
})
it('Should return a 400 when the body is not completed', async () => {
const response = await supertest(app)
.post('/signup')
.send({ username: newUser.username })
expect(response.status).toBe(400)
expect(response.body.error).toBe('User validation failed: password: Password is required, email: Email is required')
})
it('Should return a 400 when the password is weak', async () => {
const response = await supertest(app)
.post('/signup')
.send({ ...newUser, password: 'weak' })
expect(response.status).toBe(400)
expect(response.body.error).toBe('User validation failed: password: Password must be at least 8 characters long')
})
it('Should return a 200 and a token when the user is created', async () => {
const response = await supertest(app)
.post('/signup')
.send(newUser)
expect(response.status).toBe(200)
expect(response.body.accessToken).toBeDefined()
})
})
describe('POST /login', () => {
it('Should return a 400 when the body is empty', async () => {
const response = await supertest(app)
.post('/login')
.send({})
expect(response.status).toBe(400)
})
it('Should return a 400 when the body is not completed', async () => {
const response = await supertest(app)
.post('/login')
.send({ username: 'jane_doe' })
expect(response.status).toBe(400)
})
it('Should return a 400 when the user is not found', async () => {
const response = await supertest(app)
.post('/login')
.send({ username: `${firstUser.username}_invented`, password: firstUser.password })
expect(response.status).toBe(400)
})
it('Should return a 400 when the password is incorrect', async () => {
const response = await supertest(app)
.post('/login')
.send({ username: firstUser.username, password: `${firstUser.password}_invented` })
expect(response.status).toBe(400)
})
it('Should return a 200 and an accessToken when the user is created', async () => {
const response = await supertest(app)
.post('/login')
.send({ username: firstUser.username, password: firstUser.password })
expect(response.status).toBe(200)
expect(response.body.accessToken).toBeDefined()
})
})
describe('GET /about', () => {
it('Should return a 200 with the total whispers in the platform', async () => {
const response = await supertest(app)
.get('/about')
.set('Authentication', `Bearer ${firstUser.token}`)
expect(response.status).toBe(200)
expect(response.text).toContain(`Currently there are ${whispers.length} whispers available`)
})
})
describe('GET /api/v1/whisper', () => {
it('Should return a 401 when the user is not authenticated', async () => {
const response = await supertest(app)
.get('/api/v1/whisper')
expect(response.status).toBe(401)
expect(response.body.error).toBe('No token provided')
})
it("Should return an empty array when there's no data", async () => {
await restoreDb() // empty the db
const response = await supertest(app)
.get('/api/v1/whisper')
.set('Authentication', `Bearer ${firstUser.token}`)
expect(response.status).toBe(200)
expect(response.body).toEqual([])
})
it('Should return all the whispers', async () => {
const response = await supertest(app)
.get('/api/v1/whisper')
.set('Authentication', `Bearer ${firstUser.token}`)
expect(response.status).toBe(200)
expect(response.body).toEqual(whispers)
})
})
describe('GET /api/v1/whisper/:id', () => {
it('Should return a 401 when the user is not authenticated', async () => {
const response = await supertest(app)
.get(`/api/v1/whisper/${existingId}`)
expect(response.status).toBe(401)
expect(response.body.error).toBe('No token provided')
})
it("Should return a 404 when the whisper doesn't exist", async () => {
const response = await supertest(app)
.get(`/api/v1/whisper/${inventedId}`)
.set('Authentication', `Bearer ${firstUser.token}`)
expect(response.status).toBe(404)
})
it('Should return a whisper details', async () => {
const response = await supertest(app)
.get(`/api/v1/whisper/${existingId}`)
.set('Authentication', `Bearer ${firstUser.token}`)
expect(response.status).toBe(200)
expect(response.body).toEqual(whispers.find(w => w.id === existingId))
})
})
describe('POST /api/v1/whisper', () => {
it('Should return a 400 when the body is empty', async () => {
const response = await supertest(app)
.post('/api/v1/whisper')
.set('Authentication', `Bearer ${firstUser.token}`)
.send({})
expect(response.status).toBe(400)
})
it('Should return a 400 when the body is invalid', async () => {
const response = await supertest(app)
.post('/api/v1/whisper')
.set('Authentication', `Bearer ${firstUser.token}`)
.send({ invented: 'This is a new whisper' })
expect(response.status).toBe(400)
})
it('Should return a 401 when the user is not authenticated', async () => {
const newWhisper = { message: 'This is a new whisper' }
const response = await supertest(app)
.post('/api/v1/whisper')
.send({ message: newWhisper.message })
expect(response.status).toBe(401)
expect(response.body.error).toBe('No token provided')
})
it('Should return a 201 when the whisper is created', async () => {
const newWhisper = { message: 'This is a new whisper' }
const response = await supertest(app)
.post('/api/v1/whisper')
.set('Authentication', `Bearer ${firstUser.token}`)
.send({ message: newWhisper.message })
expect(response.status).toBe(201)
expect(response.body.message).toEqual(newWhisper.message)
// Database changes
const storedWhisper = await getById(response.body.id)
expect(normalize(storedWhisper).message).toStrictEqual(newWhisper.message)
})
})
describe('PUT /api/v1/whisper/:id', () => {
it('Should return a 400 when the body is empty', async () => {
const response = await supertest(app)
.put(`/api/v1/whisper/${existingId}`)
.set('Authentication', `Bearer ${firstUser.token}`)
.send({})
expect(response.status).toBe(400)
})
it('Should return a 400 when the body is invalid', async () => {
const response = await supertest(app)
.put(`/api/v1/whisper/${existingId}`)
.set('Authentication', `Bearer ${firstUser.token}`)
.send({ invented: 'This a new field' })
expect(response.status).toBe(400)
})
it("Should return a 404 when the whisper doesn't exist", async () => {
const response = await supertest(app)
.put(`/api/v1/whisper/${inventedId}`)
.set('Authentication', `Bearer ${firstUser.token}`)
.send({ message: 'Whisper updated' })
expect(response.status).toBe(404)
})
it('Should return a 401 when the user is not authenticated', async () => {
const response = await supertest(app)
.put(`/api/v1/whisper/${existingId}`)
.send({ message: 'Whisper updated' })
expect(response.status).toBe(401)
expect(response.body.error).toBe('No token provided')
})
it('Should return a 403 when the user is not the author', async () => {
const response = await supertest(app)
.put(`/api/v1/whisper/${existingId}`)
.set('Authentication', `Bearer ${secondUser.token}`)
.send({ message: 'Whisper updated' })
expect(response.status).toBe(403)
})
it('Should return a 200 when the whisper is updated', async () => {
const response = await supertest(app)
.put(`/api/v1/whisper/${existingId}`)
.set('Authentication', `Bearer ${firstUser.token}`)
.send({ message: 'Whisper updated' })
expect(response.status).toBe(200)
// Database changes
const storedWhisper = await getById(existingId)
const normalizedWhisper = normalize(storedWhisper)
expect(normalizedWhisper.id).toBe(existingId)
expect(normalizedWhisper.message).toBe('Whisper updated')
})
})
describe('DELETE /api/v1/whisper/:id', () => {
it("Should return a 404 when the whisper doesn't exist", async () => {
const response = await supertest(app)
.delete(`/api/v1/whisper/${inventedId}`)
.set('Authentication', `Bearer ${firstUser.token}`)
expect(response.status).toBe(404)
})
it('Should return a 401 when the user is not authenticated', async () => {
const response = await supertest(app)
.delete(`/api/v1/whisper/${existingId}`)
expect(response.status).toBe(401)
expect(response.body.error).toBe('No token provided')
})
it('Should return a 403 when the user is not the author', async () => {
const response = await supertest(app)
.delete(`/api/v1/whisper/${existingId}`)
.set('Authentication', `Bearer ${secondUser.token}`)
expect(response.status).toBe(403)
})
it('Should return a 200 when the whisper is deleted', async () => {
const response = await supertest(app)
.delete(`/api/v1/whisper/${existingId}`)
.set('Authentication', `Bearer ${firstUser.token}`)
expect(response.status).toBe(200)
// Database changes
const storedWhisper = await getById(existingId)
expect(storedWhisper).toBe(null)
})
})
})
+64
View File
@@ -0,0 +1,64 @@
import mongoose from 'mongoose'
import {
Whisper,
User
} from '../database.js'
import { generateToken } from '../utils.js'
const ensureDbConnection = async () => {
try {
if (mongoose.connection.readyState !== 1) {
await mongoose.connect(process.env.MONGODB_URI)
}
} catch (error) {
console.error('Error connecting to the database:', error)
throw error
}
}
const closeDbConnection = async () => {
if (mongoose.connection.readyState === 1) {
await mongoose.disconnect()
}
}
const restoreDb = async () => {
await Whisper.deleteMany({})
await User.deleteMany({})
}
const getUsersFixtures = () => [
{ username: 'jane_doe', password: 'qg82H0Zt1Ee6F2ESNwI!ZN8iq7N', email: 'jane@doe.com' },
{ username: 'joe_doe', password: 'nnO864BTxe#103Hl8eI!Qx#0xCw', email: 'joe@doe.com' }
]
const populateDb = async () => {
const users = []
for (const user of getUsersFixtures()) {
const storedUser = await User.create(user)
users.push(storedUser)
}
const messages = [
{ message: 'Jane testing', author: users[0]._id },
{ message: 'hello world from Joe', author: users[0]._id }
]
for (const message of messages) {
await Whisper.create(message)
}
}
const getFixtures = async () => {
const data = await Whisper.find().populate('author', 'username')
const whispers = JSON.parse(JSON.stringify(data))
const inventedId = '64e0e5c75a4a3c715b7c1074'
const existingId = data[0].id
const storedUsers = await User.find({})
const [firstUser, secondUser] = getUsersFixtures()
firstUser.id = storedUsers[0]._id.toString()
secondUser.id = storedUsers[1]._id.toString()
firstUser.token = generateToken({ id: firstUser.id, username: firstUser.username })
secondUser.token = generateToken({ id: secondUser.id, username: secondUser.username })
return { inventedId, existingId, whispers, firstUser, secondUser }
}
const normalize = (data) => JSON.parse(JSON.stringify(data))
export { restoreDb, populateDb, getFixtures, ensureDbConnection, normalize, closeDbConnection }