more work on testing

This commit is contained in:
Mikayla Dobson
2022-12-17 12:22:03 -06:00
parent a38bc2793f
commit 27e6b4aa1f
14 changed files with 96 additions and 62 deletions

View File

@@ -1,10 +1,11 @@
import { NextFunction, Request, Response } from "express" import { NextFunction, Request, Response } from "express"
import { StatusCode } from "../util/types";
export function restrictAccess(req: Request, res: Response, next: NextFunction) { export function restrictAccess(req: Request, res: Response, next: NextFunction) {
if (req.isAuthenticated()) { if (req.isAuthenticated()) {
next(); next();
} else { } else {
res.send({ ok: false, user: undefined }) res.status(StatusCode.Forbidden).send({ ok: false, user: undefined })
} }
} }

View File

@@ -12,7 +12,8 @@ export default async function populate() {
('Emily', 'Dobson', 'emjdobson', 'emily@email.com', 'password2', true, false, $1, $1), ('Emily', 'Dobson', 'emjdobson', 'emily@email.com', 'password2', true, false, $1, $1),
('Montanna', 'Dobson', 'delayedlemon', 'montanna@email.com', 'password3', true, false, $1, $1), ('Montanna', 'Dobson', 'delayedlemon', 'montanna@email.com', 'password3', true, false, $1, $1),
('Christine', 'Riley', 'christine', 'christine@email.com', 'password4', true, false, $1, $1), ('Christine', 'Riley', 'christine', 'christine@email.com', 'password4', true, false, $1, $1),
('Someone', 'Not active', 'someone', 'someone@email.com', 'notactive', false, false, $1, $1) ('Someone', 'Not active', 'someone', 'someone@email.com', 'notactive', false, false, $1, $1),
('Verified', 'User', 'verifiedtestuser', 'verifieduser@test.com','$2a$10$7j1tE9mL3qAIMG8vwLsb2u1Mm3DC/7EdJI/X7KDBbQ9c34KmnLEMq', false, false, $1, $1)
; ;
` `
@@ -43,7 +44,8 @@ export default async function populate() {
('Pad Thai', 'noodles', '1 hour', 1, 1, 3, $1, $1), ('Pad Thai', 'noodles', '1 hour', 1, 1, 3, $1, $1),
('Tacos', null, '30 minutes', 1, 3, 3, $1, $1), ('Tacos', null, '30 minutes', 1, 3, 3, $1, $1),
('Garlic knots', null, '1 hour', 4, 4, 3, $1, $1), ('Garlic knots', null, '1 hour', 4, 4, 3, $1, $1),
('Cacio e pepe', 'stinky pasta', '1 hour', 3, 4, 3, $1, $1) ('Cacio e pepe', 'stinky pasta', '1 hour', 3, 4, 3, $1, $1),
('Green beans', 'green beans', '30 minutes', 6, 1, 1, $1, $1)
; ;
` `
@@ -52,7 +54,8 @@ export default async function populate() {
(name, active, ismaincollection, ownerid, datecreated, datemodified) (name, active, ismaincollection, ownerid, datecreated, datemodified)
VALUES VALUES
('Mikayla''s collection', true, true, 1, $1, $1), ('Mikayla''s collection', true, true, 1, $1, $1),
('Emily''s collection', true, true, 2, $1, $1) ('Emily''s collection', true, true, 2, $1, $1),
('Verified user collection', true, true, 6, $1, $1)
; ;
` `
@@ -99,9 +102,9 @@ export default async function populate() {
` `
const allStatements: Array<string> = [ const allStatements: Array<string> = [
populateUsers, populateCuisines, populateCourses, populateRecipes, populateUsers, populateCuisines, populateCourses,
populateCollection, populateIngredients, populateGroceryList, populateCollection, populateIngredients, populateRecipes,
populateFriendships, populateComments populateGroceryList, populateFriendships, populateComments
]; ];
await pool.query(setup); await pool.query(setup);

View File

@@ -1,23 +1,21 @@
import express from 'express'; import express from 'express';
import path from 'path';
import cors from 'cors'; import cors from 'cors';
import dotenv from 'dotenv'; import dotenv from 'dotenv';
dotenv.config();
import { loaders } from './loaders'; import { loaders } from './loaders';
dotenv.config();
const port = 8080; const port = 8080;
const app = express(); const app = express();
app.use(cors()); app.use(cors());
export const appRoot = path.resolve(__dirname); async function main() {
export default async function main() {
const app = express();
await loaders(app); await loaders(app);
app.listen(port, () => { app.listen(port, () => {
console.log('listening on port ' + port); console.log('listening on port ' + port);
}) })
}; };
export default app;
main(); main();

View File

@@ -1,19 +1,8 @@
import request from 'supertest'; export default function loginUser(server: any) {
server.post('/auth/login')
const agent = request('localhost:8080'); .send({ email: 'verifieduser@test.com', password: 'coolpassword' })
.end((err: any, res: Response) => {
export default async function loginUser(auth: { token: any }) { if (err) throw err;
const onResponse = (err: any, res: any) => { expect(res.status).toBe(200);
if (err) throw err; })
auth.token = res.body.token;
}
agent.post('/auth/login')
.send({
email: "verifieduser@test.com",
password: "verifieduser"
})
.end(onResponse);
return auth;
} }

View File

@@ -0,0 +1,3 @@
export default function logoutUser(server: any) {
server.delete('/auth/logout');
}

View File

@@ -0,0 +1,23 @@
import dotenv from 'dotenv';
import supertest from "supertest";
import loginUser from '../../helpers/loginUser';
dotenv.config();
const APISTRING = process.env.APISTRING || 'localhost:8080';
const server = supertest.agent(APISTRING);
describe('/auth', () => {
// beforeAll(() => {
// loginUser(server);
// })
// it('receives a token', () => {
// })
// test('allows access to protected resources', async () => {
// const data = await supertest(APISTRING).get('/recipe');
// console.log(data.body);
// expect(data.statusCode).toBe(200);
// // expect(data.body.name).toBe("Green beans");
// })
})

View File

@@ -1,23 +1,27 @@
import request from 'supertest' import supertest from 'supertest'
import loginUser from '../../helpers/loginUser';
import { IRecipe } from '../../../schemas' import { IRecipe } from '../../../schemas'
import dotenv from 'dotenv';
const server = request.agent('localhost:8080'); import app from '../../..';
dotenv.config();
const APISTRING = process.env.APISTRING || 'localhost:8080';
const server = supertest.agent(app);
describe('/recipe', () => { describe('/recipe', () => {
beforeAll(async () => { beforeAll(() => {
// to do: create session user, server.post('/auth/login')
// use it to log in on this test, .send({ email: 'verifieduser@test.com', password: 'coolpassword' });
// use the authenticated session to view recipes
// await server.post('/auth/login')
// .body()
}) })
describe('GET /', () => { describe('GET /', () => {
test('gets an array of recipes', async () => { it('gets an array of recipes', () => {
const result = await request('localhost:8080').get('/recipe'); server.get('/recipe').end((err, res) => {
const data = JSON.parse(result.text); if (err) throw err;
expect(data.length).toBeGreaterThan(0); console.log(res.body);
}) expect(res.statusCode).toBe(200);
}) expect(res.body.ok).toBeTruthy();
}) });
});
});
});

View File

@@ -1,13 +1,19 @@
import loginUser from "../../helpers/loginUser" import supertest from "supertest";
import loginUser from '../../helpers/loginUser';
import dotenv from 'dotenv';
dotenv.config();
const APISTRING = process.env.APISTRING || 'localhost:8080';
const server = supertest.agent(APISTRING);
describe('login user', () => { describe('login user', () => {
let auth = { token: undefined } beforeAll(() => {
beforeAll(async () => { loginUser(server);
auth = await loginUser(auth);
}) })
it('authenticates a hard-coded user', () => { it('allows access to protected resources', () => {
console.log(auth); server.get('/recipe').end((err, res) => {
expect(auth.token).toBeDefined(); if (err) throw err;
expect(res.statusCode).toBe(200);
})
}) })
}) })

View File

@@ -3,8 +3,9 @@ import swaggerUI from 'swagger-ui-express';
import yaml from 'js-yaml'; import yaml from 'js-yaml';
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import { appRoot } from '../appRoot';
const swaggerDocument = yaml.load(fs.readFileSync(path.resolve(__dirname, '../swagger.yaml'), 'utf-8')); const swaggerDocument = yaml.load(fs.readFileSync(path.resolve(appRoot, './swagger.yaml'), 'utf-8'));
export const swaggerLoader = async (app: Express) => { export const swaggerLoader = async (app: Express) => {
app.use('/api-docs', swaggerUI.serve, swaggerUI.setup(swaggerDocument!)); app.use('/api-docs', swaggerUI.serve, swaggerUI.setup(swaggerDocument!));

View File

@@ -4,10 +4,9 @@
"description": "REST API for recipe manager", "description": "REST API for recipe manager",
"main": "dist/index.js", "main": "dist/index.js",
"scripts": { "scripts": {
"build": "rm -rf dist && ./node_modules/.bin/tsc --project ./tsconfig.json", "build": "bash util/build.sh",
"seed": "npm run build && ts-node-dev db/seed.ts", "seed": "npm run build && ts-node-dev db/seed.ts",
"populate": "npm run build && node dist/db/examplevals.js", "dev": "bash util/dev.sh",
"dev": "rm -rf dist && ./node_modules/.bin/tsc --project ./tsconfig.json --watch & ts-node-dev index.ts",
"prod": "npm run build && node dist/index.js", "prod": "npm run build && node dist/index.js",
"test": "jest --coverage", "test": "jest --coverage",
"test:watch": "jest --watch", "test:watch": "jest --watch",

View File

@@ -21,7 +21,7 @@ export const recipeRoute = (app: Express) => {
} }
}) })
router.get('/', async (req, res, next) => { router.get('/', restrictAccess, async (req, res, next) => {
const { user }: any = req.user; const { user }: any = req.user;
const { filterby } = req.query; const { filterby } = req.query;

View File

@@ -17,7 +17,8 @@
} }
}, },
"include": [ "include": [
"**/*" "**/*",
"swagger.yaml"
], ],
"exclude": [ "exclude": [
"node_modules", "node_modules",

3
server/util/build.sh Normal file
View File

@@ -0,0 +1,3 @@
#! /bin/bash
rm -rf dist && mkdir -p dist && cp ./swagger.yaml ./dist && ./node_modules/.bin/tsc --project ./tsconfig.json

3
server/util/dev.sh Normal file
View File

@@ -0,0 +1,3 @@
#! /bin/bash
rm -rf dist && mkdir -p dist && cp ./swagger.yaml ./dist && ./node_modules/.bin/tsc --project ./tsconfig.json --watch & ts-node-dev index.ts