Skip to content

Commit 1fae3e4

Browse files
authored
Merge pull request #215 from makeopensource/67-bug-fixes
67 bug fixes
2 parents b74dbca + b15f294 commit 1fae3e4

9 files changed

Lines changed: 90 additions & 37 deletions

File tree

devU-api/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
"version": "1.0.0",
44
"description": "DevU API",
55
"scripts": {
6-
"start": "npm run migrate && ts-node-dev src/index.ts",
6+
"start": "npm run migrate && ts-node src/index.ts",
7+
"dev": "npm run migrate && ts-node-dev src/index.ts",
78
"migrate": "npm run typeorm -- migration:run -d src/database.ts",
89
"create-migrate": "npx typeorm-ts-node-commonjs migration:generate -d src/database.ts",
910
"update-shared": "cd ../devU-shared && npm run build-local && cd ../devU-api && npm i",

devU-api/src/entities/containerAutoGrader/containerAutoGrader.controller.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,12 @@ export async function detail(req: Request, res: Response, next: NextFunction) {
3030
}
3131
}
3232

33-
export async function getObjectByAssignment(req: Request, res: Response, next: NextFunction) {
33+
export async function getAllByAssignment(req: Request, res: Response, next: NextFunction) {
3434
try {
3535
const assignmentId = parseInt(req.params.id)
36-
const containerAutoGrader = await ContainerAutoGraderService.getGraderObjectByAssignmentId(assignmentId)
36+
if (!assignmentId) return res.status(404).json({ message: 'invalid assignment ID' })
37+
38+
const containerAutoGrader = await ContainerAutoGraderService.getAllGradersByAssignment(assignmentId)
3739

3840
res.status(200).json(containerAutoGrader.map(serialize))
3941
} catch (err) {
@@ -110,5 +112,5 @@ export default {
110112
post,
111113
put,
112114
_delete,
113-
getObjectByAssignment,
115+
getAllByAssignment,
114116
}

devU-api/src/entities/containerAutoGrader/containerAutoGrader.router.ts

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,6 @@ import ContainerAutoGraderController from './containerAutoGrader.controller'
1010
const Router = express.Router({ mergeParams: true })
1111
const upload = multer()
1212

13-
/**
14-
* @swagger
15-
* /course/:courseId/assignment/:assignmentId/container-auto-graders:
16-
* get:
17-
* summary: Retrieve a list of all container auto graders
18-
* tags:
19-
* - ContainerAutoGraders
20-
* responses:
21-
* '200':
22-
* description: OK
23-
*/
24-
Router.get('/', isAuthorized('assignmentViewAll'), ContainerAutoGraderController.get)
25-
2613
/**
2714
* @swagger
2815
* /course/:courseId/assignment/:assignmentId/container-auto-graders/{id}:
@@ -59,7 +46,7 @@ Router.get('/:id', isAuthorized('assignmentViewAll'), asInt(), ContainerAutoGrad
5946
* schema:
6047
* type: integer
6148
*/
62-
Router.get('/assignment/:id', asInt(), ContainerAutoGraderController.getObjectByAssignment)
49+
Router.get('/assignment/:id', asInt(), ContainerAutoGraderController.getAllByAssignment)
6350

6451
/**
6552
* @swagger

devU-api/src/entities/containerAutoGrader/containerAutoGrader.service.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { ContainerAutoGrader, FileUpload } from 'devu-shared-modules'
66
import ContainerAutoGraderModel from './containerAutoGrader.model'
77
import FileModel from '../../fileUpload/fileUpload.model'
88

9-
import { uploadFile, downloadFile } from '../../fileStorage'
9+
import { downloadFile, uploadFile } from '../../fileStorage'
1010
import { generateFilename } from '../../utils/fileUpload.utils'
1111

1212
const connect = () => dataSource.getRepository(ContainerAutoGraderModel)
@@ -105,14 +105,11 @@ export async function list() {
105105
return await connect().findBy({ deletedAt: IsNull() })
106106
}
107107

108-
//The grader has not changed to the new function, so the fake function keep here for now to avoid error
109-
//But need to be deleted when the grader entity changed to the getGraderByAssignmentId
110-
export async function getGraderObjectByAssignmentId(assignmentId: number) {
111-
if (!assignmentId) throw new Error('Missing AssignmentId')
108+
export async function getAllGradersByAssignment(assignmentId: number) {
112109
return await connect().findBy({ assignmentId: assignmentId, deletedAt: IsNull() })
113110
}
114111

115-
export async function getGraderByAssignmentId(assignmentId: number) {
112+
export async function loadGrader(assignmentId: number) {
116113
const containerAutoGraders = await connect().findOneBy({ assignmentId: assignmentId, deletedAt: IsNull() })
117114
if (!containerAutoGraders) return { graderData: null, makefileData: null, autogradingImage: null, timeout: null }
118115

@@ -135,6 +132,6 @@ export default {
135132
update,
136133
_delete,
137134
list,
138-
getGraderByAssignmentId,
139-
getGraderObjectByAssignmentId,
135+
loadGrader,
136+
getAllGradersByAssignment,
140137
}

devU-api/src/entities/grader/grader.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ async function runContainerAutograders(filepaths: string[], submission: Submissi
108108
let jobResponse = null
109109

110110
const { graderData, makefileData, autogradingImage, timeout } =
111-
await containerAutograderService.getGraderByAssignmentId(assignmentId)
111+
await containerAutograderService.loadGrader(assignmentId)
112112
if (!graderData || !makefileData || !autogradingImage || !timeout) {
113113
containerGrading = false
114114
} else {

devU-api/src/entities/userCourse/userCourse.controller.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ import { NextFunction, Request, Response } from 'express'
22

33
import UserCourseService from './userCourse.service'
44
import { serialize } from './userCourse.serializer'
5+
import { serialize as userSerialize } from '../user/user.serializer'
56

67
import { GenericResponse, NotFound, Updated } from '../../utils/apiResponse.utils'
8+
import UserService from '../user/user.service'
79

810
export async function getAll(req: Request, res: Response, next: NextFunction) {
911
try {
@@ -54,6 +56,25 @@ export async function detail(req: Request, res: Response, next: NextFunction) {
5456
}
5557
}
5658

59+
export async function getInstructor(req: Request, res: Response, next: NextFunction) {
60+
try {
61+
const cid = parseInt(req.params.courseId)
62+
63+
const instructorInfo = await UserCourseService.instructor(cid)
64+
if (!instructorInfo) return res.status(400).json({ message: `no instructors found for course ${cid}` })
65+
66+
const userInfo = await UserService.retrieve(instructorInfo.userId)
67+
if (!userInfo) return res.status(400).json({ message: `no instructors found for course ${cid}` })
68+
69+
// strip out unnecessary info
70+
const { isAdmin, createdAt, ...responsePayload } = userSerialize(userInfo)
71+
72+
res.status(200).json(responsePayload)
73+
} catch (err) {
74+
next(err)
75+
}
76+
}
77+
5778
export async function detailByUser(req: Request, res: Response, next: NextFunction) {
5879
try {
5980
const courseId = parseInt(req.params.courseId)
@@ -122,7 +143,7 @@ export async function checkEnroll(req: Request, res: Response, next: NextFunctio
122143
export async function _delete(req: Request, res: Response, next: NextFunction) {
123144
try {
124145
const id = parseInt(req.params.courseId)
125-
console.log("DELETE PARAMS: ", req.params)
146+
console.log('DELETE PARAMS: ', req.params)
126147
const currentUser = req.currentUser?.userId
127148
if (!currentUser) return res.status(401).json({ message: 'Unauthorized' })
128149

@@ -140,7 +161,7 @@ export async function _delete(req: Request, res: Response, next: NextFunction) {
140161
export async function _deleteUser(req: Request, res: Response, next: NextFunction) {
141162
try {
142163
const courseID = parseInt(req.params.courseId)
143-
console.log("DELETE PARAMS2: ", req.params)
164+
console.log('DELETE PARAMS2: ', req.params)
144165
// const currentUser = req.currentUser?.userId
145166
const userID = parseInt(req.params.id)
146167
if (!userID) return res.status(401).json({ message: 'Unauthorized' })
@@ -194,4 +215,5 @@ export default {
194215
checkEnroll,
195216
addStudents,
196217
dropStudents,
218+
getInstructor,
197219
}

devU-api/src/entities/userCourse/userCourse.router.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,40 @@ Router.get('/users', UserCourseController.checkEnroll)
3535
*/
3636
Router.get('/', isAuthorized('courseViewAll'), UserCourseController.getByCourse)
3737

38+
/**
39+
* @swagger
40+
* /course/:courseId/user-courses/instructor:
41+
* get:
42+
* summary: Retrieve first instructor of the course
43+
* tags:
44+
* - UserCourses
45+
* responses:
46+
* '200':
47+
* description: OK
48+
* content:
49+
* application/json:
50+
* schema:
51+
* $ref: '#/components/schemas/User'
52+
* '404':
53+
* description: no instructor found associated with course
54+
* content:
55+
* application/json:
56+
* schema:
57+
* type: object
58+
* properties:
59+
* message:
60+
* type: string
61+
* description: error message
62+
* parameters:
63+
* - name: courseId
64+
* description: Enter Course Id
65+
* in: path
66+
* required: true
67+
* schema:
68+
* type: integer
69+
*/
70+
Router.get('/instructor', isAuthorized('courseViewAll'), UserCourseController.getInstructor)
71+
3872
/**
3973
* @swagger
4074
* /course/:courseId/user-courses/{id}:

devU-api/src/entities/userCourse/userCourse.service.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ export async function create(userCourse: UserCourseType) {
1616
return await connect().save(userCourse)
1717
}
1818

19+
export async function instructor(courseId: number) {
20+
return await connect().findOne({
21+
select: ['userId'],
22+
where: { role: 'instructor', courseId: courseId, deletedAt: IsNull() },
23+
})
24+
}
25+
1926
// Add/drop students based on a list of users,
2027
// to drop students, set the third param to true
2128
export async function bulkAddDrop(userEmails: string[], courseId: number, drop: boolean) {
@@ -41,12 +48,12 @@ export async function bulkAddDrop(userEmails: string[], courseId: number, drop:
4148
try {
4249
await create(student)
4350
} catch (error) {
44-
if (error instanceof Error && error.message === 'User already enrolled in course') {
45-
// update student drop to false, since they re-enrolled after being dropped
46-
await update(student)
47-
} else {
48-
throw error; // re-throw if it's a different error
49-
}
51+
if (error instanceof Error && error.message === 'User already enrolled in course') {
52+
// update student drop to false, since they re-enrolled after being dropped
53+
await update(student)
54+
} else {
55+
throw error // re-throw if it's a different error
56+
}
5057
}
5158
success.push(`${email} enrolled successfully`)
5259
} else {
@@ -121,4 +128,5 @@ export default {
121128
listByUser,
122129
checking: checkIfEnrolled,
123130
bulkCreate: bulkAddDrop,
131+
instructor,
124132
}

devU-api/src/router/courseData.router.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import assignmentProblem from '../entities/assignmentProblem/assignmentProblem.r
99
import submissionProblemScore from '../entities/submissionProblemScore/submissionProblemScore.router'
1010
import deadlineExtensions from '../entities/deadlineExtensions/deadlineExtensions.router'
1111
import fileUpload from '../fileUpload/fileUpload.router'
12-
import categories from '../entities/category/category.router'
1312
import categoryScores from '../entities/categoryScore/categoryScore.router'
1413
import courseScores from '../entities/courseScore/courseScore.router'
1514
import assignmentScore from '../entities/assignmentScore/assignmentScore.router'
@@ -41,13 +40,16 @@ Router.use('/a/:assignmentId/', asInt('assignmentId'), assignmentRouter)
4140

4241
Router.use('/assignments', assignments)
4342
Router.use('/assignment-scores', assignmentScore)
44-
Router.use('/categories', categories)
4543
Router.use('/category-scores', categoryScores)
4644
Router.use('/course-scores', courseScores)
4745
Router.use('/file-upload', fileUpload)
4846
Router.use('/roles', role)
4947
Router.use('/user-courses', userCourse)
5048

49+
// redundant endpoint, assignment already encodes the categories
50+
// here if we need it in the future
51+
// Router.use('/categories', categories)
52+
5153
Router.use('/webhooks', webhooksRouter)
5254

5355

0 commit comments

Comments
 (0)