| 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 |
|
| 104 |
1.1 |
|
| 108 |
1.1 |
|
| 115 |
1.1 |
|
| 139 |
1.1 |
|
| 154 |
1.1 |
|
| 157 |
1.1 |
|
| 167 |
1.1 |
|
| 169 |
1.1 |
|
| 187 |
1.1 |
|
| 204 |
1.1 |
|
| 212 |
1.1 |
|
| 227 |
1.1 |
|
| 228 |
1.1 |
|
| 244 |
1.1 |
|
| 247 |
1.1 |
|
| 249 |
1.1 |
|
| 253 |
1.1 |
|
| 259 |
1.1 |
|
| 261 |
1.1 |
|
| 262 |
1.1 |
|
| 283 |
1.1 |
|
| 288 |
1.1 |
|
| 290 |
1.1 |
|
| 294 |
1.1 |
|
| 299 |
1.1 |
|
| 308 |
1.1 |
|
| 327 |
1.1 |
|
| 332 |
1.1 |
|
| 335 |
1.1 |
|
| 360 |
1.1 2.2 |
|
| 362 |
1.1 2.2 |
|
| 363 |
1.1 |
|
| 368 |
1.1 |
|
| 369 |
1.1 |
|
| 381 |
1.1 |
|
| 388 |
1.1 2.2 |
|
| 391 |
1.1 |
|
| 392 |
1.1 |
|
| 397 |
1.1 |
|
| 399 |
1.1 |
|
| 405 |
1.1 |
|
| 407 |
1.1 |