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