TeamsController.java

1
package edu.ucsb.cs156.frontiers.controllers;
2
3
import com.opencsv.CSVReader;
4
import com.opencsv.exceptions.CsvException;
5
import edu.ucsb.cs156.frontiers.entities.Course;
6
import edu.ucsb.cs156.frontiers.entities.RosterStudent;
7
import edu.ucsb.cs156.frontiers.entities.Team;
8
import edu.ucsb.cs156.frontiers.entities.TeamMember;
9
import edu.ucsb.cs156.frontiers.errors.EntityNotFoundException;
10
import edu.ucsb.cs156.frontiers.jobs.PushTeamsToGithubJob;
11
import edu.ucsb.cs156.frontiers.repositories.CourseRepository;
12
import edu.ucsb.cs156.frontiers.repositories.RosterStudentRepository;
13
import edu.ucsb.cs156.frontiers.repositories.TeamMemberRepository;
14
import edu.ucsb.cs156.frontiers.repositories.TeamRepository;
15
import edu.ucsb.cs156.frontiers.services.GithubTeamService;
16
import edu.ucsb.cs156.frontiers.services.jobs.JobService;
17
import io.swagger.v3.oas.annotations.Operation;
18
import io.swagger.v3.oas.annotations.Parameter;
19
import io.swagger.v3.oas.annotations.tags.Tag;
20
import java.io.BufferedInputStream;
21
import java.io.IOException;
22
import java.io.InputStream;
23
import java.io.InputStreamReader;
24
import java.util.*;
25
import lombok.extern.slf4j.Slf4j;
26
import org.springframework.beans.factory.annotation.Autowired;
27
import org.springframework.http.HttpStatus;
28
import org.springframework.http.ResponseEntity;
29
import org.springframework.security.access.prepost.PreAuthorize;
30
import org.springframework.transaction.annotation.Transactional;
31
import org.springframework.web.bind.annotation.*;
32
import org.springframework.web.multipart.MultipartFile;
33
import org.springframework.web.server.ResponseStatusException;
34
35
@Tag(name = "Teams")
36
@RequestMapping("/api/teams")
37
@RestController
38
@Slf4j
39
public class TeamsController extends ApiController {
40
41
  @Autowired private TeamRepository teamRepository;
42
43
  @Autowired private TeamMemberRepository teamMemberRepository;
44
45
  @Autowired private CourseRepository courseRepository;
46
47
  @Autowired private RosterStudentRepository rosterStudentRepository;
48
49
  @Autowired private JobService jobService;
50
51
  @Autowired private GithubTeamService githubTeamService;
52
53
  public record TeamMemberResult(
54
      TeamMember teamMember, TeamMemberStatus status, String rejectedEmail) {
55
    public TeamMemberResult(TeamMember teamMember, TeamMemberStatus status) {
56
      this(teamMember, status, null);
57
    }
58
59
    public TeamMemberResult(String rejectedEmail) {
60
      this(null, TeamMemberStatus.MISSING, rejectedEmail);
61
    }
62
  }
63
64
  public record TeamCreationResponse(
65
      TeamSourceType typeMatched, Integer created, Integer existing, List<String> rejected) {}
66
67
  public record TeamMemberMapping(
68
      Long teamId,
69
      String teamName,
70
      Long rosterStudentId,
71
      String email,
72
      String firstName,
73
      String lastName,
74
      String githubLogin) {
75
    public static TeamMemberMapping from(TeamMember member) {
76 1 1. from : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController$TeamMemberMapping::from → KILLED
      return new TeamMemberMapping(
77
          member.getTeam().getId(),
78
          member.getTeam().getName(),
79
          member.getRosterStudent().getId(),
80
          member.getRosterStudent().getEmail(),
81
          member.getRosterStudent().getFirstName(),
82
          member.getRosterStudent().getLastName(),
83
          member.getRosterStudent().getGithubLogin());
84
    }
85
  }
86
87
  /**
88
   * This method creates a new Team.
89
   *
90
   * @param name the name of the team
91
   * @param courseId the ID of the course this team belongs to
92
   * @return the created team
93
   */
94
  @Operation(summary = "Create a new team")
95
  @PreAuthorize("@CourseSecurity.hasManagePermissions(#root, #courseId)")
96
  @PostMapping("/post")
97
  public Team postTeam(
98
      @Parameter(name = "name") @RequestParam String name,
99
      @Parameter(name = "courseId") @RequestParam Long courseId) {
100
101
    Course course =
102
        courseRepository
103
            .findById(courseId)
104 1 1. lambda$postTeam$0 : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::lambda$postTeam$0 → KILLED
            .orElseThrow(() -> new EntityNotFoundException(Course.class, courseId));
105
106
    Team team = Team.builder().name(name).course(course).build();
107
108 1 1. postTeam : negated conditional → KILLED
    if (teamRepository.findByCourseIdAndName(course.getId(), name).isPresent()) {
109
      throw new ResponseStatusException(
110
          HttpStatus.CONFLICT, "Team with name %s already exists".formatted(name));
111
    } else {
112
      team = teamRepository.save(team);
113
    }
114
115 1 1. postTeam : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::postTeam → KILLED
    return team;
116
  }
117
118
  /**
119
   * Upload teams in CSV format (team, email) It is important to keep the code in this method
120
   * consistent with the code for adding a single roster student
121
   *
122
   * @param courseId course the teams are for
123
   * @param file csv file with roster student emails and team assignments
124
   * @return Count of students added to teams, already existing, and rejected students
125
   */
126
  @Operation(summary = "Upload team assignments; CSV in format team,email")
127
  @PreAuthorize("@CourseSecurity.hasManagePermissions(#root, #courseId)")
128
  @PostMapping(
129
      value = "/upload/csv",
130
      consumes = {"multipart/form-data"})
131
  public ResponseEntity<TeamCreationResponse> uploadTeamsCsv(
132
      @Parameter(name = "courseId") @RequestParam Long courseId,
133
      @Parameter(name = "file") @RequestParam("file") MultipartFile file)
134
      throws IOException, CsvException {
135
136
    Course course =
137
        courseRepository
138
            .findById(courseId)
139 1 1. lambda$uploadTeamsCsv$1 : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::lambda$uploadTeamsCsv$1 → KILLED
            .orElseThrow(() -> new EntityNotFoundException(Course.class, courseId.toString()));
140
141
    int counts[] = {0, 0};
142
143
    List<String> failed = new ArrayList<>();
144
145
    try (InputStream inputStream = new BufferedInputStream(file.getInputStream());
146
        InputStreamReader reader = new InputStreamReader(inputStream);
147
        CSVReader csvReader = new CSVReader(reader); ) {
148
149
      String[] headers = csvReader.readNext();
150
      TeamSourceType sourceType = getRosterSourceType(headers);
151
      List<String[]> myEntries = csvReader.readAll();
152
      for (String[] row : myEntries) {
153
        TeamMemberResult rowResult = fromCSVRow(row, sourceType, course);
154 1 1. uploadTeamsCsv : negated conditional → KILLED
        if (rowResult.status == TeamMemberStatus.MISSING) {
155
          failed.add(rowResult.rejectedEmail);
156
        } else {
157 1 1. uploadTeamsCsv : Replaced integer addition with subtraction → KILLED
          counts[rowResult.status.ordinal()]++;
158
        }
159
      }
160
      TeamCreationResponse response =
161
          new TeamCreationResponse(
162
              sourceType,
163
              counts[TeamMemberStatus.CREATED.ordinal()],
164
              counts[TeamMemberStatus.EXISTS.ordinal()],
165
              failed);
166
167 1 1. uploadTeamsCsv : removed call to edu/ucsb/cs156/frontiers/controllers/TeamsController::launchPushTeamsToGithubJob → KILLED
      launchPushTeamsToGithubJob(courseId);
168
169 1 1. uploadTeamsCsv : negated conditional → KILLED
      if (!failed.isEmpty()) {
170
        return ResponseEntity.status(HttpStatus.CONFLICT).body(response);
171
      } else {
172
        return ResponseEntity.ok(response);
173
      }
174
    }
175
  }
176
177
  /**
178
   * This method returns a list of all teams for a course
179
   *
180
   * @return a list of all teams for a course
181
   */
182
  @Operation(summary = "List all teams")
183
  @PreAuthorize("@CourseSecurity.hasManagePermissions(#root, #courseId)")
184
  @GetMapping("/all")
185
  public Iterable<Team> allTeams(@RequestParam Long courseId) {
186
    Iterable<Team> teams = teamRepository.findByCourseIdOrderByNameAsc(courseId);
187 1 1. allTeams : replaced return value with Collections.emptyList for edu/ucsb/cs156/frontiers/controllers/TeamsController::allTeams → KILLED
    return teams;
188
  }
189
190
  /**
191
   * Retrieves a list of mappings between roster students and teams for a given course. Each mapping
192
   * represents a relationship between a team and its members.
193
   *
194
   * @param courseId the unique identifier of the course for which team mappings are retrieved
195
   * @return an iterable collection of {@code TeamMemberMapping} objects representing the mappings
196
   */
197
  @Operation(summary = "List the mapping of Roster Students to Teams")
198
  @PreAuthorize("@CourseSecurity.hasManagePermissions(#root, #courseId)")
199
  @GetMapping("/mapping")
200
  public Iterable<TeamMemberMapping> teamMemberMapping(@RequestParam Long courseId) {
201
    List<Team> teams =
202
        courseRepository
203
            .findById(courseId)
204 1 1. lambda$teamMemberMapping$2 : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::lambda$teamMemberMapping$2 → KILLED
            .orElseThrow(() -> new EntityNotFoundException(Course.class, courseId))
205
            .getTeams();
206
    List<TeamMemberMapping> mappings = new ArrayList<>();
207
    for (Team team : teams) {
208
      for (TeamMember member : team.getTeamMembers()) {
209
        mappings.add(TeamMemberMapping.from(member));
210
      }
211
    }
212 1 1. teamMemberMapping : replaced return value with Collections.emptyList for edu/ucsb/cs156/frontiers/controllers/TeamsController::teamMemberMapping → KILLED
    return mappings;
213
  }
214
215
  /**
216
   * This method returns a single team by its id
217
   *
218
   * @param id the id of the team
219
   * @return the team
220
   */
221
  @Operation(summary = "Get a single team")
222
  @PreAuthorize("@CourseSecurity.hasManagePermissions(#root, #courseId)")
223
  @GetMapping("")
224
  public Team getTeamById(
225
      @Parameter(name = "id") @RequestParam Long id, @RequestParam Long courseId) {
226
    Team team =
227 1 1. lambda$getTeamById$3 : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::lambda$getTeamById$3 → KILLED
        teamRepository.findById(id).orElseThrow(() -> new EntityNotFoundException(Team.class, id));
228 1 1. getTeamById : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::getTeamById → KILLED
    return team;
229
  }
230
231
  /**
232
   * This method deletes a team by its id
233
   *
234
   * @param id the id of the team to delete
235
   * @return a message indicating the team was deleted
236
   */
237
  @Operation(summary = "Delete a team")
238
  @PreAuthorize("@CourseSecurity.hasManagePermissions(#root, #courseId)")
239
  @DeleteMapping("")
240
  @Transactional
241
  public Object deleteTeam(
242
      @Parameter(name = "id") @RequestParam Long id, @RequestParam Long courseId) {
243
    Team team =
244 1 1. lambda$deleteTeam$4 : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::lambda$deleteTeam$4 → KILLED
        teamRepository.findById(id).orElseThrow(() -> new EntityNotFoundException(Team.class, id));
245
246
    // Handle team members that reference this team
247 1 1. deleteTeam : negated conditional → KILLED
    if (!team.getTeamMembers().isEmpty()) {
248
      team.getTeamMembers()
249 1 1. deleteTeam : removed call to java/util/List::forEach → KILLED
          .forEach(
250
              teamMember -> {
251
                // Remove from roster student's team members list
252
                teamMember.getRosterStudent().getTeamMembers().remove(teamMember);
253 1 1. lambda$deleteTeam$5 : removed call to edu/ucsb/cs156/frontiers/entities/TeamMember::setRosterStudent → KILLED
                teamMember.setRosterStudent(null);
254
              });
255
    }
256
257
    // Disconnect from course
258
    team.getCourse().getTeams().remove(team);
259 1 1. deleteTeam : removed call to edu/ucsb/cs156/frontiers/entities/Team::setCourse → KILLED
    team.setCourse(null);
260
261 1 1. deleteTeam : removed call to edu/ucsb/cs156/frontiers/repositories/TeamRepository::delete → KILLED
    teamRepository.delete(team);
262 1 1. deleteTeam : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::deleteTeam → KILLED
    return genericMessage("Team with id %s deleted".formatted(id));
263
  }
264
265
  /**
266
   * This method adds a roster student as a team member
267
   *
268
   * @param teamId the ID of the team
269
   * @param rosterStudentId the ID of the roster student to add
270
   * @return the created team member
271
   */
272
  @Operation(summary = "Add a roster student to a team")
273
  @PreAuthorize("@CourseSecurity.hasManagePermissions(#root, #courseId)")
274
  @PostMapping("/addMember")
275
  public TeamMember addTeamMember(
276
      @Parameter(name = "teamId") @RequestParam Long teamId,
277
      @Parameter(name = "rosterStudentId") @RequestParam Long rosterStudentId,
278
      @Parameter(name = "courseId") @RequestParam Long courseId) {
279
280
    Team team =
281
        teamRepository
282
            .findById(teamId)
283 1 1. lambda$addTeamMember$6 : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::lambda$addTeamMember$6 → KILLED
            .orElseThrow(() -> new EntityNotFoundException(Team.class, teamId));
284
285
    RosterStudent rosterStudent =
286
        rosterStudentRepository
287
            .findById(rosterStudentId)
288 1 1. lambda$addTeamMember$7 : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::lambda$addTeamMember$7 → KILLED
            .orElseThrow(() -> new EntityNotFoundException(RosterStudent.class, rosterStudentId));
289
290 1 1. addTeamMember : negated conditional → KILLED
    if (!team.getCourse().getId().equals(courseId)) {
291
      throw new ResponseStatusException(
292
          HttpStatus.BAD_REQUEST, "Team is not from course %d".formatted(courseId));
293
    }
294 1 1. addTeamMember : negated conditional → KILLED
    if (!rosterStudent.getCourse().getId().equals(courseId)) {
295
      throw new ResponseStatusException(
296
          HttpStatus.BAD_REQUEST, "Roster student is not from course %d".formatted(courseId));
297
    }
298
299 1 1. addTeamMember : negated conditional → KILLED
    if (teamMemberRepository.findByTeamAndRosterStudent(team, rosterStudent).isPresent()) {
300
      throw new ResponseStatusException(
301
          HttpStatus.CONFLICT,
302
          "Team member already exists for team %s and roster student %s"
303
              .formatted(team.getName(), rosterStudent.getEmail()));
304
    }
305
    TeamMember teamMember = TeamMember.builder().team(team).rosterStudent(rosterStudent).build();
306
    TeamMember savedTeamMember = teamMemberRepository.save(teamMember);
307
308 1 1. addTeamMember : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::addTeamMember → KILLED
    return savedTeamMember;
309
  }
310
311
  /**
312
   * This method removes a team member
313
   *
314
   * @param teamMemberId the ID of the team member to remove
315
   * @return a message indicating the team member was removed
316
   */
317
  @Operation(summary = "Remove a team member")
318
  @PreAuthorize("@CourseSecurity.hasManagePermissions(#root, #courseId)")
319
  @DeleteMapping("/removeMember")
320
  @Transactional
321
  public Object removeTeamMember(
322
      @Parameter(name = "teamMemberId") @RequestParam Long teamMemberId,
323
      @Parameter(name = "courseId") @RequestParam Long courseId) {
324
    TeamMember teamMember =
325
        teamMemberRepository
326
            .findById(teamMemberId)
327 1 1. lambda$removeTeamMember$8 : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::lambda$removeTeamMember$8 → KILLED
            .orElseThrow(() -> new EntityNotFoundException(TeamMember.class, teamMemberId));
328
    Team team = teamMember.getTeam();
329
    RosterStudent rosterStudent = teamMember.getRosterStudent();
330
    team.getTeamMembers().remove(teamMember);
331
    rosterStudent.getTeamMembers().remove(teamMember);
332 1 1. removeTeamMember : removed call to edu/ucsb/cs156/frontiers/repositories/TeamMemberRepository::delete → KILLED
    teamMemberRepository.delete(teamMember);
333
    teamRepository.save(team);
334
    rosterStudentRepository.save(rosterStudent);
335 1 1. removeTeamMember : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::removeTeamMember → KILLED
    return genericMessage("Team member with id %s deleted".formatted(teamMemberId));
336
  }
337
338
  public enum TeamSourceType {
339
    SIMPLE,
340
    UNKNOWN
341
  }
342
343
  public enum TeamMemberStatus {
344
    CREATED,
345
    EXISTS,
346
    MISSING
347
  }
348
349
  public static final String SIMPLE_HEADERS = "team,email";
350
351
  public TeamSourceType getRosterSourceType(String[] headers) {
352
353
    Map<TeamSourceType, String[]> sourceTypeToHeaders = new HashMap<>();
354
355
    sourceTypeToHeaders.put(TeamSourceType.SIMPLE, SIMPLE_HEADERS.split(","));
356
357
    for (Map.Entry<TeamSourceType, String[]> entry : sourceTypeToHeaders.entrySet()) {
358
      TeamSourceType type = entry.getKey();
359
      String[] expectedHeaders = entry.getValue();
360 2 1. getRosterSourceType : negated conditional → KILLED
2. getRosterSourceType : changed conditional boundary → KILLED
      if (headers.length >= expectedHeaders.length) {
361
        boolean matches = true;
362 2 1. getRosterSourceType : changed conditional boundary → KILLED
2. getRosterSourceType : negated conditional → KILLED
        for (int i = 0; i < expectedHeaders.length; i++) {
363 1 1. getRosterSourceType : negated conditional → KILLED
          if (!expectedHeaders[i].equalsIgnoreCase(headers[i])) {
364
            matches = false;
365
            break;
366
          }
367
        }
368 1 1. getRosterSourceType : negated conditional → KILLED
        if (matches) {
369 1 1. getRosterSourceType : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::getRosterSourceType → KILLED
          return type;
370
        }
371
      }
372
    }
373
    // If no known type matches, throw
374
    throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Unknown Roster Source Type");
375
  }
376
377
  public TeamMemberResult fromCSVRow(String[] row, TeamSourceType sourceType, Course course) {
378
    // No if statements because this is the only possible value to enter here at the moment. Replace
379
    // with if when more
380
    // Formats are added.
381 1 1. fromCSVRow : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::fromCSVRow → KILLED
    return teamMemberFromSimpleCsv(row, course);
382
  }
383
384
  public TeamMemberResult teamMemberFromSimpleCsv(String[] row, Course course) {
385
    Optional<RosterStudent> student =
386
        rosterStudentRepository.findByCourseIdAndEmail(course.getId(), row[1]);
387
    Optional<Team> team = teamRepository.findByCourseIdAndName(course.getId(), row[0]);
388 2 1. teamMemberFromSimpleCsv : negated conditional → KILLED
2. teamMemberFromSimpleCsv : negated conditional → KILLED
    if (student.isPresent() && team.isPresent()) {
389
      Optional<TeamMember> teamMember =
390
          teamMemberRepository.findByTeamAndRosterStudent(team.get(), student.get());
391 1 1. teamMemberFromSimpleCsv : negated conditional → KILLED
      if (teamMember.isPresent()) {
392 1 1. teamMemberFromSimpleCsv : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::teamMemberFromSimpleCsv → KILLED
        return new TeamMemberResult(teamMember.get(), TeamMemberStatus.EXISTS);
393
      } else {
394
        TeamMember teamMemberToSave =
395
            TeamMember.builder().team(team.get()).rosterStudent(student.get()).build();
396
        TeamMember savedTeamMember = teamMemberRepository.save(teamMemberToSave);
397 1 1. teamMemberFromSimpleCsv : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::teamMemberFromSimpleCsv → KILLED
        return new TeamMemberResult(savedTeamMember, TeamMemberStatus.CREATED);
398
      }
399 1 1. teamMemberFromSimpleCsv : negated conditional → KILLED
    } else if (student.isPresent()) {
400
      Team teamToSave = Team.builder().name(row[0]).course(course).build();
401
      teamRepository.save(teamToSave);
402
      TeamMember saveTeamMember =
403
          TeamMember.builder().team(teamToSave).rosterStudent(student.get()).build();
404
      teamMemberRepository.save(saveTeamMember);
405 1 1. teamMemberFromSimpleCsv : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::teamMemberFromSimpleCsv → KILLED
      return new TeamMemberResult(saveTeamMember, TeamMemberStatus.CREATED);
406
    } else {
407 1 1. teamMemberFromSimpleCsv : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::teamMemberFromSimpleCsv → KILLED
      return new TeamMemberResult(row[1]);
408
    }
409
  }
410
411
  private void launchPushTeamsToGithubJob(Long courseId) {
412
    PushTeamsToGithubJob pushTeamsToGithubJob =
413
        PushTeamsToGithubJob.builder()
414
            .courseId(courseId)
415
            .courseRepository(courseRepository)
416
            .teamRepository(teamRepository)
417
            .teamMemberRepository(teamMemberRepository)
418
            .githubTeamService(githubTeamService)
419
            .build();
420
    jobService.runAsJob(pushTeamsToGithubJob);
421
  }
422
}

Mutations

76

1.1
Location : from
Killed by : edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests]/[method:testTeamMemberMapping_success()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController$TeamMemberMapping::from → KILLED

104

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

108

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

115

1.1
Location : postTeam
Killed by : edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests]/[method:testPostTeam_byInstructor()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::postTeam → KILLED

139

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

154

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

157

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

167

1.1
Location : uploadTeamsCsv
Killed by : edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests]/[method:testUploadTeamsCsv_success_noRejectedStudents()]
removed call to edu/ucsb/cs156/frontiers/controllers/TeamsController::launchPushTeamsToGithubJob → KILLED

169

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

187

1.1
Location : allTeams
Killed by : edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests]/[method:testAllTeams_ROLE_INSTRUCTOR()]
replaced return value with Collections.emptyList for edu/ucsb/cs156/frontiers/controllers/TeamsController::allTeams → KILLED

204

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

212

1.1
Location : teamMemberMapping
Killed by : edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests]/[method:testTeamMemberMapping_success()]
replaced return value with Collections.emptyList for edu/ucsb/cs156/frontiers/controllers/TeamsController::teamMemberMapping → KILLED

227

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

228

1.1
Location : getTeamById
Killed by : edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests]/[method:testGetTeamById()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::getTeamById → KILLED

244

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

247

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

249

1.1
Location : deleteTeam
Killed by : edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests]/[method:testDeleteTeam_success()]
removed call to java/util/List::forEach → KILLED

253

1.1
Location : lambda$deleteTeam$5
Killed by : edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests]/[method:testDeleteTeam_success()]
removed call to edu/ucsb/cs156/frontiers/entities/TeamMember::setRosterStudent → KILLED

259

1.1
Location : deleteTeam
Killed by : edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests]/[method:testDeleteTeam_withEmptyTeamMembers()]
removed call to edu/ucsb/cs156/frontiers/entities/Team::setCourse → KILLED

261

1.1
Location : deleteTeam
Killed by : edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests]/[method:testDeleteTeam_withEmptyTeamMembers()]
removed call to edu/ucsb/cs156/frontiers/repositories/TeamRepository::delete → KILLED

262

1.1
Location : deleteTeam
Killed by : edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests]/[method:testDeleteTeam_withEmptyTeamMembers()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::deleteTeam → KILLED

283

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

288

1.1
Location : lambda$addTeamMember$7
Killed by : edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests]/[method:testAddTeamMember_rosterStudentNotFound()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::lambda$addTeamMember$7 → KILLED

290

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

294

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

299

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

308

1.1
Location : addTeamMember
Killed by : edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests]/[method:testAddTeamMember_success()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::addTeamMember → KILLED

327

1.1
Location : lambda$removeTeamMember$8
Killed by : edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests]/[method:testRemoveTeamMember_teamMemberDoesNotExist()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::lambda$removeTeamMember$8 → KILLED

332

1.1
Location : removeTeamMember
Killed by : edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests]/[method:testRemoveTeamMember_success()]
removed call to edu/ucsb/cs156/frontiers/repositories/TeamMemberRepository::delete → KILLED

335

1.1
Location : removeTeamMember
Killed by : edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests]/[method:testRemoveTeamMember_success()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::removeTeamMember → KILLED

360

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

2.2
Location : getRosterSourceType
Killed by : edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests]/[method:testUploadTeamsCsv_success_noRejectedStudents()]
changed conditional boundary → KILLED

362

1.1
Location : getRosterSourceType
Killed by : edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests]/[method:testUploadTeamsCsv_success_noRejectedStudents()]
changed conditional boundary → KILLED

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

363

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

368

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

369

1.1
Location : getRosterSourceType
Killed by : edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests]/[method:testUploadTeamsCsv_success_noRejectedStudents()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::getRosterSourceType → KILLED

381

1.1
Location : fromCSVRow
Killed by : edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests]/[method:testUploadTeamsCsv_success_noRejectedStudents()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::fromCSVRow → KILLED

388

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

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

391

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

392

1.1
Location : teamMemberFromSimpleCsv
Killed by : edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests]/[method:testUploadTeamsCsv_success_noRejectedStudents()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::teamMemberFromSimpleCsv → KILLED

397

1.1
Location : teamMemberFromSimpleCsv
Killed by : edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests]/[method:testUploadTeamsCsv_success_noRejectedStudents()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::teamMemberFromSimpleCsv → KILLED

399

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

405

1.1
Location : teamMemberFromSimpleCsv
Killed by : edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests]/[method:testUploadTeamsCsv_success_noRejectedStudents()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::teamMemberFromSimpleCsv → KILLED

407

1.1
Location : teamMemberFromSimpleCsv
Killed by : edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.TeamsControllerTests]/[method:csv_rejected_returns_conflict()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/TeamsController::teamMemberFromSimpleCsv → KILLED

Active mutators

Tests examined


Report generated by PIT 1.17.0