-
Notifications
You must be signed in to change notification settings - Fork 72
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
117 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,8 @@ beforeEach(async () => { | |
|
||
const activeUser = { username: 'user1', email: '[email protected]', password: 'P4ssword', inactive: false }; | ||
|
||
const credentials = { email: '[email protected]', password: 'P4ssword' }; | ||
|
||
const addUser = async (user = { ...activeUser }) => { | ||
const hash = await bcrypt.hash(user.password, 10); | ||
user.password = hash; | ||
|
@@ -44,24 +46,24 @@ const postLogout = (options = {}) => { | |
describe('Authentication', () => { | ||
it('returns 200 when credentials are correct', async () => { | ||
await addUser(); | ||
const response = await postAuthentication({ email: '[email protected]', password: 'P4ssword' }); | ||
const response = await postAuthentication(credentials); | ||
expect(response.status).toBe(200); | ||
}); | ||
|
||
it('returns user id, username, image and token when login success', async () => { | ||
const user = await addUser(); | ||
const response = await postAuthentication({ email: '[email protected]', password: 'P4ssword' }); | ||
const response = await postAuthentication(credentials); | ||
expect(response.body.id).toBe(user.id); | ||
expect(response.body.username).toBe(user.username); | ||
expect(Object.keys(response.body)).toEqual(['id', 'username', 'image', 'token']); | ||
}); | ||
it('returns 401 when user does not exist', async () => { | ||
const response = await postAuthentication({ email: '[email protected]', password: 'P4ssword' }); | ||
const response = await postAuthentication(credentials); | ||
expect(response.status).toBe(401); | ||
}); | ||
it('returns proper error body when authentication fails', async () => { | ||
const nowInMillis = new Date().getTime(); | ||
const response = await postAuthentication({ email: '[email protected]', password: 'P4ssword' }); | ||
const response = await postAuthentication(credentials); | ||
const error = response.body; | ||
expect(error.path).toBe('/api/1.0/auth'); | ||
expect(error.timestamp).toBeGreaterThan(nowInMillis); | ||
|
@@ -73,7 +75,7 @@ describe('Authentication', () => { | |
${'tr'} | ${tr.authentication_failure} | ||
${'en'} | ${en.authentication_failure} | ||
`('returns $message when authentication fails and language is set as $language', async ({ language, message }) => { | ||
const response = await postAuthentication({ email: '[email protected]', password: 'P4ssword' }, { language }); | ||
const response = await postAuthentication(credentials, { language }); | ||
expect(response.body.message).toBe(message); | ||
}); | ||
|
||
|
@@ -85,13 +87,13 @@ describe('Authentication', () => { | |
|
||
it('returns 403 when logging in with an inactive account', async () => { | ||
await addUser({ ...activeUser, inactive: true }); | ||
const response = await postAuthentication({ email: '[email protected]', password: 'P4ssword' }); | ||
const response = await postAuthentication(credentials); | ||
expect(response.status).toBe(403); | ||
}); | ||
it('returns proper error body when inactive authentication fails', async () => { | ||
await addUser({ ...activeUser, inactive: true }); | ||
const nowInMillis = new Date().getTime(); | ||
const response = await postAuthentication({ email: '[email protected]', password: 'P4ssword' }); | ||
const response = await postAuthentication(credentials); | ||
const error = response.body; | ||
expect(error.path).toBe('/api/1.0/auth'); | ||
expect(error.timestamp).toBeGreaterThan(nowInMillis); | ||
|
@@ -105,7 +107,7 @@ describe('Authentication', () => { | |
'returns $message when authentication fails for inactive account and language is set as $language', | ||
async ({ language, message }) => { | ||
await addUser({ ...activeUser, inactive: true }); | ||
const response = await postAuthentication({ email: '[email protected]', password: 'P4ssword' }, { language }); | ||
const response = await postAuthentication(credentials, { language }); | ||
expect(response.body.message).toBe(message); | ||
} | ||
); | ||
|
@@ -119,7 +121,7 @@ describe('Authentication', () => { | |
}); | ||
it('returns token in response body when credentials are correct', async () => { | ||
await addUser(); | ||
const response = await postAuthentication({ email: '[email protected]', password: 'P4ssword' }); | ||
const response = await postAuthentication(credentials); | ||
expect(response.body.token).not.toBeUndefined(); | ||
}); | ||
}); | ||
|
@@ -131,7 +133,7 @@ describe('Logout', () => { | |
}); | ||
it('removes the token from database', async () => { | ||
await addUser(); | ||
const response = await postAuthentication({ email: '[email protected]', password: 'P4ssword' }); | ||
const response = await postAuthentication(credentials); | ||
const token = response.body.token; | ||
await postLogout({ token: token }); | ||
const storedToken = await Token.findOne({ where: { token: token } }); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
const request = require('supertest'); | ||
const app = require('../src/app'); | ||
const en = require('../locales/en/translation.json'); | ||
const tr = require('../locales/tr/translation.json'); | ||
const User = require('../src/user/User'); | ||
const sequelize = require('../src/config/database'); | ||
const bcrypt = require('bcrypt'); | ||
|
||
beforeAll(async () => { | ||
if (process.env.NODE_ENV === 'test') { | ||
await sequelize.sync(); | ||
} | ||
}); | ||
|
||
beforeEach(async () => { | ||
await User.destroy({ truncate: { cascade: true } }); | ||
}); | ||
|
||
const activeUser = { username: 'user1', email: '[email protected]', password: 'P4ssword', inactive: false }; | ||
|
||
const credentials = { email: '[email protected]', password: 'P4ssword' }; | ||
|
||
const addUser = async (user = { ...activeUser }) => { | ||
const hash = await bcrypt.hash(user.password, 10); | ||
user.password = hash; | ||
return await User.create(user); | ||
}; | ||
|
||
const postHoax = async (body = null, options = {}) => { | ||
let agent = request(app); | ||
let token; | ||
if (options.auth) { | ||
const response = await agent.post('/api/1.0/auth').send(options.auth); | ||
token = response.body.token; | ||
} | ||
agent = request(app).post('/api/1.0/hoaxes'); | ||
if (options.language) { | ||
agent.set('Accept-Language', options.language); | ||
} | ||
if (token) { | ||
agent.set('Authorization', `Bearer ${token}`); | ||
} | ||
if (options.token) { | ||
agent.set('Authorization', `Bearer ${options.token}`); | ||
} | ||
return agent.send(body); | ||
}; | ||
|
||
describe('Post Hoax', () => { | ||
it('returns 401 when hoax post request has no authentication', async () => { | ||
const response = await postHoax(); | ||
expect(response.status).toBe(401); | ||
}); | ||
it.each` | ||
language | message | ||
${'tr'} | ${tr.unauthorized_hoax_submit} | ||
${'en'} | ${en.unauthorized_hoax_submit} | ||
`( | ||
'returns error body with $message when unauthorized request sent with language $language', | ||
async ({ language, message }) => { | ||
const nowInMillis = Date.now(); | ||
const response = await postHoax(null, { language }); | ||
const error = response.body; | ||
expect(error.path).toBe('/api/1.0/hoaxes'); | ||
expect(error.message).toBe(message); | ||
expect(error.timestamp).toBeGreaterThan(nowInMillis); | ||
} | ||
); | ||
it('returns 200 when valid hoax submitted with authorized user', async () => { | ||
await addUser(); | ||
const response = await postHoax({ content: 'Hoax content' }, { auth: credentials }); | ||
expect(response.status).toBe(200); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,8 @@ beforeEach(async () => { | |
|
||
const activeUser = { username: 'user1', email: '[email protected]', password: 'P4ssword', inactive: false }; | ||
|
||
const credentials = { email: '[email protected]', password: 'P4ssword' }; | ||
|
||
const addUser = async (user = { ...activeUser }) => { | ||
const hash = await bcrypt.hash(user.password, 10); | ||
user.password = hash; | ||
|
@@ -68,7 +70,7 @@ describe('User Delete', () => { | |
it('returns forbidden when delete request is sent with correct credentials but for different user', async () => { | ||
await addUser(); | ||
const userToBeDelete = await addUser({ ...activeUser, username: 'user2', email: '[email protected]' }); | ||
const token = await auth({ auth: { email: '[email protected]', password: 'P4ssword' } }); | ||
const token = await auth({ auth: credentials }); | ||
const response = await deleteUser(userToBeDelete.id, { token: token }); | ||
expect(response.status).toBe(403); | ||
}); | ||
|
@@ -78,30 +80,30 @@ describe('User Delete', () => { | |
}); | ||
it('returns 200 ok when delete request sent from authorized user', async () => { | ||
const savedUser = await addUser(); | ||
const token = await auth({ auth: { email: '[email protected]', password: 'P4ssword' } }); | ||
const token = await auth({ auth: credentials }); | ||
const response = await deleteUser(savedUser.id, { token: token }); | ||
expect(response.status).toBe(200); | ||
}); | ||
it('deletes user from database when request sent from authorized user', async () => { | ||
const savedUser = await addUser(); | ||
const token = await auth({ auth: { email: '[email protected]', password: 'P4ssword' } }); | ||
const token = await auth({ auth: credentials }); | ||
await deleteUser(savedUser.id, { token: token }); | ||
|
||
const inDBUser = await User.findOne({ where: { id: savedUser.id } }); | ||
expect(inDBUser).toBeNull(); | ||
}); | ||
it('deletes token from database when delete user request sent from authorized user', async () => { | ||
const savedUser = await addUser(); | ||
const token = await auth({ auth: { email: '[email protected]', password: 'P4ssword' } }); | ||
const token = await auth({ auth: credentials }); | ||
await deleteUser(savedUser.id, { token: token }); | ||
|
||
const tokenInDB = await Token.findOne({ where: { token: token } }); | ||
expect(tokenInDB).toBeNull(); | ||
}); | ||
it('deletes all tokens from database when delete user request sent from authorized user', async () => { | ||
const savedUser = await addUser(); | ||
const token1 = await auth({ auth: { email: '[email protected]', password: 'P4ssword' } }); | ||
const token2 = await auth({ auth: { email: '[email protected]', password: 'P4ssword' } }); | ||
const token1 = await auth({ auth: credentials }); | ||
const token2 = await auth({ auth: credentials }); | ||
await deleteUser(savedUser.id, { token: token1 }); | ||
|
||
const tokenInDB = await Token.findOne({ where: { token: token2 } }); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,7 @@ beforeEach(async () => { | |
}); | ||
|
||
const activeUser = { username: 'user1', email: '[email protected]', password: 'P4ssword', inactive: false }; | ||
const credentials = { email: '[email protected]', password: 'P4ssword' }; | ||
|
||
const addUser = async (user = { ...activeUser }) => { | ||
const hash = await bcrypt.hash(user.password, 10); | ||
|
@@ -89,14 +90,14 @@ describe('User Update', () => { | |
await addUser(); | ||
const userToBeUpdated = await addUser({ ...activeUser, username: 'user2', email: '[email protected]' }); | ||
const response = await putUser(userToBeUpdated.id, null, { | ||
auth: { email: '[email protected]', password: 'P4ssword' }, | ||
auth: credentials, | ||
}); | ||
expect(response.status).toBe(403); | ||
}); | ||
it('returns forbidden when update request is sent by inactive user with correct credentials for its own user', async () => { | ||
const inactiveUser = await addUser({ ...activeUser, inactive: true }); | ||
const response = await putUser(inactiveUser.id, null, { | ||
auth: { email: '[email protected]', password: 'P4ssword' }, | ||
auth: credentials, | ||
}); | ||
expect(response.status).toBe(403); | ||
}); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
module.exports = function AuthenticationException() { | ||
module.exports = function AuthenticationException(message) { | ||
this.status = 401; | ||
this.message = 'authentication_failure'; | ||
this.message = message || 'authentication_failure'; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
const express = require('express'); | ||
const router = express.Router(); | ||
const AuthenticationException = require('../auth/AuthenticationException'); | ||
|
||
router.post('/api/1.0/hoaxes', (req, res) => { | ||
if (req.authenticatedUser) { | ||
return res.send(); | ||
} | ||
throw new AuthenticationException('unauthorized_hoax_submit'); | ||
}); | ||
|
||
module.exports = router; |