From b266f4e826b466e0e8908c48285ce0e0fb47d700 Mon Sep 17 00:00:00 2001 From: Wasiu Bakare Date: Sun, 2 Mar 2025 15:38:45 +0100 Subject: [PATCH] refactor(http): rename statusCode to status_code and prevent email exposure in response body --- src/main.ts | 2 ++ .../newsletter-subscription.service.ts | 4 ++-- .../tests/newsletter-subscription.service.spec.ts | 9 ++------- src/shared/helpers/http-exception-filter.ts | 2 +- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/main.ts b/src/main.ts index adf0c73f6..390a76125 100644 --- a/src/main.ts +++ b/src/main.ts @@ -11,6 +11,7 @@ import { initializeDataSource } from '@database/data-source'; import { SeedingService } from '@database/seeding/seeding.service'; import { ResponseInterceptor } from '@shared/inteceptors/response.interceptor'; import { Request, Response } from 'express'; +import { HttpExceptionFilter } from '@shared/helpers/http-exception-filter'; async function bootstrap() { const app = await NestFactory.create(AppModule, { bufferLogs: true }); @@ -34,6 +35,7 @@ async function bootstrap() { app.enableCors(); app.setGlobalPrefix('api/v1', { exclude: ['/', 'health', 'api', 'api/v1', 'api/docs', 'probe'] }); app.useGlobalInterceptors(new ResponseInterceptor()); + app.useGlobalFilters(new HttpExceptionFilter()); const options = new DocumentBuilder() .setTitle('HNG Boilerplate') diff --git a/src/modules/newsletter-subscription/newsletter-subscription.service.ts b/src/modules/newsletter-subscription/newsletter-subscription.service.ts index 982486daf..b981bde33 100644 --- a/src/modules/newsletter-subscription/newsletter-subscription.service.ts +++ b/src/modules/newsletter-subscription/newsletter-subscription.service.ts @@ -78,13 +78,13 @@ export class NewsletterSubscriptionService { const subscription = await this.newsletterSubscriptionRepository.findOne({ where: { email } }); if (!subscription) { - throw new NotFoundException(`Email ${email} not found in the subscription list`); + throw new NotFoundException('Email not found in the subscription list'); } subscription.isUnsubscribed = true; await this.newsletterSubscriptionRepository.save(subscription); - return { message: `Email ${email} has been unsubscribed successfully` }; + return { message: 'Email has been unsubscribed successfully' }; } async resubscribe(dto: ResubscribeNewsletterDto): Promise<{ message: string }> { const { id, email } = dto; diff --git a/src/modules/newsletter-subscription/tests/newsletter-subscription.service.spec.ts b/src/modules/newsletter-subscription/tests/newsletter-subscription.service.spec.ts index 87a11818c..23b95257a 100644 --- a/src/modules/newsletter-subscription/tests/newsletter-subscription.service.spec.ts +++ b/src/modules/newsletter-subscription/tests/newsletter-subscription.service.spec.ts @@ -152,9 +152,7 @@ describe('NewsletterService', () => { const email = 'test@example.com'; const mockSubscription = { id: '1', email, isUnsubscribed: false } as NewsletterSubscription; - // Mock `findOne` to return a subscribed user jest.spyOn(repository, 'findOne').mockResolvedValue(mockSubscription); - // Mock `save` to return updated object jest.spyOn(repository, 'save').mockImplementation( async sub => ({ @@ -169,21 +167,18 @@ describe('NewsletterService', () => { ); const result = await service.unsubscribe(email); - expect(result).toEqual({ message: `Email ${email} has been unsubscribed successfully` }); + expect(result).toEqual({ message: 'Email has been unsubscribed successfully' }); - // Ensure `isUnsubscribed` was updated expect(repository.save).toHaveBeenCalledWith(expect.objectContaining({ isUnsubscribed: true })); }); it('should throw NotFoundException if email is not found', async () => { const email = 'notfound@example.com'; - // Mock `findOne` to return null jest.spyOn(repository, 'findOne').mockResolvedValue(null); - // Expecting an error await expect(service.unsubscribe(email)).rejects.toThrow( - new NotFoundException(`Email ${email} not found in the subscription list`) + new NotFoundException('Email not found in the subscription list') ); expect(repository.findOne).toHaveBeenCalledWith({ where: { email } }); diff --git a/src/shared/helpers/http-exception-filter.ts b/src/shared/helpers/http-exception-filter.ts index d66931a20..21e4f94a8 100644 --- a/src/shared/helpers/http-exception-filter.ts +++ b/src/shared/helpers/http-exception-filter.ts @@ -35,7 +35,7 @@ export class HttpExceptionFilter implements ExceptionFilter { const error = typeof exceptionResponse === 'string' ? '' : (exceptionResponse as ExceptionResponse).error; response.status(status).json({ - status, + status_code: status, error: error, message: errorMessage, });