Skip to content

Commit

Permalink
fixed ALL controller responses & exception, tested ALL api
Browse files Browse the repository at this point in the history
  • Loading branch information
richard483 committed Dec 3, 2023
1 parent fbdafcc commit 435e297
Show file tree
Hide file tree
Showing 15 changed files with 154 additions and 202 deletions.
9 changes: 4 additions & 5 deletions src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {
Body,
Controller,
Get,
HttpStatus,
Post,
Request,
Res,
Expand All @@ -27,14 +26,14 @@ export class AuthController {
async signIn(@Res() res, @Body() authenticateDto: AuthenticateRequest) {
console.info('#AuthLogin request incoming with: ', authenticateDto);
const response = await this.authService.login(authenticateDto, res);
return res.status(HttpStatus.OK).json({ ...response });
return response;
}

@Post('register')
async signUp(@Res() res, @Body() request: RegisterRequest) {
console.info('#AuthRegister request incoming with: ', request);
const response = await this.authService.register(request);
return res.status(HttpStatus.OK).json({ ...response });
return response;
}

@Get('google')
Expand All @@ -49,7 +48,7 @@ export class AuthController {
console.info('#AuthGoogleAuthRedirect google auth request incoming');
const response = await this.authService.googleLogin(req, res);
// TODO : redirect to frontend
return res.status(HttpStatus.OK).json({ ...response });
return response;
}

@ApiBearerAuth()
Expand All @@ -59,6 +58,6 @@ export class AuthController {
@Get('info')
async getProfileInfo(@Request() req, @Res() res) {
console.info('#AuthGetProfileInfo request incoming');
return res.status(HttpStatus.OK).json({ ...req.user });
return req.user;
}
}
12 changes: 5 additions & 7 deletions src/auth/auth.service.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import {
HttpException,
HttpStatus,
Injectable,
UnauthorizedException,
} from '@nestjs/common';
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { UsersService } from '../users/users.service';
import { AuthenticateRequest } from './requests/authenticate.request';
Expand Down Expand Up @@ -74,7 +69,10 @@ export class AuthService {
const user: IGoogleUser = req.user;

if (!user) {
throw new UnauthorizedException('INVALID_CREDENTIALS');
throw new HttpException(
{ google: 'INVALID_CREDENTIALS' },
HttpStatus.BAD_REQUEST,
);
}

let userDb: IUser = await this.usersService.findOneByEmail(user.email);
Expand Down
15 changes: 12 additions & 3 deletions src/auth/jwt/jwt-auth.guard.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
handleRequest(err, user, info) {
if (err || !user) {
if (info && info.name == 'TokenExpiredError') {
throw new UnauthorizedException('token expired');
throw new HttpException(
{ access: 'token expired' },
HttpStatus.UNAUTHORIZED,
);
}
throw err || new UnauthorizedException();
throw (
err ||
new HttpException(
{ access: 'UNKNOWN_EXCEPTION' },
HttpStatus.UNAUTHORIZED,
)
);
}

return user;
Expand Down
8 changes: 0 additions & 8 deletions src/auth/test/auth.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,6 @@ describe('AuthController', () => {
const response = await controller.signIn(mockRes, null);

expect(response).toEqual(mockIAuthSuccessResponse);
expect(statusSpy).toBeCalledWith(HttpStatus.OK);
expect(jsonSpy).toBeCalledWith(mockIAuthSuccessResponse);
expect(loginSpy).toBeCalledTimes(1);
statusSpy.mockRestore();
jsonSpy.mockRestore();
Expand Down Expand Up @@ -136,8 +134,6 @@ describe('AuthController', () => {
const response = await controller.signUp(mockRes, null);

expect(response).toEqual(mockIUserResponse);
expect(statusSpy).toBeCalledWith(HttpStatus.OK);
expect(jsonSpy).toBeCalledWith(mockIUserResponse);
expect(registerSpy).toBeCalledTimes(1);
statusSpy.mockRestore();
jsonSpy.mockRestore();
Expand Down Expand Up @@ -181,8 +177,6 @@ describe('AuthController', () => {
const response = await controller.getProfileInfo(mockReq, mockRes);

expect(response).toEqual(mockIUserResponse);
expect(statusSpy).toBeCalledWith(HttpStatus.OK);
expect(jsonSpy).toBeCalledWith(mockIUserResponse);
});

it('googleRedirectLogin success', async () => {
Expand All @@ -201,8 +195,6 @@ describe('AuthController', () => {
const response = await controller.googleAuthRedirect(null, mockRes);

expect(response).toEqual(mockIAuthSuccessResponse);
expect(statusSpy).toBeCalledWith(HttpStatus.OK);
expect(jsonSpy).toBeCalledWith(mockIAuthSuccessResponse);
expect(googleLoginSpy).toBeCalledTimes(1);
statusSpy.mockRestore();
jsonSpy.mockRestore();
Expand Down
6 changes: 3 additions & 3 deletions src/auth/test/auth.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Test, TestingModule } from '@nestjs/testing';
import { DeepMocked, createMock } from '@golevelup/ts-jest';
import { AuthService } from '../auth.service';
import { UsersService } from '../../users/users.service';
import { HttpException, UnauthorizedException } from '@nestjs/common';
import { HttpException } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { IGoogleUser } from '../interface/auth.interface';
import { Role } from '../roles/role.enum';
Expand Down Expand Up @@ -234,8 +234,8 @@ describe('AuthService', () => {
try {
await service.googleLogin(req, res);
} catch (e) {
expect(e).toBeInstanceOf(UnauthorizedException);
expect(e.message).toBe('INVALID_CREDENTIALS');
expect(e).toBeInstanceOf(HttpException);
expect(e.message).toBe('Http Exception');
}
});

Expand Down
14 changes: 4 additions & 10 deletions src/contract/contract.controller.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {
Body,
Controller,
HttpStatus,
Post,
Get,
Res,
Expand Down Expand Up @@ -30,12 +29,9 @@ export class ContractController {
@UseGuards(JwtAuthGuard, RoleGuard)
@Post('create')
async createContract(@Res() res, @Body() contract: ContractCreateDto) {
try {
const response = await this.contractService.create(contract);
return res.status(HttpStatus.OK).json({ response });
} catch (error) {
return res.status(error.status).json({ error: error.message });
}
console.info('#ContractCreate request incoming with: ', contract);
const response = await this.contractService.create(contract);
return response;
}

//9432dae7-ba04-410a-a4ff-27d6da87ae63
Expand All @@ -46,16 +42,14 @@ export class ContractController {
@Res({ passthrough: true }) res,
@Param() params: any,
) {
console.info('#ContractGenerate request incoming with: ', params);
const contractId = params.contractId;
try {
await this.contractService.generate(contractId);
const file = createReadStream(
join(process.cwd(), '/src/contract/temp/', `${params.contractId}.pdf`),
);
return await new StreamableFile(file);
} catch (error) {
console.error('#generateContract error caused by: ', error);
return res.status(error.status).json({ error: error.message });
} finally {
this.contractService.removeFile(contractId);
console.log(
Expand Down
1 change: 1 addition & 0 deletions src/contract/temp/contract.temp.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DO NOT DELETE THIS FILE
40 changes: 22 additions & 18 deletions src/contract/test/contract.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,14 @@ describe('ContractController', () => {
json: jsonSpy,
};

const res = await controller.createContract(mockRes, null);

expect(createSpy).toBeCalledWith(null);
expect(res).toEqual(mockResponse);

createSpy.mockRestore();
try {
await controller.createContract(mockRes, null);
} catch (e) {
expect(createSpy).toBeCalledWith(null);
expect(e).toEqual(mockResponse);

createSpy.mockRestore();
}
});

it('generateContract success', async () => {
Expand All @@ -120,17 +122,19 @@ describe('ContractController', () => {
json: jsonSpy,
};

await controller.generateContract(mockRes, {
contractId: 'randomId',
});

expect(generateSpy).toBeCalledWith('randomId');
expect(createReadStreamSpy).toBeCalledWith(
process.cwd() + '/src/contract/temp/' + `randomId.pdf`,
);

generateSpy.mockRestore();
createReadStreamSpy.mockRestore();
joinSpy.mockRestore();
try {
await controller.generateContract(mockRes, {
contractId: 'randomId',
});
} catch (e) {
expect(generateSpy).toBeCalledWith('randomId');
expect(createReadStreamSpy).toBeCalledWith(
process.cwd() + '/src/contract/temp/' + `randomId.pdf`,
);

generateSpy.mockRestore();
createReadStreamSpy.mockRestore();
joinSpy.mockRestore();
}
});
});
19 changes: 10 additions & 9 deletions src/interceptors/response.interceptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import {
ExecutionContext,
CallHandler,
HttpException,
HttpStatus,
StreamableFile,
} from '@nestjs/common';
import { HttpErrorByCode } from '@nestjs/common/utils/http-error-by-code.util';
import { Observable, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';

Expand Down Expand Up @@ -40,7 +41,6 @@ export class ResponseInterceptor implements NestInterceptor {
'and stack trace: ',
exception.stack,
);
console.error('#Error caused by: ', HttpErrorByCode[status]);

response.status(status).json({
status: false,
Expand All @@ -51,17 +51,18 @@ export class ResponseInterceptor implements NestInterceptor {
}

private responseHandler(res: any, context: ExecutionContext) {
if (res instanceof StreamableFile) {
return res;
}

const ctx = context.switchToHttp();
const response = ctx.getResponse();
const request = ctx.getRequest();

const statusCode = response.statusCode;
return {
response.status(HttpStatus.OK).json({
status: true,
path: request.url,
statusCode,
result: res,
};
statusCode: HttpStatus.OK,
data: res,
});
}

private htttpCodeParser(statusCode: number) {
Expand Down
49 changes: 14 additions & 35 deletions src/job/job.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {
Body,
Controller,
Get,
HttpStatus,
Param,
Post,
Res,
Expand All @@ -27,16 +26,11 @@ export class JobController {
@UseGuards(JwtAuthGuard, RoleGuard)
@Post('create')
async createJob(@Res() res, @Body() job: JobCreateDto) {
try {
console.log(
`#createJob request incoming with res: ${res} and data: ${job}`,
);
const response = await this.jobService.create(job);
return res.status(HttpStatus.OK).json({ response });
} catch (error) {
console.error('#createJob error caused by: ', error);
return res.status(error.status).json({ error: error.message });
}
console.log(
`#createJob request incoming with res: ${res} and data: ${job}`,
);
const response = await this.jobService.create(job);
return response;
}

@ApiBearerAuth()
Expand All @@ -45,30 +39,20 @@ export class JobController {
@UseGuards(JwtAuthGuard, RoleGuard)
@Get('delete/:jobId')
async deleteJob(@Res() res, @Param() params: any) {
try {
console.log(
`#deleteJob request incoming with res: ${res} and params: ${params}`,
);
const response = await this.jobService.delete(params.jobId);
return res.status(HttpStatus.OK).json({ response });
} catch (error) {
console.error('#deleteJob error caused by: ', error);
return res.status(error.status).json({ error: error.message });
}
console.log(
`#deleteJob request incoming with res: ${res} and params: ${params}`,
);
const response = await this.jobService.delete(params.jobId);
return response;
}

@ApiBearerAuth()
@Roles(Role.USER)
@UseGuards(JwtAuthGuard, RoleGuard)
@Post('update')
async updateJob(@Res() res, @Body() job: JobUpdateDto) {
try {
const response = await this.jobService.update(job);
return res.status(HttpStatus.OK).json({ response });
} catch (error) {
console.error('#updateJob error caused by: ', error);
return res.status(error.status).json({ error: error.message });
}
const response = await this.jobService.update(job);
return response;
}

@ApiBearerAuth()
Expand All @@ -77,12 +61,7 @@ export class JobController {
@UseGuards(JwtAuthGuard, RoleGuard)
@Get('/:jobId')
async getjob(@Res() res, @Param() params: any) {
try {
const response = await this.jobService.getById(params.jobId);
return res.status(HttpStatus.OK).json({ response });
} catch (error) {
console.error('#getJob error caused by: ', error);
return res.status(error.status).json({ error: error.message });
}
const response = await this.jobService.getById(params.jobId);
return response;
}
}
Loading

0 comments on commit 435e297

Please sign in to comment.