Skip to content

Commit c54b0b2

Browse files
authored
Merge pull request #1656 from Northeastern-Electric-Racing/#1521-bom-create-manufacturer-endpoint
#1521 BOM create manufacturer endpoint
2 parents 23d6dfb + f17a2d1 commit c54b0b2

5 files changed

Lines changed: 79 additions & 2 deletions

File tree

src/backend/src/controllers/projects.controllers.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,4 +127,15 @@ export default class ProjectsController {
127127
next(error);
128128
}
129129
}
130+
131+
static async createManufacturer(req: Request, res: Response, next: NextFunction) {
132+
try {
133+
const { name } = req.body;
134+
const user = await getCurrentUser(res);
135+
const createdManufacturer = await ProjectsService.createManufacturer(user, name);
136+
res.status(200).json(createdManufacturer);
137+
} catch (error: unknown) {
138+
next(error);
139+
}
140+
}
130141
}

src/backend/src/routes/projects.routes.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,12 @@ projectRouter.post('/:wbsNum/set-team', nonEmptyString(body('teamId')), validate
4848
projectRouter.delete('/:wbsNum/delete', ProjectsController.deleteProject);
4949
projectRouter.post('/:wbsNum/favorite', ProjectsController.toggleFavorite);
5050

51+
/**************** BOM Section ****************/
52+
projectRouter.post(
53+
'/bom/manufacturer/create',
54+
nonEmptyString(body('name')),
55+
validateInputs,
56+
ProjectsController.createManufacturer
57+
);
58+
5159
export default projectRouter;

src/backend/src/services/projects.services.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,4 +602,29 @@ export default class ProjectsService {
602602
})
603603
).map(linkTypeTransformer);
604604
}
605+
606+
/**
607+
* Creates a new Manufacturer
608+
* @param submitter the user who's creating the manufacturer
609+
* @param name the name of the manufacturer
610+
* @returns the newly created manufacturer
611+
* @throws if the submitter is a guest or the given manufacturer name already exists
612+
*/
613+
static async createManufacturer(submitter: User, name: string) {
614+
if (isGuest(submitter.role)) throw new AccessDeniedGuestException('create manufacturers');
615+
616+
const manufacturer = await prisma.manufacturer.findUnique({
617+
where: {
618+
name
619+
}
620+
});
621+
622+
if (manufacturer) throw new HttpException(400, `${name} already exists as a manufacturer!`);
623+
624+
const newManufacturer = await prisma.manufacturer.create({
625+
data: { name, dateCreated: new Date(), creatorId: submitter.userId }
626+
});
627+
628+
return newManufacturer;
629+
}
605630
}

src/backend/tests/projects.test.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ import prisma from '../src/prisma/prisma';
22
import { getHighestProjectNumber } from '../src/utils/projects.utils';
33
import * as changeRequestUtils from '../src/utils/change-requests.utils';
44
import { aquaman, batman, wonderwoman } from './test-data/users.test-data';
5-
import { prismaProject1, sharedProject1 } from './test-data/projects.test-data';
5+
import { prismaManufacturer1, prismaProject1, sharedProject1 } from './test-data/projects.test-data';
66
import { prismaChangeRequest1 } from './test-data/change-requests.test-data';
77
import { prismaTeam1 } from './test-data/teams.test-data';
88
import * as projectTransformer from '../src/transformers/projects.transformer';
99
import ProjectsService from '../src/services/projects.services';
1010
import {
1111
AccessDeniedAdminOnlyException,
12+
AccessDeniedGuestException,
1213
DeletedException,
1314
HttpException,
1415
NotFoundException
@@ -254,4 +255,30 @@ describe('Projects', () => {
254255
expect(prisma.user.update).toBeCalledTimes(1);
255256
});
256257
});
258+
259+
describe('Manufacturer Tests', () => {
260+
test('createManufacturer throws an error if user is a guest', async () => {
261+
await expect(ProjectsService.createManufacturer(wonderwoman, 'NAME')).rejects.toThrow(
262+
new AccessDeniedGuestException('create manufacturers')
263+
);
264+
});
265+
266+
test('createManufacturer throws an error if manufacturer already exists', async () => {
267+
vi.spyOn(prisma.manufacturer, 'findUnique').mockResolvedValue(prismaManufacturer1);
268+
269+
await expect(ProjectsService.createManufacturer(batman, 'Manufacturer1')).rejects.toThrow(
270+
new HttpException(400, 'Manufacturer1 already exists as a manufacturer!')
271+
);
272+
});
273+
274+
test('createManufacturer works as intended and successfully returns correct name and creator ID', async () => {
275+
vi.spyOn(prisma.manufacturer, 'findUnique').mockResolvedValue(null);
276+
vi.spyOn(prisma.manufacturer, 'create').mockResolvedValue(prismaManufacturer1);
277+
278+
const manufacturer = await ProjectsService.createManufacturer(batman, 'Manufacturer1');
279+
280+
expect(manufacturer.name).toBe(prismaManufacturer1.name);
281+
expect(manufacturer.creatorId).toBe(prismaManufacturer1.creatorId);
282+
});
283+
});
257284
});

src/backend/tests/test-data/projects.test-data.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Prisma, WBS_Element_Status as PrismaWBSElementStatus, Project } from '@prisma/client';
1+
import { Prisma, WBS_Element_Status as PrismaWBSElementStatus, Project, Manufacturer } from '@prisma/client';
22
import { Project as SharedProject, WbsElementStatus } from 'shared';
33
import projectQueryArgs from '../../src/prisma-query-args/projects.query-args';
44
import { prismaTeam1 } from './teams.test-data';
@@ -97,3 +97,9 @@ export const sharedProject1: SharedProject = {
9797
tasks: [],
9898
teams: []
9999
};
100+
101+
export const prismaManufacturer1: Manufacturer = {
102+
name: 'Manufacturer1',
103+
dateCreated: new Date('10-1-2023'),
104+
creatorId: 1
105+
};

0 commit comments

Comments
 (0)