UNPKG

express-generator-typescript

Version:

Generate new Express applications similar to express-generate which but sets it up to use TypeScript instead

186 lines (159 loc) 6.3 kB
import supertest from 'supertest'; import insertUrlParams from 'inserturlparams'; import { customDeepCompare } from 'jet-validators/utils'; import app from '@src/server'; import UserRepo from '@src/repos/UserRepo'; import User, { IUser } from '@src/models/User'; import { USER_NOT_FOUND_ERR } from '@src/services/UserService'; import HttpStatusCodes from '@src/common/HttpStatusCodes'; import { ValidationError } from '@src/common/route-errors'; import Paths from 'spec/support/Paths'; import { cleanDatabase, parseValidationErr, TRes } from 'spec/support'; /****************************************************************************** Variables ******************************************************************************/ // Dummy users for GET req const DB_USERS = [ User.new({ name: 'Sean Maxwell', email: 'sean.maxwell@gmail.com' }), User.new({ name: 'John Smith', email: 'john.smith@gmail.com' }), User.new({ name: 'Gordan Freeman', email: 'gordan.freeman@gmail.com' }), ] as const; // Don't compare "id" and "created" cause those are set dynamically by the // database const compareUserArrays = customDeepCompare({ onlyCompareProps: ['name', 'email'], }); /****************************************************************************** Tests IMPORTANT: Following TypeScript best practices, we test all scenarios that can be triggered by a user under normal circumstances. Not all theoretically scenarios (i.e. a failed database connection). ******************************************************************************/ describe('UserRouter', () => { const agent = supertest.agent(app); let dbUsers: IUser[] = []; // Run before all tests beforeEach(async () => { await cleanDatabase(); dbUsers = await UserRepo.insertMult(DB_USERS); }); // Get all users describe(`"GET:${Paths.Users.Get}"`, () => { // Success it('should return a JSON object with all the users and a status code ' + `of "${HttpStatusCodes.OK}" if the request was successful.`, done => { agent .get(Paths.Users.Get) .end((_, res: TRes<{ users: IUser[]}>) => { expect(res.status).toBe(HttpStatusCodes.OK); expect(compareUserArrays(res.body.users, DB_USERS)).toBeTruthy(); done(); }); }); }); // Test add user describe(`"POST:${Paths.Users.Add}"`, () => { // Test add user success it(`should return a status code of "${HttpStatusCodes.CREATED}" if the ` + 'request was successful.', done => { const user = User.new({ name: 'a', email: 'a@a.com' }); agent .post(Paths.Users.Add) .send({ user }) .end((_, res) => { expect(res.status).toBe(HttpStatusCodes.CREATED); done(); }); }); // Missing param it('should return a JSON object with an error message of and a status ' + `code of "${HttpStatusCodes.BAD_REQUEST}" if the user param was ` + 'missing.', done => { agent .post(Paths.Users.Add) .send({ user: null }) .end((_, res: TRes) => { expect(res.status).toBe(HttpStatusCodes.BAD_REQUEST); const errorObj = parseValidationErr(res.body.error); expect(errorObj.message).toBe(ValidationError.MESSAGE); expect(errorObj.errors[0].prop).toBe('user'); done(); }); }); }); // Update users describe(`"PUT:${Paths.Users.Update}"`, () => { // Success it(`should return a status code of "${HttpStatusCodes.OK}" if the ` + 'request was successful.', done => { const user = DB_USERS[0]; user.name = 'Bill'; agent .put(Paths.Users.Update) .send({ user }) .end((_, res) => { expect(res.status).toBe(HttpStatusCodes.OK); done(); }); }); // Id is the wrong data type it('should return a JSON object with an error message and a status code ' + `of "${HttpStatusCodes.BAD_REQUEST}" if the user param was missing`, done => { const user = User.new(); user.id = ('5' as unknown as number); agent .put(Paths.Users.Update) .send({ user }) .end((_, res: TRes) => { expect(res.status).toBe(HttpStatusCodes.BAD_REQUEST); const errorObj = parseValidationErr(res.body.error); expect(errorObj.message).toBe(ValidationError.MESSAGE); expect(errorObj.errors[0].prop).toBe('user'); expect(errorObj.errors[0].children?.[0].prop).toBe('id'); done(); }); }); // User not found it('should return a JSON object with the error message of ' + `"${USER_NOT_FOUND_ERR}" and a status code of ` + `"${HttpStatusCodes.NOT_FOUND}" if the id was not found.`, done => { const user = User.new({ id: 4, name: 'a', email: 'a@a.com' }); agent .put(Paths.Users.Update) .send({ user }) .end((_, res: TRes) => { expect(res.status).toBe(HttpStatusCodes.NOT_FOUND); expect(res.body.error).toBe(USER_NOT_FOUND_ERR); done(); }); }); }); // Delete User describe(`"DELETE:${Paths.Users.Delete}"`, () => { const getPath = (id: number) => insertUrlParams(Paths.Users.Delete, { id }); // Success it(`should return a status code of "${HttpStatusCodes.OK}" if the ` + 'request was successful.', done => { const id = dbUsers[0].id; agent .delete(getPath(id)) .end((_, res) => { expect(res.status).toBe(HttpStatusCodes.OK); done(); }); }); // User not found it('should return a JSON object with the error message of ' + `"${USER_NOT_FOUND_ERR}" and a status code of ` + `"${HttpStatusCodes.NOT_FOUND}" if the id was not found.`, done => { agent .delete(getPath(-1)) .end((_, res: TRes) => { expect(res.status).toBe(HttpStatusCodes.NOT_FOUND); expect(res.body.error).toBe(USER_NOT_FOUND_ERR); done(); }); }); }); });