1 | package edu.ucsb.cs156.frontiers.controllers; | |
2 | ||
3 | import com.fasterxml.jackson.core.JsonProcessingException; | |
4 | import edu.ucsb.cs156.frontiers.entities.Course; | |
5 | import edu.ucsb.cs156.frontiers.entities.Job; | |
6 | import edu.ucsb.cs156.frontiers.entities.RosterStudent; | |
7 | import edu.ucsb.cs156.frontiers.entities.User; | |
8 | import edu.ucsb.cs156.frontiers.enums.InsertStatus; | |
9 | import edu.ucsb.cs156.frontiers.enums.OrgStatus; | |
10 | import edu.ucsb.cs156.frontiers.enums.RosterStatus; | |
11 | import edu.ucsb.cs156.frontiers.errors.EntityNotFoundException; | |
12 | import edu.ucsb.cs156.frontiers.errors.NoLinkedOrganizationException; | |
13 | import edu.ucsb.cs156.frontiers.jobs.UpdateOrgMembershipJob; | |
14 | import edu.ucsb.cs156.frontiers.models.RosterStudentDTO; | |
15 | import edu.ucsb.cs156.frontiers.models.UpsertResponse; | |
16 | import edu.ucsb.cs156.frontiers.repositories.CourseRepository; | |
17 | import edu.ucsb.cs156.frontiers.repositories.RosterStudentRepository; | |
18 | import edu.ucsb.cs156.frontiers.services.CurrentUserService; | |
19 | import edu.ucsb.cs156.frontiers.services.OrganizationMemberService; | |
20 | import edu.ucsb.cs156.frontiers.services.UpdateUserService; | |
21 | import edu.ucsb.cs156.frontiers.services.jobs.JobService; | |
22 | import edu.ucsb.cs156.frontiers.utilities.CanonicalFormConverter; | |
23 | import io.swagger.v3.oas.annotations.Operation; | |
24 | import io.swagger.v3.oas.annotations.Parameter; | |
25 | import io.swagger.v3.oas.annotations.tags.Tag; | |
26 | import java.security.NoSuchAlgorithmException; | |
27 | import java.security.spec.InvalidKeySpecException; | |
28 | import java.util.Optional; | |
29 | import lombok.extern.slf4j.Slf4j; | |
30 | import org.springframework.beans.factory.annotation.Autowired; | |
31 | import org.springframework.http.HttpStatus; | |
32 | import org.springframework.http.ResponseEntity; | |
33 | import org.springframework.security.access.AccessDeniedException; | |
34 | import org.springframework.security.access.prepost.PreAuthorize; | |
35 | import org.springframework.transaction.annotation.Transactional; | |
36 | import org.springframework.web.bind.annotation.DeleteMapping; | |
37 | import org.springframework.web.bind.annotation.GetMapping; | |
38 | import org.springframework.web.bind.annotation.PathVariable; | |
39 | import org.springframework.web.bind.annotation.PostMapping; | |
40 | import org.springframework.web.bind.annotation.PutMapping; | |
41 | import org.springframework.web.bind.annotation.RequestMapping; | |
42 | import org.springframework.web.bind.annotation.RequestParam; | |
43 | import org.springframework.web.bind.annotation.RestController; | |
44 | import org.springframework.web.server.ResponseStatusException; | |
45 | ||
46 | @Tag(name = "RosterStudents") | |
47 | @RequestMapping("/api/rosterstudents") | |
48 | @RestController | |
49 | @Slf4j | |
50 | public class RosterStudentsController extends ApiController { | |
51 | ||
52 | @Autowired private JobService jobService; | |
53 | @Autowired private OrganizationMemberService organizationMemberService; | |
54 | ||
55 | @Autowired private RosterStudentRepository rosterStudentRepository; | |
56 | ||
57 | @Autowired private CourseRepository courseRepository; | |
58 | ||
59 | @Autowired private UpdateUserService updateUserService; | |
60 | ||
61 | @Autowired private CurrentUserService currentUserService; | |
62 | ||
63 | /** | |
64 | * This method creates a new RosterStudent. It is important to keep the code in this method | |
65 | * consistent with the code for adding multiple roster students from a CSV | |
66 | * | |
67 | * @return the created RosterStudent | |
68 | */ | |
69 | @Operation(summary = "Create a new roster student") | |
70 | @PreAuthorize("@CourseSecurity.hasManagePermissions(#root, #courseId)") | |
71 | @PostMapping("/post") | |
72 | public ResponseEntity<UpsertResponse> postRosterStudent( | |
73 | @Parameter(name = "studentId") @RequestParam String studentId, | |
74 | @Parameter(name = "firstName") @RequestParam String firstName, | |
75 | @Parameter(name = "lastName") @RequestParam String lastName, | |
76 | @Parameter(name = "email") @RequestParam String email, | |
77 | @Parameter(name = "courseId") @RequestParam Long courseId) | |
78 | throws EntityNotFoundException { | |
79 | ||
80 | // Get Course or else throw an error | |
81 | ||
82 | Course course = | |
83 | courseRepository | |
84 | .findById(courseId) | |
85 |
1
1. lambda$postRosterStudent$0 : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::lambda$postRosterStudent$0 → KILLED |
.orElseThrow(() -> new EntityNotFoundException(Course.class, courseId)); |
86 | ||
87 | RosterStudent rosterStudent = | |
88 | RosterStudent.builder() | |
89 | .studentId(studentId) | |
90 | .firstName(firstName) | |
91 | .lastName(lastName) | |
92 | .email(email) | |
93 | .build(); | |
94 | ||
95 | UpsertResponse upsertResponse = upsertStudent(rosterStudent, course, RosterStatus.MANUAL); | |
96 |
1
1. postRosterStudent : negated conditional → KILLED |
if (upsertResponse.getInsertStatus() == InsertStatus.REJECTED) { |
97 |
1
1. postRosterStudent : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::postRosterStudent → KILLED |
return ResponseEntity.status(HttpStatus.CONFLICT).body(upsertResponse); |
98 | } else { | |
99 | rosterStudent = rosterStudentRepository.save(upsertResponse.rosterStudent()); | |
100 |
1
1. postRosterStudent : removed call to edu/ucsb/cs156/frontiers/services/UpdateUserService::attachUserToRosterStudent → KILLED |
updateUserService.attachUserToRosterStudent(rosterStudent); |
101 |
1
1. postRosterStudent : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::postRosterStudent → KILLED |
return ResponseEntity.ok(upsertResponse); |
102 | } | |
103 | } | |
104 | ||
105 | /** | |
106 | * This method returns a list of roster students for a given course. | |
107 | * | |
108 | * @return a list of all courses. | |
109 | */ | |
110 | @Operation(summary = "List all roster students for a course") | |
111 | @PreAuthorize("@CourseSecurity.hasManagePermissions(#root, #courseId)") | |
112 | @GetMapping("/course/{courseId}") | |
113 | public Iterable<RosterStudentDTO> rosterStudentForCourse( | |
114 | @Parameter(name = "courseId") @PathVariable Long courseId) throws EntityNotFoundException { | |
115 | courseRepository | |
116 | .findById(courseId) | |
117 |
1
1. lambda$rosterStudentForCourse$1 : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::lambda$rosterStudentForCourse$1 → KILLED |
.orElseThrow(() -> new EntityNotFoundException(Course.class, courseId)); |
118 | Iterable<RosterStudent> rosterStudents = rosterStudentRepository.findByCourseId(courseId); | |
119 | Iterable<RosterStudentDTO> rosterStudentDTOs = | |
120 | () -> | |
121 |
1
1. lambda$rosterStudentForCourse$2 : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::lambda$rosterStudentForCourse$2 → KILLED |
java.util.stream.StreamSupport.stream(rosterStudents.spliterator(), false) |
122 | .map(RosterStudentDTO::new) | |
123 | .iterator(); | |
124 |
1
1. rosterStudentForCourse : replaced return value with Collections.emptyList for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::rosterStudentForCourse → KILLED |
return rosterStudentDTOs; |
125 | } | |
126 | ||
127 | public static UpsertResponse upsertStudent( | |
128 | RosterStudent student, Course course, RosterStatus rosterStatus) { | |
129 | String convertedEmail = CanonicalFormConverter.convertToValidEmail(student.getEmail()); | |
130 | Optional<RosterStudent> existingStudent = | |
131 | course.getRosterStudents().stream() | |
132 | .filter( | |
133 |
2
1. lambda$upsertStudent$3 : replaced boolean return with true for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::lambda$upsertStudent$3 → KILLED 2. lambda$upsertStudent$3 : replaced boolean return with false for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::lambda$upsertStudent$3 → KILLED |
filteringStudent -> student.getStudentId().equals(filteringStudent.getStudentId())) |
134 | .findFirst(); | |
135 | Optional<RosterStudent> existingStudentByEmail = | |
136 | course.getRosterStudents().stream() | |
137 |
2
1. lambda$upsertStudent$4 : replaced boolean return with true for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::lambda$upsertStudent$4 → KILLED 2. lambda$upsertStudent$4 : replaced boolean return with false for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::lambda$upsertStudent$4 → KILLED |
.filter(filteringStudent -> convertedEmail.equals(filteringStudent.getEmail())) |
138 | .findFirst(); | |
139 |
2
1. upsertStudent : negated conditional → KILLED 2. upsertStudent : negated conditional → KILLED |
if (existingStudent.isPresent() && existingStudentByEmail.isPresent()) { |
140 |
1
1. upsertStudent : negated conditional → KILLED |
if (existingStudent.get().getId().equals(existingStudentByEmail.get().getId())) { |
141 | RosterStudent existingStudentObj = existingStudent.get(); | |
142 |
1
1. upsertStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setRosterStatus → KILLED |
existingStudentObj.setRosterStatus(rosterStatus); |
143 |
1
1. upsertStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setFirstName → KILLED |
existingStudentObj.setFirstName(student.getFirstName()); |
144 |
1
1. upsertStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setLastName → KILLED |
existingStudentObj.setLastName(student.getLastName()); |
145 |
1
1. upsertStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setSection → KILLED |
existingStudentObj.setSection(student.getSection()); |
146 |
1
1. upsertStudent : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::upsertStudent → KILLED |
return new UpsertResponse(InsertStatus.UPDATED, existingStudentObj); |
147 | } else { | |
148 |
1
1. upsertStudent : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::upsertStudent → KILLED |
return new UpsertResponse(InsertStatus.REJECTED, student); |
149 | } | |
150 |
2
1. upsertStudent : negated conditional → KILLED 2. upsertStudent : negated conditional → KILLED |
} else if (existingStudent.isPresent() || existingStudentByEmail.isPresent()) { |
151 | RosterStudent existingStudentObj = | |
152 |
1
1. upsertStudent : negated conditional → KILLED |
existingStudent.isPresent() ? existingStudent.get() : existingStudentByEmail.get(); |
153 |
1
1. upsertStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setRosterStatus → KILLED |
existingStudentObj.setRosterStatus(rosterStatus); |
154 |
1
1. upsertStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setFirstName → KILLED |
existingStudentObj.setFirstName(student.getFirstName()); |
155 |
1
1. upsertStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setLastName → KILLED |
existingStudentObj.setLastName(student.getLastName()); |
156 |
1
1. upsertStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setSection → KILLED |
existingStudentObj.setSection(student.getSection()); |
157 |
1
1. upsertStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setEmail → KILLED |
existingStudentObj.setEmail(convertedEmail); |
158 |
1
1. upsertStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setStudentId → KILLED |
existingStudentObj.setStudentId(student.getStudentId()); |
159 |
1
1. upsertStudent : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::upsertStudent → KILLED |
return new UpsertResponse(InsertStatus.UPDATED, existingStudentObj); |
160 | } else { | |
161 |
1
1. upsertStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setCourse → KILLED |
student.setCourse(course); |
162 |
1
1. upsertStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setEmail → KILLED |
student.setEmail(convertedEmail); |
163 |
1
1. upsertStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setRosterStatus → KILLED |
student.setRosterStatus(rosterStatus); |
164 | // if an installationID exists, orgStatus should be set to JOINCOURSE. if it doesn't exist | |
165 | // (null), set orgStatus to PENDING. | |
166 |
1
1. upsertStudent : negated conditional → KILLED |
if (course.getInstallationId() != null) { |
167 |
1
1. upsertStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setOrgStatus → KILLED |
student.setOrgStatus(OrgStatus.JOINCOURSE); |
168 | } else { | |
169 |
1
1. upsertStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setOrgStatus → KILLED |
student.setOrgStatus(OrgStatus.PENDING); |
170 | } | |
171 |
1
1. upsertStudent : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::upsertStudent → KILLED |
return new UpsertResponse(InsertStatus.INSERTED, student); |
172 | } | |
173 | } | |
174 | ||
175 | @PreAuthorize("@CourseSecurity.hasManagePermissions(#root, #courseId)") | |
176 | @PostMapping("/updateCourseMembership") | |
177 | public Job updateCourseMembership( | |
178 | @Parameter(name = "courseId", description = "Course ID") @RequestParam Long courseId) | |
179 | throws NoSuchAlgorithmException, InvalidKeySpecException, JsonProcessingException { | |
180 | Course course = | |
181 | courseRepository | |
182 | .findById(courseId) | |
183 |
1
1. lambda$updateCourseMembership$5 : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::lambda$updateCourseMembership$5 → KILLED |
.orElseThrow(() -> new EntityNotFoundException(Course.class, courseId)); |
184 |
2
1. updateCourseMembership : negated conditional → KILLED 2. updateCourseMembership : negated conditional → KILLED |
if (course.getInstallationId() == null || course.getOrgName() == null) { |
185 | throw new NoLinkedOrganizationException(course.getCourseName()); | |
186 | } else { | |
187 | UpdateOrgMembershipJob job = | |
188 | UpdateOrgMembershipJob.builder() | |
189 | .rosterStudentRepository(rosterStudentRepository) | |
190 | .organizationMemberService(organizationMemberService) | |
191 | .course(course) | |
192 | .build(); | |
193 | ||
194 |
1
1. updateCourseMembership : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::updateCourseMembership → KILLED |
return jobService.runAsJob(job); |
195 | } | |
196 | } | |
197 | ||
198 | @Operation( | |
199 | summary = | |
200 | "Allow roster student to join a course by generating an invitation to the linked Github Org") | |
201 | @PreAuthorize("hasRole('ROLE_USER')") | |
202 | @PutMapping("/joinCourse") | |
203 | public ResponseEntity<String> joinCourseOnGitHub( | |
204 | @Parameter( | |
205 | name = "rosterStudentId", | |
206 | description = "Roster Student joining a course on GitHub") | |
207 | @RequestParam | |
208 | Long rosterStudentId) | |
209 | throws NoSuchAlgorithmException, InvalidKeySpecException, JsonProcessingException { | |
210 | ||
211 | User currentUser = currentUserService.getUser(); | |
212 | RosterStudent rosterStudent = | |
213 | rosterStudentRepository | |
214 | .findById(rosterStudentId) | |
215 |
1
1. lambda$joinCourseOnGitHub$6 : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::lambda$joinCourseOnGitHub$6 → KILLED |
.orElseThrow(() -> new EntityNotFoundException(RosterStudent.class, rosterStudentId)); |
216 | ||
217 |
2
1. joinCourseOnGitHub : negated conditional → KILLED 2. joinCourseOnGitHub : negated conditional → KILLED |
if (rosterStudent.getUser() == null || currentUser.getId() != rosterStudent.getUser().getId()) { |
218 | throw new AccessDeniedException("User not authorized join the course as this roster student"); | |
219 | } | |
220 | ||
221 |
1
1. joinCourseOnGitHub : negated conditional → KILLED |
if (rosterStudent.getRosterStatus() == RosterStatus.DROPPED) { |
222 | throw new AccessDeniedException( | |
223 | "You have dropped this course. Please contact your instructor."); | |
224 | } | |
225 | ||
226 |
1
1. joinCourseOnGitHub : negated conditional → KILLED |
if (rosterStudent.getGithubId() != null |
227 |
1
1. joinCourseOnGitHub : negated conditional → KILLED |
&& rosterStudent.getGithubLogin() != null |
228 |
1
1. joinCourseOnGitHub : negated conditional → KILLED |
&& (rosterStudent.getOrgStatus() == OrgStatus.MEMBER |
229 |
1
1. joinCourseOnGitHub : negated conditional → KILLED |
|| rosterStudent.getOrgStatus() == OrgStatus.OWNER)) { |
230 |
1
1. joinCourseOnGitHub : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::joinCourseOnGitHub → KILLED |
return ResponseEntity.badRequest() |
231 | .body("This user has already linked a Github account to this course."); | |
232 | } | |
233 | ||
234 |
1
1. joinCourseOnGitHub : negated conditional → KILLED |
if (rosterStudent.getCourse().getOrgName() == null |
235 |
1
1. joinCourseOnGitHub : negated conditional → KILLED |
|| rosterStudent.getCourse().getInstallationId() == null) { |
236 |
1
1. joinCourseOnGitHub : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::joinCourseOnGitHub → KILLED |
return ResponseEntity.badRequest() |
237 | .body("Course has not been set up. Please ask your instructor for help."); | |
238 | } | |
239 |
1
1. joinCourseOnGitHub : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setGithubId → KILLED |
rosterStudent.setGithubId(currentUser.getGithubId()); |
240 |
1
1. joinCourseOnGitHub : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setGithubLogin → KILLED |
rosterStudent.setGithubLogin(currentUser.getGithubLogin()); |
241 | OrgStatus status = organizationMemberService.inviteOrganizationMember(rosterStudent); | |
242 |
1
1. joinCourseOnGitHub : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setOrgStatus → KILLED |
rosterStudent.setOrgStatus(status); |
243 | rosterStudentRepository.save(rosterStudent); | |
244 |
1
1. joinCourseOnGitHub : negated conditional → KILLED |
if (status == OrgStatus.INVITED) { |
245 |
1
1. joinCourseOnGitHub : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::joinCourseOnGitHub → KILLED |
return ResponseEntity.accepted().body("Successfully invited student to Organization"); |
246 |
2
1. joinCourseOnGitHub : negated conditional → KILLED 2. joinCourseOnGitHub : negated conditional → KILLED |
} else if (status == OrgStatus.MEMBER || status == OrgStatus.OWNER) { |
247 |
1
1. joinCourseOnGitHub : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::joinCourseOnGitHub → KILLED |
return ResponseEntity.accepted() |
248 | .body("Already in organization - set status to %s".formatted(status.toString())); | |
249 | } else { | |
250 |
1
1. joinCourseOnGitHub : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::joinCourseOnGitHub → KILLED |
return ResponseEntity.internalServerError().body("Could not invite student to Organization"); |
251 | } | |
252 | } | |
253 | ||
254 | @Operation(summary = "Get Associated Roster Students with a User") | |
255 | @PreAuthorize("hasRole('ROLE_USER')") | |
256 | @GetMapping("/associatedRosterStudents") | |
257 | public Iterable<RosterStudent> getAssociatedRosterStudents() { | |
258 | User currentUser = currentUserService.getUser(); | |
259 | Iterable<RosterStudent> rosterStudents = rosterStudentRepository.findAllByUser((currentUser)); | |
260 |
1
1. getAssociatedRosterStudents : replaced return value with Collections.emptyList for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::getAssociatedRosterStudents → KILLED |
return rosterStudents; |
261 | } | |
262 | ||
263 | @Operation(summary = "Update a roster student") | |
264 | @PreAuthorize("@CourseSecurity.hasRosterStudentManagementPermissions(#root, #id)") | |
265 | @PutMapping("/update") | |
266 | public RosterStudent updateRosterStudent( | |
267 | @Parameter(name = "id") @RequestParam Long id, | |
268 | @Parameter(name = "firstName") @RequestParam(required = false) String firstName, | |
269 | @Parameter(name = "lastName") @RequestParam(required = false) String lastName, | |
270 | @Parameter(name = "studentId") @RequestParam(required = false) String studentId) | |
271 | throws EntityNotFoundException { | |
272 | ||
273 |
3
1. updateRosterStudent : negated conditional → KILLED 2. updateRosterStudent : negated conditional → KILLED 3. updateRosterStudent : negated conditional → KILLED |
if (firstName == null |
274 | || lastName == null | |
275 | || studentId == null | |
276 |
1
1. updateRosterStudent : negated conditional → KILLED |
|| firstName.trim().isEmpty() |
277 |
1
1. updateRosterStudent : negated conditional → KILLED |
|| lastName.trim().isEmpty() |
278 |
1
1. updateRosterStudent : negated conditional → KILLED |
|| studentId.trim().isEmpty()) { |
279 | throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Required fields cannot be empty"); | |
280 | } | |
281 | ||
282 | RosterStudent rosterStudent = | |
283 | rosterStudentRepository | |
284 | .findById(id) | |
285 |
1
1. lambda$updateRosterStudent$7 : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::lambda$updateRosterStudent$7 → KILLED |
.orElseThrow(() -> new EntityNotFoundException(RosterStudent.class, id)); |
286 | ||
287 |
1
1. updateRosterStudent : negated conditional → KILLED |
if (!rosterStudent.getStudentId().trim().equals(studentId.trim())) { |
288 | Optional<RosterStudent> existingStudent = | |
289 | rosterStudentRepository.findByCourseIdAndStudentId( | |
290 | rosterStudent.getCourse().getId(), studentId.trim()); | |
291 |
1
1. updateRosterStudent : negated conditional → KILLED |
if (existingStudent.isPresent()) { |
292 | throw new ResponseStatusException( | |
293 | HttpStatus.BAD_REQUEST, "Student ID already exists in this course"); | |
294 | } | |
295 | } | |
296 | ||
297 |
1
1. updateRosterStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setFirstName → KILLED |
rosterStudent.setFirstName(firstName.trim()); |
298 |
1
1. updateRosterStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setLastName → KILLED |
rosterStudent.setLastName(lastName.trim()); |
299 |
1
1. updateRosterStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setStudentId → KILLED |
rosterStudent.setStudentId(studentId.trim()); |
300 | ||
301 |
1
1. updateRosterStudent : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::updateRosterStudent → KILLED |
return rosterStudentRepository.save(rosterStudent); |
302 | } | |
303 | ||
304 | @Operation( | |
305 | summary = "Restore a roster student", | |
306 | description = "Makes a student who previously dropped the course able to join and interact") | |
307 | @PreAuthorize("@CourseSecurity.hasRosterStudentManagementPermissions(#root, #id)") | |
308 | @PutMapping("/restore") | |
309 | public RosterStudent restoreRosterStudent(@Parameter(name = "id") @RequestParam Long id) | |
310 | throws EntityNotFoundException { | |
311 | RosterStudent rosterStudent = | |
312 | rosterStudentRepository | |
313 | .findById(id) | |
314 |
1
1. lambda$restoreRosterStudent$8 : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::lambda$restoreRosterStudent$8 → KILLED |
.orElseThrow(() -> new EntityNotFoundException(RosterStudent.class, id)); |
315 |
1
1. restoreRosterStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setRosterStatus → KILLED |
rosterStudent.setRosterStatus(RosterStatus.MANUAL); |
316 |
1
1. restoreRosterStudent : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::restoreRosterStudent → KILLED |
return rosterStudentRepository.save(rosterStudent); |
317 | } | |
318 | ||
319 | @Operation(summary = "Delete a roster student") | |
320 | @PreAuthorize("@CourseSecurity.hasRosterStudentManagementPermissions(#root, #id)") | |
321 | @DeleteMapping("/delete") | |
322 | @Transactional | |
323 | public ResponseEntity<String> deleteRosterStudent( | |
324 | @Parameter(name = "id") @RequestParam Long id, | |
325 | @Parameter( | |
326 | name = "removeFromOrg", | |
327 | description = "Whether to remove student from GitHub organization") | |
328 | @RequestParam(defaultValue = "true") | |
329 | boolean removeFromOrg) | |
330 | throws EntityNotFoundException { | |
331 | RosterStudent rosterStudent = | |
332 | rosterStudentRepository | |
333 | .findById(id) | |
334 |
1
1. lambda$deleteRosterStudent$9 : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::lambda$deleteRosterStudent$9 → KILLED |
.orElseThrow(() -> new EntityNotFoundException(RosterStudent.class, id)); |
335 | Course course = rosterStudent.getCourse(); | |
336 | ||
337 | boolean orgRemovalAttempted = false; | |
338 | boolean orgRemovalSuccessful = false; | |
339 | String orgRemovalErrorMessage = null; | |
340 | ||
341 | // Try to remove the student from the organization if they have a GitHub login | |
342 | // and removeFromOrg parameter is true | |
343 |
1
1. deleteRosterStudent : negated conditional → KILLED |
if (removeFromOrg |
344 |
1
1. deleteRosterStudent : negated conditional → KILLED |
&& rosterStudent.getGithubLogin() != null |
345 |
1
1. deleteRosterStudent : negated conditional → KILLED |
&& course.getOrgName() != null |
346 |
1
1. deleteRosterStudent : negated conditional → KILLED |
&& course.getInstallationId() != null) { |
347 | orgRemovalAttempted = true; | |
348 | try { | |
349 |
1
1. deleteRosterStudent : removed call to edu/ucsb/cs156/frontiers/services/OrganizationMemberService::removeOrganizationMember → KILLED |
organizationMemberService.removeOrganizationMember(rosterStudent); |
350 | orgRemovalSuccessful = true; | |
351 | } catch (Exception e) { | |
352 | log.error("Error removing student from organization: {}", e.getMessage()); | |
353 | orgRemovalErrorMessage = e.getMessage(); | |
354 | // Continue with deletion even if organization removal fails | |
355 | } | |
356 | } | |
357 | ||
358 |
1
1. deleteRosterStudent : negated conditional → KILLED |
if (!rosterStudent.getTeamMembers().isEmpty()) { |
359 | rosterStudent | |
360 | .getTeamMembers() | |
361 |
1
1. deleteRosterStudent : removed call to java/util/List::forEach → KILLED |
.forEach( |
362 | teamMember -> { | |
363 | teamMember.getTeam().getTeamMembers().remove(teamMember); | |
364 |
1
1. lambda$deleteRosterStudent$10 : removed call to edu/ucsb/cs156/frontiers/entities/TeamMember::setTeam → KILLED |
teamMember.setTeam(null); |
365 | }); | |
366 | } | |
367 | ||
368 | rosterStudent.getCourse().getRosterStudents().remove(rosterStudent); | |
369 |
1
1. deleteRosterStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setCourse → KILLED |
rosterStudent.setCourse(null); |
370 |
1
1. deleteRosterStudent : removed call to edu/ucsb/cs156/frontiers/repositories/RosterStudentRepository::delete → KILLED |
rosterStudentRepository.delete(rosterStudent); |
371 | ||
372 |
1
1. deleteRosterStudent : negated conditional → KILLED |
if (!orgRemovalAttempted) { |
373 |
1
1. deleteRosterStudent : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::deleteRosterStudent → KILLED |
return ResponseEntity.ok( |
374 | "Successfully deleted roster student and removed him/her from the course list"); | |
375 |
1
1. deleteRosterStudent : negated conditional → KILLED |
} else if (orgRemovalSuccessful) { |
376 |
1
1. deleteRosterStudent : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::deleteRosterStudent → KILLED |
return ResponseEntity.ok( |
377 | "Successfully deleted roster student and removed him/her from the course list and organization"); | |
378 | } else { | |
379 |
1
1. deleteRosterStudent : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::deleteRosterStudent → KILLED |
return ResponseEntity.ok( |
380 | "Successfully deleted roster student but there was an error removing them from the course organization: " | |
381 | + orgRemovalErrorMessage); | |
382 | } | |
383 | } | |
384 | } | |
Mutations | ||
85 |
1.1 |
|
96 |
1.1 |
|
97 |
1.1 |
|
100 |
1.1 |
|
101 |
1.1 |
|
117 |
1.1 |
|
121 |
1.1 |
|
124 |
1.1 |
|
133 |
1.1 2.2 |
|
137 |
1.1 2.2 |
|
139 |
1.1 2.2 |
|
140 |
1.1 |
|
142 |
1.1 |
|
143 |
1.1 |
|
144 |
1.1 |
|
145 |
1.1 |
|
146 |
1.1 |
|
148 |
1.1 |
|
150 |
1.1 2.2 |
|
152 |
1.1 |
|
153 |
1.1 |
|
154 |
1.1 |
|
155 |
1.1 |
|
156 |
1.1 |
|
157 |
1.1 |
|
158 |
1.1 |
|
159 |
1.1 |
|
161 |
1.1 |
|
162 |
1.1 |
|
163 |
1.1 |
|
166 |
1.1 |
|
167 |
1.1 |
|
169 |
1.1 |
|
171 |
1.1 |
|
183 |
1.1 |
|
184 |
1.1 2.2 |
|
194 |
1.1 |
|
215 |
1.1 |
|
217 |
1.1 2.2 |
|
221 |
1.1 |
|
226 |
1.1 |
|
227 |
1.1 |
|
228 |
1.1 |
|
229 |
1.1 |
|
230 |
1.1 |
|
234 |
1.1 |
|
235 |
1.1 |
|
236 |
1.1 |
|
239 |
1.1 |
|
240 |
1.1 |
|
242 |
1.1 |
|
244 |
1.1 |
|
245 |
1.1 |
|
246 |
1.1 2.2 |
|
247 |
1.1 |
|
250 |
1.1 |
|
260 |
1.1 |
|
273 |
1.1 2.2 3.3 |
|
276 |
1.1 |
|
277 |
1.1 |
|
278 |
1.1 |
|
285 |
1.1 |
|
287 |
1.1 |
|
291 |
1.1 |
|
297 |
1.1 |
|
298 |
1.1 |
|
299 |
1.1 |
|
301 |
1.1 |
|
314 |
1.1 |
|
315 |
1.1 |
|
316 |
1.1 |
|
334 |
1.1 |
|
343 |
1.1 |
|
344 |
1.1 |
|
345 |
1.1 |
|
346 |
1.1 |
|
349 |
1.1 |
|
358 |
1.1 |
|
361 |
1.1 |
|
364 |
1.1 |
|
369 |
1.1 |
|
370 |
1.1 |
|
372 |
1.1 |
|
373 |
1.1 |
|
375 |
1.1 |
|
376 |
1.1 |
|
379 |
1.1 |