From 3179ab49b7a2d6cc48f6c1ef624746371c655f99 Mon Sep 17 00:00:00 2001 From: Roland Bernard <rolbernard@unibz.it> Date: Sun, 23 May 2021 20:23:26 +0200 Subject: [PATCH] Added tests for the auth.ts file --- server/package.json | 2 +- server/src/setupTests.ts | 4 +- server/src/v1/auth.test.ts | 225 ++++++++++++++++++++++++++++++++++++- server/src/v1/auth.ts | 41 +++---- server/src/v1/user.test.ts | 7 +- 5 files changed, 245 insertions(+), 34 deletions(-) diff --git a/server/package.json b/server/package.json index 3abc8c5..728f81a 100644 --- a/server/package.json +++ b/server/package.json @@ -23,7 +23,7 @@ "scripts": { "start": "nodemon src/index.ts", "build": "tsc --project .", - "test": "jest --passWithNoTests --config ./jest.config.json" + "test": "jest --passWithNoTests --verbose --config ./jest.config.json" }, "devDependencies": { "@types/bcrypt": "^3.0.1", diff --git a/server/src/setupTests.ts b/server/src/setupTests.ts index fd33e1e..4329df1 100644 --- a/server/src/setupTests.ts +++ b/server/src/setupTests.ts @@ -8,14 +8,14 @@ async function loadTestData() { .insert([ { id: '00000000-0000-0000-0000-000000000000', - user_name: 'User0', + user_name: 'user0', passwd_hash: '$2b$10$sjHhJNz4sLNclKEwWISZRe4cVju6jn4QjMVs4wdZ6wug2SKG774pq', email: 'test0@example.com', real_name: 'Testing Tester', image: null, }, { id: '00000000-0000-0000-0000-000000000001', - user_name: 'User1', + user_name: 'user1', passwd_hash: '$2b$10$sjHhJNz4sLNclKEwWISZRe4cVju6jn4QjMVs4wdZ6wug2SKG774pq', email: 'test1@example.com', real_name: 'Tester Testing', diff --git a/server/src/v1/auth.test.ts b/server/src/v1/auth.test.ts index d87a33a..fb67e4e 100644 --- a/server/src/v1/auth.test.ts +++ b/server/src/v1/auth.test.ts @@ -1,11 +1,232 @@ -import supertest from 'supertest'; +import supertest, { Response } from 'supertest'; +import { database } from '../database'; import { api } from '../api'; +import { generateAuthToken } from './auth'; const request = supertest(api); -test('', async () => { +describe('requesting a token', () => { + test('fails if username does not exist', async () => { + const response = await request + .post('/v1/auth/token') + .send({ + username: 'User2', + password: 'testtest', + }); + expect(response.status).toEqual(404); + expect(response.body.status).toEqual('error'); + }); + + test('fails if the password is wrong', async () => { + const response = await request + .post('/v1/auth/token') + .send({ + username: 'User0', + password: 'test', + }); + expect(response.status).toEqual(403); + expect(response.body.status).toEqual('error'); + }); + + test('succeeds if username and password are correct', async () => { + const response = await request + .post('/v1/auth/token') + .send({ + username: 'User0', + password: 'testtest', + }); + expect(response.status).toEqual(200); + expect(response.body.status).toEqual('success'); + expect(response.body.token).toBeTruthy(); + }); +}); + +test('registering a user with an existing username fails', async () => { + const response = await request + .post('/v1/auth/register') + .send({ + username: 'User0', + password: 'testtest', + }); + expect(response.status).toEqual(400); + expect(response.body.status).toEqual('error'); +}); + +describe('successful user registration', () => { + let response: Response; + + beforeAll(async () => { + response = await request + .post('/v1/auth/register') + .send({ + username: 'User2', + password: 'testing', + email: 'test@example.com', + realname: 'Real Test', + }); + }); + + test('returns a valid token', async () => { + expect(response.status).toEqual(200); + expect(response.body.status).toEqual('success'); + expect(response.body.token).toBeTruthy(); + }); + + test('creates a new user', async () => { + const user = await database('users') + .select() + .where({ 'users.user_name': 'user2' }); + expect(user.length).toEqual(1); + expect(user[0].user_name).toEqual('user2'); + expect(user[0].email).toEqual('test@example.com'); + expect(user[0].real_name).toEqual('Real Test'); + }); + + test('auth token can be requested', async () => { + const response = await request + .post('/v1/auth/token') + .send({ + username: 'User2', + password: 'testing', + }); + expect(response.status).toEqual(200); + expect(response.body.status).toEqual('success'); + expect(response.body.token).toBeTruthy(); + }); + + afterAll(async () => { + await database('users') + .delete() + .where({ 'users.user_name': 'user2' }); + }); +}) + +describe('password can be changed', () => { + let response: Response; + + beforeAll(async () => { + response = await request + .put('/v1/auth/password') + .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-0000-0000-000000000000')}`) + .send({ + password: 'testtest2', + }); + }) + + test('returns successfully', async () => { + expect(response.status).toEqual(200); + expect(response.body.status).toEqual('success'); + }); + + test('token request with old password fails', async () => { + const response = await request + .post('/v1/auth/token') + .send({ + username: 'User0', + password: 'testtest', + }); + expect(response.status).toEqual(403); + expect(response.body.status).toEqual('error'); + }); + test('token request with new password succeeds', async () => { + const response = await request + .post('/v1/auth/token') + .send({ + username: 'User0', + password: 'testtest2', + }); + expect(response.status).toEqual(200); + expect(response.body.status).toEqual('success'); + expect(response.body.token).toBeTruthy(); + }); + + afterAll(async () => { + response = await request + .put('/v1/auth/password') + .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-0000-0000-000000000000')}`) + .send({ + password: 'testtest', + }); + }) +}); + +test('changing username to an existing one fails', async () => { + const response = await request + .put('/v1/auth/username') + .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-0000-0000-000000000000')}`) + .send({ + username: 'User1', + }); + expect(response.status).toEqual(400); + expect(response.body.status).toEqual('error'); +}); + +describe('username can be changed', () => { + let response: Response; + + beforeAll(async () => { + response = await request + .put('/v1/auth/username') + .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-0000-0000-000000000000')}`) + .send({ + username: 'User00', + }); + }) + + test('returns successfully', async () => { + expect(response.status).toEqual(200); + expect(response.body.status).toEqual('success'); + }); + + test('token request with old username fails', async () => { + const response = await request + .post('/v1/auth/token') + .send({ + username: 'User0', + password: 'testtest', + }); + expect(response.status).toEqual(404); + expect(response.body.status).toEqual('error'); + }); + + test('token request with new username succeeds', async () => { + const response = await request + .post('/v1/auth/token') + .send({ + username: 'User00', + password: 'testtest', + }); + expect(response.status).toEqual(200); + expect(response.body.status).toEqual('success'); + expect(response.body.token).toBeTruthy(); + }); + + afterAll(async () => { + response = await request + .put('/v1/auth/username') + .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-0000-0000-000000000000')}`) + .send({ + username: 'User0', + }); + }) +}); + +test('valid tokens can be extended', async () => { + const response = await request + .get('/v1/auth/extend') + .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-0000-0000-000000000000')}`); + expect(response.status).toEqual(200); + expect(response.body.status).toEqual('success'); +}); + +test('invalid tokens cause an 403 error', async () => { + const response = await request + .get('/v1/auth/extend') + .set('Authorization', 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMCJ9.Kq2cI42E_-c1No89CpGyqwLV3BL4fFpe5fGhDjrUr2c'); + expect(response.status).toEqual(403); + expect(response.body.status).toEqual('error'); }); diff --git a/server/src/v1/auth.ts b/server/src/v1/auth.ts index 4bf7400..93a92cb 100644 --- a/server/src/v1/auth.ts +++ b/server/src/v1/auth.ts @@ -65,7 +65,7 @@ export function requireVerification(req: Request, res: Response, next: NextFunct } } -async function generateAuthToken(id: string) { +export async function generateAuthToken(id: string) { const token: Token = { id: id, type: authTokenType, @@ -90,31 +90,24 @@ auth.post('/register', async (req, res) => { const id = uuid(); const passwdHash = await hash(body.password, 10); const name = body.username.trim().toLowerCase(); - if (name.length >= 4) { - try { - const token = await generateAuthToken(id); - await database('users').insert({ - id: id, - user_name: name, - passwd_hash: passwdHash, - email: body.email ?? null, - real_name: body.realname ?? null, - }); - res.status(200).json({ - status: 'success', - token: token, - }); - } catch (e) { - // Fails if unique constraint for username is not met - res.status(400).json({ - status: 'error', - message: 'failed to create user', - }); - } - } else { + try { + const token = await generateAuthToken(id); + await database('users').insert({ + id: id, + user_name: name, + passwd_hash: passwdHash, + email: body.email ?? null, + real_name: body.realname ?? null, + }); + res.status(200).json({ + status: 'success', + token: token, + }); + } catch (e) { + // Fails if unique constraint for username is not met res.status(400).json({ status: 'error', - message: 'usernames must be four letters or longer', + message: 'failed to create user', }); } } else { diff --git a/server/src/v1/user.test.ts b/server/src/v1/user.test.ts index 269ea75..5587d6e 100644 --- a/server/src/v1/user.test.ts +++ b/server/src/v1/user.test.ts @@ -6,11 +6,8 @@ import { api } from '../api'; const request = supertest(api); test('non existant username returns 404 for /v1/user/name/', async () => { - const response = await request.get('/v1/user/name/__NO_REAL_NAME__'); + const response = await request.get('/v1/user/name/User3'); expect(response.status).toEqual(404); - expect(response.body).toEqual({ - status: 'error', - message: 'user not found', - }); + expect(response.body.status).toEqual('error'); }); -- GitLab