RosterStudentsController.java

1
package edu.ucsb.cs156.frontiers.controllers;
2
3
import java.io.BufferedInputStream;
4
import java.io.IOException;
5
import java.io.InputStream;
6
import java.io.InputStreamReader;
7
import java.security.NoSuchAlgorithmException;
8
import java.security.spec.InvalidKeySpecException;
9
import java.util.List;
10
import java.util.Map;
11
import java.util.Optional;
12
13
import edu.ucsb.cs156.frontiers.entities.Job;
14
import edu.ucsb.cs156.frontiers.entities.User;
15
import edu.ucsb.cs156.frontiers.errors.NoLinkedOrganizationException;
16
import edu.ucsb.cs156.frontiers.jobs.UpdateOrgMembershipJob;
17
import edu.ucsb.cs156.frontiers.repositories.UserRepository;
18
import edu.ucsb.cs156.frontiers.services.*;
19
import edu.ucsb.cs156.frontiers.services.jobs.JobService;
20
import org.apache.coyote.BadRequestException;
21
import org.springframework.beans.factory.annotation.Autowired;
22
import org.springframework.http.ResponseEntity;
23
import org.springframework.security.access.AccessDeniedException;
24
import org.springframework.security.access.prepost.PreAuthorize;
25
import org.springframework.web.bind.annotation.*;
26
import org.springframework.web.multipart.MultipartFile;
27
28
import com.fasterxml.jackson.core.JsonProcessingException;
29
30
import edu.ucsb.cs156.frontiers.entities.Course;
31
import edu.ucsb.cs156.frontiers.entities.RosterStudent;
32
import edu.ucsb.cs156.frontiers.enums.OrgStatus;
33
import edu.ucsb.cs156.frontiers.enums.RosterStatus;
34
import edu.ucsb.cs156.frontiers.errors.EntityNotFoundException;
35
import edu.ucsb.cs156.frontiers.repositories.CourseRepository;
36
import edu.ucsb.cs156.frontiers.repositories.RosterStudentRepository;
37
import io.swagger.v3.oas.annotations.Operation;
38
import io.swagger.v3.oas.annotations.Parameter;
39
import io.swagger.v3.oas.annotations.tags.Tag;
40
import jakarta.validation.Valid;
41
import lombok.extern.slf4j.Slf4j;
42
43
import com.opencsv.CSVReader;
44
import com.opencsv.exceptions.CsvException;
45
46
@Tag(name = "RosterStudents")
47
@RequestMapping("/api/rosterstudents")
48
@RestController
49
@Slf4j
50
public class RosterStudentsController extends ApiController {
51
52
    @Autowired
53
    private JobService jobService;
54
    @Autowired
55
    private OrganizationMemberService organizationMemberService;
56
57
    public enum InsertStatus {
58
        INSERTED, UPDATED
59
    };
60
61
    @Autowired
62
    private RosterStudentRepository rosterStudentRepository;
63
64
    @Autowired
65
    private CourseRepository courseRepository;
66
67
    @Autowired
68
    private UpdateUserService updateUserService;
69
70
    @Autowired
71
    private CurrentUserService currentUserService;
72
73
    /**
74
     * This method creates a new RosterStudent.
75
     * 
76
     * 
77
     * @return the created RosterStudent
78
     */
79
80
    @Operation(summary = "Create a new roster student")
81
    @PreAuthorize("hasRole('ROLE_ADMIN')")
82
    @PostMapping("/post")
83
    public RosterStudent postRosterStudent(
84
            @Parameter(name = "studentId") @RequestParam String studentId,
85
            @Parameter(name = "firstName") @RequestParam String firstName,
86
            @Parameter(name = "lastName") @RequestParam String lastName,
87
            @Parameter(name = "email") @RequestParam String email,
88
            @Parameter(name = "courseId") @RequestParam Long courseId) throws EntityNotFoundException {
89
90
        // Get Course or else throw an error
91
92
        Course course = courseRepository.findById(courseId)
93 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));
94
95
        RosterStudent rosterStudent = RosterStudent.builder()
96
                .studentId(studentId)
97
                .firstName(firstName)
98
                .lastName(lastName)
99
                .email(email)
100
                .course(course)
101
                .rosterStatus(RosterStatus.MANUAL)
102
                .orgStatus(OrgStatus.NONE)
103
                .build();
104
        RosterStudent savedRosterStudent = rosterStudentRepository.save(rosterStudent);
105
106 1 1. postRosterStudent : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::postRosterStudent → KILLED
        return savedRosterStudent;
107
    }
108
109
    /**
110
     * This method returns a list of roster students for a given course.
111
     * 
112
     * @return a list of all courses.
113
     */
114
    @Operation(summary = "List all roster students for a course")
115
    @PreAuthorize("hasRole('ROLE_ADMIN')")
116
    @GetMapping("/course")
117
    public Iterable<RosterStudent> rosterStudentForCourse(
118
            @Parameter(name = "courseId") @RequestParam Long courseId) throws EntityNotFoundException {
119 1 1. lambda$rosterStudentForCourse$1 : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::lambda$rosterStudentForCourse$1 → KILLED
        courseRepository.findById(courseId).orElseThrow(() -> new EntityNotFoundException(Course.class, courseId));
120
        Iterable<RosterStudent> rosterStudents = rosterStudentRepository.findByCourseId(courseId);
121 1 1. rosterStudentForCourse : replaced return value with Collections.emptyList for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::rosterStudentForCourse → KILLED
        return rosterStudents;
122
    }
123
124
    @Operation(summary = "Upload Roster students for Course in UCSB Egrades Format")
125
    @PreAuthorize("hasRole('ROLE_ADMIN')")
126
    @PostMapping(value = "/upload/egrades", consumes = { "multipart/form-data" })
127
    public Map<String, String> uploadRosterStudents(
128
            @Parameter(name = "courseId") @RequestParam Long courseId,
129
            @Parameter(name = "file") @RequestParam("file") MultipartFile file)
130
            throws JsonProcessingException, IOException, CsvException {
131
132
        Course course = courseRepository.findById(courseId)
133 1 1. lambda$uploadRosterStudents$2 : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::lambda$uploadRosterStudents$2 → KILLED
                .orElseThrow(() -> new EntityNotFoundException(Course.class, courseId.toString()));
134
135
        int counts[] = { 0, 0 };
136
137
        try (InputStream inputStream = new BufferedInputStream(file.getInputStream());
138
                InputStreamReader reader = new InputStreamReader(inputStream);
139
                CSVReader csvReader = new CSVReader(reader);) {
140 1 1. uploadRosterStudents : removed call to com/opencsv/CSVReader::skip → KILLED
            csvReader.skip(2);
141
            List<String[]> myEntries = csvReader.readAll();
142
            for (String[] row : myEntries) {
143
                RosterStudent rosterStudent = fromEgradesCSVRow(row);
144
                InsertStatus s = upsertStudent(rosterStudent, course);
145 1 1. uploadRosterStudents : Replaced integer addition with subtraction → KILLED
                counts[s.ordinal()]++;
146
            }
147
        }
148 1 1. uploadRosterStudents : replaced return value with Collections.emptyMap for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::uploadRosterStudents → KILLED
        return Map.of(
149
                "filename", file.getOriginalFilename(),
150
                "message", String.format("Inserted %d new students, Updated %d students",
151
                        counts[InsertStatus.INSERTED.ordinal()], counts[InsertStatus.UPDATED.ordinal()]));
152
153
    }
154
155
    public RosterStudent fromEgradesCSVRow(String[] row) {
156 1 1. fromEgradesCSVRow : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::fromEgradesCSVRow → KILLED
        return RosterStudent.builder()
157
                .firstName(row[5])
158
                .lastName(row[4])
159
                .studentId(row[1])
160
                .email(row[10])
161
                .build();
162
    }
163
164
    public InsertStatus upsertStudent(RosterStudent student, Course course) {
165
        Optional<RosterStudent> existingStudent = rosterStudentRepository.findByCourseIdAndStudentId(course.getId(),
166
                student.getStudentId());
167
        String convertedEmail = student.getEmail().replace("@umail.ucsb.edu","@ucsb.edu");
168 1 1. upsertStudent : negated conditional → KILLED
        if (existingStudent.isPresent()) {
169
            RosterStudent existingStudentObj = existingStudent.get();
170 1 1. upsertStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setRosterStatus → KILLED
            existingStudentObj.setRosterStatus(RosterStatus.ROSTER);
171 1 1. upsertStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setFirstName → KILLED
            existingStudentObj.setFirstName(student.getFirstName());
172 1 1. upsertStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setLastName → KILLED
            existingStudentObj.setLastName(student.getLastName());
173 1 1. upsertStudent : negated conditional → KILLED
            if (!existingStudentObj.getEmail().equals(convertedEmail)) {
174 1 1. upsertStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setEmail → KILLED
                existingStudentObj.setEmail(convertedEmail);
175
            }
176
            existingStudentObj = rosterStudentRepository.save(existingStudentObj);
177 1 1. upsertStudent : removed call to edu/ucsb/cs156/frontiers/services/UpdateUserService::attachUserToRosterStudent → KILLED
            updateUserService.attachUserToRosterStudent(existingStudentObj);
178 1 1. upsertStudent : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::upsertStudent → KILLED
            return InsertStatus.UPDATED;
179
        } else {
180 1 1. upsertStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setCourse → KILLED
            student.setCourse(course);
181 1 1. upsertStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setEmail → KILLED
            student.setEmail(convertedEmail);
182 1 1. upsertStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setRosterStatus → KILLED
            student.setRosterStatus(RosterStatus.ROSTER);
183 1 1. upsertStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setOrgStatus → KILLED
            student.setOrgStatus(OrgStatus.NONE);
184
            student = rosterStudentRepository.save(student);
185 1 1. upsertStudent : removed call to edu/ucsb/cs156/frontiers/services/UpdateUserService::attachUserToRosterStudent → KILLED
            updateUserService.attachUserToRosterStudent(student);
186 1 1. upsertStudent : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::upsertStudent → KILLED
            return InsertStatus.INSERTED;
187
        }
188
    }
189
190
    @PreAuthorize("hasRole('ROLE_PROFESSOR')")
191
    @PostMapping("/updateCourseMembership")
192
    public Job updateCourseMembership(@Parameter(name = "courseId", description = "Course ID") @RequestParam Long courseId) throws NoSuchAlgorithmException, InvalidKeySpecException, JsonProcessingException {
193 1 1. lambda$updateCourseMembership$3 : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::lambda$updateCourseMembership$3 → KILLED
        Course course = courseRepository.findById(courseId).orElseThrow(() -> new EntityNotFoundException(Course.class, courseId));
194 2 1. updateCourseMembership : negated conditional → KILLED
2. updateCourseMembership : negated conditional → KILLED
        if(course.getInstallationId() == null || course.getOrgName() == null){
195
            throw new NoLinkedOrganizationException(course.getCourseName());
196
        }else{
197
            UpdateOrgMembershipJob job = UpdateOrgMembershipJob.builder()
198
                    .rosterStudentRepository(rosterStudentRepository)
199
                    .organizationMemberService(organizationMemberService)
200
                    .course(course)
201
                    .build();
202
203 1 1. updateCourseMembership : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::updateCourseMembership → KILLED
            return jobService.runAsJob(job);
204
        }
205
    }
206
    
207
    @Operation(summary = "Link a Roster Student to a Github Account")
208
    @PreAuthorize("hasRole('ROLE_USER')")
209
    @PutMapping("/linkGitHub")
210
    public ResponseEntity<String> linkGitHub(@Parameter(name = "rosterStudentId", description = "Roster Student to be linked to") @RequestParam Long rosterStudentId){
211
        User currentUser = currentUserService.getUser();
212
        RosterStudent rosterStudent = rosterStudentRepository.findById(rosterStudentId)
213 1 1. lambda$linkGitHub$4 : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::lambda$linkGitHub$4 → KILLED
                .orElseThrow(() -> new EntityNotFoundException(RosterStudent.class, rosterStudentId));
214
215 1 1. linkGitHub : negated conditional → KILLED
        if (currentUser.getId() != rosterStudent.getUser().getId()) {
216
            throw new AccessDeniedException("User not authorized to link this roster student");
217
        }
218
219 2 1. linkGitHub : negated conditional → KILLED
2. linkGitHub : negated conditional → KILLED
        if (rosterStudent.getGithubId() != 0 && rosterStudent.getGithubLogin() != null ) {
220 1 1. linkGitHub : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::linkGitHub → KILLED
            return ResponseEntity.badRequest().body("This roster student is already linked to a GitHub account");
221
        }
222
223 1 1. linkGitHub : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setGithubId → KILLED
        rosterStudent.setGithubId(currentUser.getGithubId());
224 1 1. linkGitHub : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setGithubLogin → KILLED
        rosterStudent.setGithubLogin(currentUser.getGithubLogin());
225
        rosterStudentRepository.save(rosterStudent);
226 1 1. linkGitHub : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::linkGitHub → KILLED
        return ResponseEntity.ok("Successfully linked GitHub account to roster student");
227
    }
228
229
    @Operation(summary = "Get Associated Roster Students with a User")
230
    @PreAuthorize("hasRole('ROLE_USER')")
231
    @GetMapping("/associatedRosterStudents")
232
    public Iterable<RosterStudent> getAssociatedRosterStudents(){
233
        User currentUser = currentUserService.getUser();
234
        Iterable<RosterStudent> rosterStudents = rosterStudentRepository.findAllByUser((currentUser));
235 1 1. getAssociatedRosterStudents : replaced return value with Collections.emptyList for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::getAssociatedRosterStudents → KILLED
        return rosterStudents;
236
    }
237
238
    /**
239
     * Update first name, last name, and student number of an existing roster student.
240
     * 
241
     * @param id the RosterStudent record ID
242
     * @param firstName new first name
243
     * @param lastName new last name
244
     * @param studentId new student number (must be unique within the same course)
245
     * @return the updated RosterStudent
246
     * @throws EntityNotFoundException if no RosterStudent exists with that ID
247
     * @throws BadRequestException if the new student number duplicates another in the same course
248
     */
249
    @Operation(summary = "Update a roster student's name and student number")
250
    @PreAuthorize("hasRole('ROLE_ADMIN')")
251
    @PutMapping("/{id}")
252
    public RosterStudent updateRosterStudent(
253
            @Parameter(name = "id", description = "RosterStudent record ID") 
254
            @PathVariable Long id,
255
256
            @Parameter(name = "firstName", description = "New first name") 
257
            @RequestParam String firstName,
258
259
            @Parameter(name = "lastName", description = "New last name") 
260
            @RequestParam String lastName,
261
262
            @Parameter(name = "studentId", description = "New student number") 
263
            @RequestParam String studentId
264
    ) throws EntityNotFoundException, BadRequestException {
265
266
        RosterStudent rs = rosterStudentRepository.findById(id)
267 1 1. lambda$updateRosterStudent$5 : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::lambda$updateRosterStudent$5 → KILLED
            .orElseThrow(() -> new EntityNotFoundException(RosterStudent.class, id));
268
269 1 1. updateRosterStudent : negated conditional → KILLED
        if (!rs.getStudentId().equals(studentId)) {
270
            Optional<RosterStudent> duplicate = 
271
                rosterStudentRepository.findByCourseIdAndStudentId(
272
                    rs.getCourse().getId(), studentId);
273
274 1 1. updateRosterStudent : negated conditional → KILLED
            if (duplicate.isPresent()) {
275
                throw new BadRequestException(
276
                    String.format("Student number '%s' is already used in course %d",
277
                                  studentId, rs.getCourse().getId()));
278
            }
279 1 1. updateRosterStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setStudentId → KILLED
            rs.setStudentId(studentId);
280
        }
281
282 1 1. updateRosterStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setFirstName → KILLED
        rs.setFirstName(firstName);
283 1 1. updateRosterStudent : removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setLastName → KILLED
        rs.setLastName(lastName);
284
285 1 1. updateRosterStudent : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::updateRosterStudent → KILLED
        return rosterStudentRepository.save(rs);
286
    }
287
288
    @Operation(summary = "Delete a roster student by record ID")
289
    @PreAuthorize("hasRole('ROLE_ADMIN')")
290
    @DeleteMapping("/{id}")
291
    public ResponseEntity<String> deleteRosterStudentById(
292
        @Parameter(description = "RosterStudent record ID") @PathVariable Long id)
293
        throws EntityNotFoundException {
294
295
        RosterStudent rs = rosterStudentRepository.findById(id)
296 1 1. lambda$deleteRosterStudentById$6 : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::lambda$deleteRosterStudentById$6 → KILLED
            .orElseThrow(() -> new EntityNotFoundException(RosterStudent.class, id));
297
298 1 1. deleteRosterStudentById : removed call to edu/ucsb/cs156/frontiers/repositories/RosterStudentRepository::delete → KILLED
        rosterStudentRepository.delete(rs);
299
300 1 1. deleteRosterStudentById : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::deleteRosterStudentById → KILLED
        return ResponseEntity.ok(
301
            String.format("Deleted roster student %d", id));
302
    }
303
304
}
305

Mutations

93

1.1
Location : lambda$postRosterStudent$0
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:test_AdminCannotPostRosterStudentForCourseThatDoesNotExist()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::lambda$postRosterStudent$0 → KILLED

106

1.1
Location : postRosterStudent
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:testPostRosterStudent()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::postRosterStudent → KILLED

119

1.1
Location : lambda$rosterStudentForCourse$1
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:admin_can_get_roster_students_for_a_non_existing_course()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::lambda$rosterStudentForCourse$1 → KILLED

121

1.1
Location : rosterStudentForCourse
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:testRosterStudentsByCourse()]
replaced return value with Collections.emptyList for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::rosterStudentForCourse → KILLED

133

1.1
Location : lambda$uploadRosterStudents$2
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:admin_cannot_upload_students_for_a_course_that_does_not_exist()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::lambda$uploadRosterStudents$2 → KILLED

140

1.1
Location : uploadRosterStudents
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:admin_can_upload_students_for_an_existing_course()]
removed call to com/opencsv/CSVReader::skip → KILLED

145

1.1
Location : uploadRosterStudents
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:admin_can_upload_students_for_an_existing_course()]
Replaced integer addition with subtraction → KILLED

148

1.1
Location : uploadRosterStudents
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:admin_can_upload_students_for_an_existing_course()]
replaced return value with Collections.emptyMap for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::uploadRosterStudents → KILLED

156

1.1
Location : fromEgradesCSVRow
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:admin_can_upload_students_for_an_existing_course()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::fromEgradesCSVRow → KILLED

168

1.1
Location : upsertStudent
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:admin_can_upload_students_for_an_existing_course()]
negated conditional → KILLED

170

1.1
Location : upsertStudent
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:admin_can_upload_students_for_an_existing_course()]
removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setRosterStatus → KILLED

171

1.1
Location : upsertStudent
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:admin_can_upload_students_for_an_existing_course()]
removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setFirstName → KILLED

172

1.1
Location : upsertStudent
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:admin_can_upload_students_for_an_existing_course()]
removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setLastName → KILLED

173

1.1
Location : upsertStudent
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:admin_can_upload_students_for_an_existing_course()]
negated conditional → KILLED

174

1.1
Location : upsertStudent
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:admin_can_upload_students_for_an_existing_course()]
removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setEmail → KILLED

177

1.1
Location : upsertStudent
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:admin_can_upload_students_for_an_existing_course()]
removed call to edu/ucsb/cs156/frontiers/services/UpdateUserService::attachUserToRosterStudent → KILLED

178

1.1
Location : upsertStudent
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:admin_can_upload_students_for_an_existing_course()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::upsertStudent → KILLED

180

1.1
Location : upsertStudent
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:admin_can_upload_students_for_an_existing_course()]
removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setCourse → KILLED

181

1.1
Location : upsertStudent
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:admin_can_upload_students_for_an_existing_course()]
removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setEmail → KILLED

182

1.1
Location : upsertStudent
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:admin_can_upload_students_for_an_existing_course()]
removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setRosterStatus → KILLED

183

1.1
Location : upsertStudent
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:admin_can_upload_students_for_an_existing_course()]
removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setOrgStatus → KILLED

185

1.1
Location : upsertStudent
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:admin_can_upload_students_for_an_existing_course()]
removed call to edu/ucsb/cs156/frontiers/services/UpdateUserService::attachUserToRosterStudent → KILLED

186

1.1
Location : upsertStudent
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:admin_can_upload_students_for_an_existing_course()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::upsertStudent → KILLED

193

1.1
Location : lambda$updateCourseMembership$3
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:notFound()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::lambda$updateCourseMembership$3 → KILLED

194

1.1
Location : updateCourseMembership
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:just_no_org_name()]
negated conditional → KILLED

2.2
Location : updateCourseMembership
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:not_registered_org()]
negated conditional → KILLED

203

1.1
Location : updateCourseMembership
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:job_actually_fires()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::updateCourseMembership → KILLED

213

1.1
Location : lambda$linkGitHub$4
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:testLinkGitHub_notFound()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::lambda$linkGitHub$4 → KILLED

215

1.1
Location : linkGitHub
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:testLinkGitHub_alreadyLinked()]
negated conditional → KILLED

219

1.1
Location : linkGitHub
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:testLinkGitHub_alreadyLinked()]
negated conditional → KILLED

2.2
Location : linkGitHub
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:testLinkGitHub_alreadyLinked()]
negated conditional → KILLED

220

1.1
Location : linkGitHub
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:testLinkGitHub_alreadyLinked()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::linkGitHub → KILLED

223

1.1
Location : linkGitHub
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:testLinkGitHub_success()]
removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setGithubId → KILLED

224

1.1
Location : linkGitHub
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:testLinkGitHub_success()]
removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setGithubLogin → KILLED

226

1.1
Location : linkGitHub
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:testLinkGitHub_success()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::linkGitHub → KILLED

235

1.1
Location : getAssociatedRosterStudents
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:testGetAssociatedRosterStudents()]
replaced return value with Collections.emptyList for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::getAssociatedRosterStudents → KILLED

267

1.1
Location : lambda$updateRosterStudent$5
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:updateRosterStudent_notFound()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::lambda$updateRosterStudent$5 → KILLED

269

1.1
Location : updateRosterStudent
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:updateRosterStudent_badRequest_onDuplicate()]
negated conditional → KILLED

274

1.1
Location : updateRosterStudent
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:updateRosterStudent_badRequest_onDuplicate()]
negated conditional → KILLED

279

1.1
Location : updateRosterStudent
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:updateRosterStudent_success_withIdChange()]
removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setStudentId → KILLED

282

1.1
Location : updateRosterStudent
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:updateRosterStudent_success_withIdChange()]
removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setFirstName → KILLED

283

1.1
Location : updateRosterStudent
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:updateRosterStudent_success_withIdChange()]
removed call to edu/ucsb/cs156/frontiers/entities/RosterStudent::setLastName → KILLED

285

1.1
Location : updateRosterStudent
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:updateRosterStudent_success_withIdChange()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::updateRosterStudent → KILLED

296

1.1
Location : lambda$deleteRosterStudentById$6
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:admin_tries_to_delete_non_existent_rosterstudent_and_gets_right_error_message()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::lambda$deleteRosterStudentById$6 → KILLED

298

1.1
Location : deleteRosterStudentById
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:admin_can_delete_a_rosterstudent()]
removed call to edu/ucsb/cs156/frontiers/repositories/RosterStudentRepository::delete → KILLED

300

1.1
Location : deleteRosterStudentById
Killed by : edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RosterStudentsControllerTests]/[method:admin_can_delete_a_rosterstudent()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RosterStudentsController::deleteRosterStudentById → KILLED

Active mutators

Tests examined


Report generated by PIT 1.17.0