Skip to content

Commit ceb1366

Browse files
committed
#1522: added create material type endpoint with tests
1 parent 52980cd commit ceb1366

5 files changed

Lines changed: 62 additions & 4 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 createMaterialType(req: Request, res: Response, next: NextFunction) {
132+
try {
133+
const { name } = req.body;
134+
const user = await getCurrentUser(res);
135+
const createdMaterialType = await ProjectsService.createMaterialType(name, user);
136+
res.status(200).json(createdMaterialType);
137+
} catch (error: unknown) {
138+
next(error);
139+
}
140+
}
130141
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,6 @@ projectRouter.post(
4747
projectRouter.post('/:wbsNum/set-team', nonEmptyString(body('teamId')), validateInputs, ProjectsController.setProjectTeam);
4848
projectRouter.delete('/:wbsNum/delete', ProjectsController.deleteProject);
4949
projectRouter.post('/:wbsNum/favorite', ProjectsController.toggleFavorite);
50+
projectRouter.post('/bom/material-type/create', nonEmptyString(body('name')), ProjectsController.createMaterialType);
5051

5152
export default projectRouter;

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

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { User } from '@prisma/client';
2-
import { isAdmin, isGuest, isProject, LinkCreateArgs, LinkType, Project, WbsNumber, wbsPipe } from 'shared';
1+
import { Material_Type, User } from '@prisma/client';
2+
import { isAdmin, isGuest, isLeadership, isProject, LinkCreateArgs, LinkType, Project, WbsNumber, wbsPipe } from 'shared';
33
import projectQueryArgs from '../prisma-query-args/projects.query-args';
44
import prisma from '../prisma/prisma';
55
import projectTransformer from '../transformers/projects.transformer';
@@ -602,4 +602,23 @@ export default class ProjectsService {
602602
})
603603
).map(linkTypeTransformer);
604604
}
605+
606+
/**
607+
* Create a new material type
608+
* @param name the name of the new material type
609+
* @param submitter the user who is creating the material type
610+
*/
611+
static async createMaterialType(name: string, submitter: User): Promise<Material_Type> {
612+
if (!isLeadership(submitter.role)) throw new AccessDeniedAdminOnlyException('create material type');
613+
614+
const materialType = await prisma.material_Type.create({
615+
data: {
616+
name,
617+
dateCreated: new Date(),
618+
creatorId: submitter.userId
619+
}
620+
});
621+
622+
return materialType;
623+
}
605624
}

src/backend/tests/projects.test.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ 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 { prismaProject1, sharedProject1, toolMaterial } 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';
@@ -252,4 +252,20 @@ describe('Projects', () => {
252252
expect(prisma.user.update).toBeCalledTimes(1);
253253
});
254254
});
255+
256+
describe('materialType', () => {
257+
test('Create material type fails if user is not leader', async () => {
258+
await expect(ProjectsService.createMaterialType('Tools', wonderwoman)).rejects.toThrow(
259+
new AccessDeniedAdminOnlyException('create material type')
260+
);
261+
});
262+
263+
test('Create material type works', async () => {
264+
vi.spyOn(prisma.material_Type, 'create').mockResolvedValue(toolMaterial);
265+
266+
const materialType = await ProjectsService.createMaterialType('Tools', batman);
267+
expect(materialType.name).toBe('Tools');
268+
expect(prisma.material_Type.create).toBeCalledTimes(1);
269+
});
270+
});
255271
});

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import { Prisma, WBS_Element_Status as PrismaWBSElementStatus, Project } from '@prisma/client';
1+
import {
2+
Material_Type as PrismaMaterialType,
3+
Prisma,
4+
WBS_Element_Status as PrismaWBSElementStatus,
5+
Project
6+
} from '@prisma/client';
27
import { Project as SharedProject, WbsElementStatus } from 'shared';
38
import projectQueryArgs from '../../src/prisma-query-args/projects.query-args';
49
import { prismaTeam1 } from './teams.test-data';
@@ -97,3 +102,9 @@ export const sharedProject1: SharedProject = {
97102
tasks: [],
98103
teams: []
99104
};
105+
106+
export const toolMaterial: PrismaMaterialType = {
107+
name: 'Tools',
108+
dateCreated: new Date(),
109+
creatorId: batman.userId
110+
};

0 commit comments

Comments
 (0)