general code improvements
This commit is contained in:
@@ -4,21 +4,20 @@ import { ProjectService } from "../service/project.service";
|
||||
|
||||
const router = Router();
|
||||
|
||||
const BASE_PATH = "/projects";
|
||||
export const apiNamespace = "/projects";
|
||||
|
||||
export const getAllPath = BASE_PATH;
|
||||
router.get(getAllPath, async (req, res) => {
|
||||
router.get(apiNamespace, async (req, res) => {
|
||||
const projects = await ProjectService.listAllByUserId(req.userId)
|
||||
|
||||
const response: ProjectDto[] = projects.map<ProjectDto>(project => ({
|
||||
id: project.id,
|
||||
name: project.name
|
||||
}))
|
||||
|
||||
res.json(response)
|
||||
});
|
||||
|
||||
export const createPath = BASE_PATH;
|
||||
router.post(createPath, (req, res) => {
|
||||
router.post(apiNamespace, (req, res) => {
|
||||
const { name } = req.body;
|
||||
|
||||
ProjectService.create({
|
||||
@@ -26,6 +25,7 @@ router.post(createPath, (req, res) => {
|
||||
userId: req.userId
|
||||
}).then(project => {
|
||||
const respose: ProjectDto = {
|
||||
id: project.id,
|
||||
name: project.name
|
||||
}
|
||||
|
||||
@@ -37,4 +37,28 @@ router.post(createPath, (req, res) => {
|
||||
})
|
||||
});
|
||||
|
||||
router.delete(`${apiNamespace}/:id`, async (req, res, next) => {
|
||||
const { id } = req.params;
|
||||
const projectId = parseInt(id)
|
||||
|
||||
const userProjects = await ProjectService.listAllByUserId(req.userId)
|
||||
const projecToBeDeleted = userProjects.find(project => project.id === projectId)
|
||||
|
||||
if (projecToBeDeleted) {
|
||||
const success = await ProjectService.destroyProject(projecToBeDeleted)
|
||||
|
||||
if (success) {
|
||||
res.json({ success })
|
||||
} else {
|
||||
res.status(422).json({
|
||||
error: "Could not delete project"
|
||||
})
|
||||
}
|
||||
} else {
|
||||
res.status(404).json({
|
||||
error: "Project not found"
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
export const ProjectRoutes = router;
|
||||
|
||||
@@ -2,15 +2,12 @@ import { Router } from 'express';
|
||||
import { UserDto } from '../dto/user.dto';
|
||||
import { AuthService } from '../service/auth.service';
|
||||
import { UserService } from '../service/user.service';
|
||||
import { createPath as buildPath } from '../utils/createPath';
|
||||
|
||||
const router = Router();
|
||||
|
||||
const BASE_PATH = '/users'
|
||||
export const apiNamespace = '/users'
|
||||
|
||||
export const createPath = BASE_PATH
|
||||
|
||||
router.post(createPath, (req, res) => {
|
||||
router.post(apiNamespace, (req, res) => {
|
||||
const { email, password } = req.body;
|
||||
|
||||
UserService.create({
|
||||
@@ -30,8 +27,7 @@ router.post(createPath, (req, res) => {
|
||||
})
|
||||
})
|
||||
|
||||
export const signInPath = buildPath(BASE_PATH, 'sign_in')
|
||||
router.post(signInPath, async (req, res) => {
|
||||
router.post(`${apiNamespace}/sign_in`, async (req, res) => {
|
||||
const { email, password } = req.body;
|
||||
|
||||
const user = await UserService.findByEmail(email)
|
||||
@@ -53,8 +49,7 @@ router.post(signInPath, async (req, res) => {
|
||||
}
|
||||
})
|
||||
|
||||
export const signOutPath = buildPath(BASE_PATH, 'sign_out')
|
||||
router.delete(signOutPath, async (req, res) => {
|
||||
router.delete(`${apiNamespace}/sign_out`, async (req, res) => {
|
||||
const token = req.headers['x-access-token']
|
||||
|
||||
if (typeof token === 'string') {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export type ProjectDto = {
|
||||
id: number
|
||||
name: string
|
||||
}
|
||||
@@ -6,8 +6,12 @@ import { cleanDataSource } from "../../utils/cleanDataSource";
|
||||
describe("Project", () => {
|
||||
beforeAll(async () => {
|
||||
await AppDataSource.initialize();
|
||||
await cleanDataSource(AppDataSource, ["project", "user"]);
|
||||
await cleanDataSource(AppDataSource);
|
||||
});
|
||||
afterAll(async () => {
|
||||
await cleanDataSource(AppDataSource);
|
||||
await AppDataSource.destroy()
|
||||
})
|
||||
|
||||
describe("relations", () => {
|
||||
it("should have many projects", async () => {
|
||||
|
||||
@@ -7,8 +7,12 @@ import { User } from "../user.entity";
|
||||
describe("User", () => {
|
||||
beforeAll(async () => {
|
||||
await AppDataSource.initialize();
|
||||
await cleanDataSource(AppDataSource, ["project", "user"]);
|
||||
await cleanDataSource(AppDataSource);
|
||||
});
|
||||
afterAll(async () => {
|
||||
await cleanDataSource(AppDataSource);
|
||||
await AppDataSource.destroy()
|
||||
})
|
||||
|
||||
describe("relations", () => {
|
||||
it("should have many projects", async () => {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { signInPath, createPath } from '../../controller/users.controller';
|
||||
import { UNPROTECTED_ROUTES } from '../session.middleware'
|
||||
|
||||
describe('Unprotected Routes', () => {
|
||||
it('check content', () => {
|
||||
expect(UNPROTECTED_ROUTES.sort()).toEqual([createPath, signInPath].sort());
|
||||
import {isRouteUnprotected} from '../session.middleware'
|
||||
describe('isRouteUnprotected', () => {
|
||||
it('validate unprotected routes', () => {
|
||||
expect(isRouteUnprotected('/users')).toBeTruthy()
|
||||
expect(isRouteUnprotected('/users/sign_in')).toBeTruthy()
|
||||
expect(isRouteUnprotected('/users/sign_out')).toBeTruthy()
|
||||
expect(isRouteUnprotected('/projects')).toBeFalsy()
|
||||
})
|
||||
})
|
||||
@@ -1,14 +1,16 @@
|
||||
import { Handler, Request, Response } from 'express';
|
||||
import { RequestHandler } from 'express';
|
||||
import { verify } from 'jsonwebtoken';
|
||||
import { signInPath, createPath } from '../controller/user.controller';
|
||||
import { apiNamespace as userControllerNamespace } from '../controller/user.controller';
|
||||
import { AuthService } from '../service/auth.service';
|
||||
|
||||
export const UNPROTECTED_ROUTES = [signInPath, createPath];
|
||||
export const isRouteUnprotected = (path: string) => {
|
||||
return path.startsWith(userControllerNamespace)
|
||||
}
|
||||
|
||||
export const sessionMiddleware: Handler = (req: Request, res: Response, next) => {
|
||||
export const sessionMiddleware: RequestHandler = (req, res, next) => {
|
||||
const token = req.headers['x-access-token'];
|
||||
|
||||
if (UNPROTECTED_ROUTES.includes(req.url)) {
|
||||
if (isRouteUnprotected(req.url)) {
|
||||
next();
|
||||
} else if (typeof token === 'string') {
|
||||
AuthService.isSessionValid(token).then(valid => {
|
||||
|
||||
@@ -44,8 +44,6 @@ describe('AuthService', () => {
|
||||
});
|
||||
})
|
||||
|
||||
const currentUserEncryptedPassowrd = user.encryptedPassword
|
||||
|
||||
const result = await AuthService.isUserPasswordValid(user, 'example');
|
||||
|
||||
expect(result).toBeTruthy()
|
||||
@@ -66,8 +64,6 @@ describe('AuthService', () => {
|
||||
});
|
||||
})
|
||||
|
||||
const currentUserEncryptedPassowrd = user.encryptedPassword
|
||||
|
||||
const result = await AuthService.isUserPasswordValid(user, 'example2');
|
||||
|
||||
expect(result).toBeFalsy()
|
||||
|
||||
@@ -28,7 +28,17 @@ async function listAllByUserId(userId: User["id"]): Promise<Project[]> {
|
||||
return query.getMany();
|
||||
}
|
||||
|
||||
async function destroyProject(project: Project): Promise<boolean>{
|
||||
const query = projectRepository.createQueryBuilder();
|
||||
query.where('"id" = :projectId', { projectId: project.id });
|
||||
|
||||
const result = await query.delete().execute()
|
||||
|
||||
return result.affected > 0;
|
||||
}
|
||||
|
||||
export const ProjectService = {
|
||||
create,
|
||||
listAllByUserId,
|
||||
destroyProject
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@ import { DataSource } from "typeorm";
|
||||
|
||||
export const cleanDataSource = async (
|
||||
dataSource: DataSource,
|
||||
entityNames: string[]
|
||||
entityNames: string[] = ["project", "user"]
|
||||
) => {
|
||||
if (process.env.NODE_ENV !== "test") {
|
||||
throw new Error(
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
export const createPath = (...args: string[]): string => {
|
||||
return args.join('/')
|
||||
}
|
||||
Reference in New Issue
Block a user