-
Notifications
You must be signed in to change notification settings - Fork 0
[SSF 172] - Food Request Edit & Delete Endpoints #147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| import { | ||
| ArrayNotEmpty, | ||
| IsEnum, | ||
| IsNotEmpty, | ||
| IsOptional, | ||
| IsString, | ||
| } from 'class-validator'; | ||
| import { RequestSize } from '../types'; | ||
| import { FoodType } from '../../donationItems/types'; | ||
|
|
||
| export class UpdateRequestDto { | ||
| @IsOptional() | ||
| @IsEnum(RequestSize) | ||
| requestedSize?: RequestSize; | ||
|
|
||
| @IsOptional() | ||
| @ArrayNotEmpty() | ||
| @IsEnum(FoodType, { each: true }) | ||
| requestedFoodTypes?: FoodType[]; | ||
|
|
||
| @IsOptional() | ||
| @IsString() | ||
| @IsNotEmpty() | ||
| additionalInformation?: string; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,9 +11,9 @@ import { FoodType } from '../donationItems/types'; | |
| import { DonationItem } from '../donationItems/donationItems.entity'; | ||
| import { testDataSource } from '../config/typeormTestDataSource'; | ||
| import { | ||
| BadRequestException, | ||
| InternalServerErrorException, | ||
| NotFoundException, | ||
| BadRequestException, | ||
| } from '@nestjs/common'; | ||
| import { EmailsService } from '../emails/email.service'; | ||
| import { mock } from 'jest-mock-extended'; | ||
|
|
@@ -582,6 +582,137 @@ describe('RequestsService', () => { | |
| ); | ||
| }); | ||
| }); | ||
|
|
||
| describe('update', () => { | ||
| it('should update request attributes', async () => { | ||
| await testDataSource.query( | ||
| `DELETE FROM allocations WHERE order_id IN (SELECT order_id FROM orders WHERE request_id = 1)`, | ||
| ); | ||
| await testDataSource.query(`DELETE FROM orders WHERE request_id = 1`); | ||
|
|
||
| const result = await service.update(1, { | ||
| requestedSize: RequestSize.MEDIUM, | ||
| }); | ||
|
|
||
| expect(result.requestedSize).toBe(RequestSize.MEDIUM); | ||
| expect(result.requestedFoodTypes).toEqual([ | ||
| FoodType.SEED_BUTTERS, | ||
| FoodType.GLUTEN_FREE_BREAD, | ||
| FoodType.DRIED_BEANS, | ||
| FoodType.DAIRY_FREE_ALTERNATIVES, | ||
| ]); | ||
|
|
||
| const fromDb = await testDataSource | ||
| .getRepository(FoodRequest) | ||
| .findOneBy({ requestId: 1 }); | ||
| expect(fromDb?.requestedSize).toBe(RequestSize.MEDIUM); | ||
| }); | ||
|
|
||
| it('should throw NotFoundException when request is not found', async () => { | ||
| await expect( | ||
| service.update(9999, { requestedSize: RequestSize.MEDIUM }), | ||
| ).rejects.toThrow(new NotFoundException('Request 9999 not found')); | ||
| }); | ||
|
|
||
| it('should update all request attributes when all fields are provided', async () => { | ||
| await testDataSource.query( | ||
| `DELETE FROM allocations WHERE order_id IN (SELECT order_id FROM orders WHERE request_id = 1)`, | ||
| ); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we add a test that has other fields in the dto which will be whitelisted from the validation pipe setting - meaning payload with fields we didn't define (ex. pantryid) will be ignored
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sorry, i got a chance to look more into it, and i feel like this test is not really necessary. we know that the whitelisting works from the main.ts code:
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thanks for looking into it. that makes sense, i'll note to test that in a future ticket! |
||
| await testDataSource.query(`DELETE FROM orders WHERE request_id = 1`); | ||
|
|
||
| const result = await service.update(1, { | ||
| requestedSize: RequestSize.SMALL, | ||
| requestedFoodTypes: [FoodType.GRANOLA], | ||
| additionalInformation: 'Updated information', | ||
| }); | ||
|
|
||
| expect(result.requestedSize).toBe(RequestSize.SMALL); | ||
| expect(result.requestedFoodTypes).toEqual([FoodType.GRANOLA]); | ||
| expect(result.additionalInformation).toBe('Updated information'); | ||
|
|
||
| const fromDb = await testDataSource | ||
| .getRepository(FoodRequest) | ||
| .findOneBy({ requestId: 1 }); | ||
| expect(fromDb?.requestedSize).toBe(RequestSize.SMALL); | ||
| expect(fromDb?.requestedFoodTypes).toEqual([FoodType.GRANOLA]); | ||
| expect(fromDb?.additionalInformation).toBe('Updated information'); | ||
| }); | ||
|
|
||
| it('should throw BadRequestException when request is not active', async () => { | ||
| await testDataSource.query( | ||
| `UPDATE food_requests SET status = 'closed' WHERE request_id = 1`, | ||
| ); | ||
|
|
||
| await expect( | ||
| service.update(1, { requestedSize: RequestSize.MEDIUM }), | ||
| ).rejects.toThrow( | ||
| new BadRequestException( | ||
| `Request must be ${FoodRequestStatus.ACTIVE} in order to be updated`, | ||
| ), | ||
| ); | ||
| }); | ||
|
|
||
| it('should throw BadRequestException when request has orders', async () => { | ||
| await expect( | ||
| service.update(2, { requestedSize: RequestSize.MEDIUM }), | ||
| ).rejects.toThrow( | ||
| new BadRequestException( | ||
| `Request 2 cannot be updated if it still has orders associated with it`, | ||
| ), | ||
| ); | ||
| }); | ||
|
|
||
| it('should throw BadRequestException when all DTO fields are undefined', async () => { | ||
| await expect(service.update(1, {})).rejects.toThrow( | ||
| new BadRequestException( | ||
| 'At least one field must be provided to update request', | ||
| ), | ||
| ); | ||
| }); | ||
| }); | ||
|
|
||
| describe('delete', () => { | ||
| it('should delete a request by id', async () => { | ||
| await testDataSource.query( | ||
| `DELETE FROM allocations WHERE order_id IN (SELECT order_id FROM orders WHERE request_id = 1)`, | ||
| ); | ||
| await testDataSource.query(`DELETE FROM orders WHERE request_id = 1`); | ||
|
|
||
| await service.delete(1); | ||
|
|
||
| const fromDb = await testDataSource | ||
| .getRepository(FoodRequest) | ||
| .findOneBy({ requestId: 1 }); | ||
| expect(fromDb).toBeNull(); | ||
| }); | ||
|
|
||
| it('should throw BadRequestException when request is not active', async () => { | ||
| await testDataSource.query( | ||
| `UPDATE food_requests SET status = 'closed' WHERE request_id = 1`, | ||
| ); | ||
|
|
||
| await expect(service.delete(1)).rejects.toThrow( | ||
| new BadRequestException( | ||
| `Request must be ${FoodRequestStatus.ACTIVE} in order to be deleted`, | ||
| ), | ||
| ); | ||
| }); | ||
|
|
||
| it('should throw BadRequestException when request has orders', async () => { | ||
| await expect(service.delete(2)).rejects.toThrow( | ||
| new BadRequestException( | ||
| `Request 2 cannot be deleted if it still has orders associated with it`, | ||
| ), | ||
| ); | ||
| }); | ||
|
|
||
| it('should throw NotFoundException when request is not found', async () => { | ||
| await expect(service.delete(9999)).rejects.toThrow( | ||
| new NotFoundException('Request 9999 not found'), | ||
| ); | ||
| }); | ||
| }); | ||
|
|
||
| describe('closeRequest', () => { | ||
| it('should close an active request', async () => { | ||
| const result = await service.closeRequest(3); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.