PullTeamsFromCanvasJob.java

1
package edu.ucsb.cs156.frontiers.jobs;
2
3
import edu.ucsb.cs156.frontiers.entities.Course;
4
import edu.ucsb.cs156.frontiers.entities.RosterStudent;
5
import edu.ucsb.cs156.frontiers.entities.Team;
6
import edu.ucsb.cs156.frontiers.entities.TeamMember;
7
import edu.ucsb.cs156.frontiers.errors.DuplicateGroupException;
8
import edu.ucsb.cs156.frontiers.models.CanvasGroup;
9
import edu.ucsb.cs156.frontiers.repositories.CourseRepository;
10
import edu.ucsb.cs156.frontiers.repositories.TeamMemberRepository;
11
import edu.ucsb.cs156.frontiers.repositories.TeamRepository;
12
import edu.ucsb.cs156.frontiers.services.CanvasService;
13
import edu.ucsb.cs156.frontiers.services.jobs.JobContext;
14
import edu.ucsb.cs156.frontiers.services.jobs.JobContextConsumer;
15
import edu.ucsb.cs156.frontiers.utilities.CanonicalFormConverter;
16
import jakarta.transaction.Transactional;
17
import java.util.ArrayList;
18
import java.util.HashMap;
19
import java.util.HashSet;
20
import java.util.List;
21
import java.util.Optional;
22
import java.util.Set;
23
import java.util.stream.Collectors;
24
import lombok.Builder;
25
26
@Builder
27
public class PullTeamsFromCanvasJob implements JobContextConsumer {
28
29
  Course course;
30
  String groupsetId;
31
  CanvasService canvasService;
32
  TeamRepository teamRepository;
33
  TeamMemberRepository teamMemberRepository;
34
  CourseRepository courseRepository;
35
36
  @Override
37
  public Course getCourse() {
38 1 1. getCourse : replaced return value with null for edu/ucsb/cs156/frontiers/jobs/PullTeamsFromCanvasJob::getCourse → KILLED
    return course;
39
  }
40
41
  @Override
42
  @Transactional
43
  public void accept(JobContext ctx) throws Exception {
44
    // Prior to attempting to optimize this code or modify any repository calls, please see here:
45
    // https://github.com/ucsb-cs156/ucsb-cs156.github.io/blob/main/topics/spring_boot/spring_boot_entity_relationships.md
46
    Optional<Course> courseOpt = courseRepository.findById(course.getId());
47
    course = courseOpt.get();
48
    ctx.log("Processing...");
49
    List<CanvasGroup> groups = canvasService.getCanvasGroups(course, groupsetId);
50
    HashMap<String, RosterStudent> mappedStudents = new HashMap<>();
51
    HashMap<String, Team> teamsByName = new HashMap<>();
52
    HashMap<Integer, Team> teamsByCanvasId = new HashMap<>();
53 1 1. accept : removed call to java/util/List::forEach → KILLED
    course.getRosterStudents().forEach(student -> mappedStudents.put(student.getEmail(), student));
54
    course
55
        .getTeams()
56 1 1. accept : removed call to java/util/List::forEach → KILLED
        .forEach(
57
            team -> {
58
              teamsByName.put(team.getName(), team);
59 1 1. lambda$accept$1 : negated conditional → KILLED
              if (team.getCanvasId() != null) {
60
                teamsByCanvasId.put(team.getCanvasId(), team);
61
              }
62
            });
63
64
    List<Team> createdTeams = new ArrayList<>();
65
66
    for (CanvasGroup group : groups) {
67
      Team linked;
68 1 1. accept : negated conditional → KILLED
      if (teamsByCanvasId.containsKey(group.getId())) {
69
        linked = teamsByCanvasId.get(group.getId());
70 1 1. accept : negated conditional → KILLED
      } else if (teamsByName.containsKey(group.getName().trim())) {
71
        linked = teamsByName.get(group.getName().trim());
72
      } else {
73
        linked =
74
            Team.builder()
75
                .name(group.getName())
76
                .teamMembers(new ArrayList<>())
77
                .course(course)
78
                .build();
79
      }
80 2 1. accept : negated conditional → KILLED
2. accept : negated conditional → KILLED
      if (linked.getCanvasId() != null && !linked.getCanvasId().equals(group.getId())) {
81
        ctx.log("Duplicate group found: " + group.getName() + " with canvasId: " + group.getId());
82
        throw new DuplicateGroupException();
83
      }
84
85
      HashSet<String> processedEmails = new HashSet<>();
86
87 1 1. accept : removed call to edu/ucsb/cs156/frontiers/entities/Team::setCanvasId → KILLED
      linked.setCanvasId(group.getId());
88
      ctx.log("Processing group: " + group.getName() + " with canvasId: " + group.getId());
89
      Team finalLinked = linked;
90
      group
91
          .getMembers()
92 1 1. accept : removed call to java/util/List::forEach → KILLED
          .forEach(
93
              email -> {
94
                RosterStudent student =
95
                    mappedStudents.get(CanonicalFormConverter.convertToValidEmail(email));
96 1 1. lambda$accept$3 : negated conditional → KILLED
                if (student != null) {
97
                  processedEmails.add(student.getEmail());
98
                  if (student.getTeamMembers().stream()
99 3 1. lambda$accept$3 : negated conditional → KILLED
2. lambda$accept$2 : replaced boolean return with false for edu/ucsb/cs156/frontiers/jobs/PullTeamsFromCanvasJob::lambda$accept$2 → KILLED
3. lambda$accept$2 : replaced boolean return with true for edu/ucsb/cs156/frontiers/jobs/PullTeamsFromCanvasJob::lambda$accept$2 → KILLED
                      .anyMatch(teamMember -> teamMember.getTeam().equals(finalLinked))) {
100
                    return;
101
                  } else {
102
                    finalLinked
103
                        .getTeamMembers()
104
                        .add(TeamMember.builder().team(finalLinked).rosterStudent(student).build());
105
                  }
106
                }
107
              });
108
      createdTeams.add(finalLinked);
109
      Set<TeamMember> removedMembers =
110
          finalLinked.getTeamMembers().stream()
111
              .filter(
112 2 1. lambda$accept$4 : replaced boolean return with true for edu/ucsb/cs156/frontiers/jobs/PullTeamsFromCanvasJob::lambda$accept$4 → KILLED
2. lambda$accept$4 : negated conditional → KILLED
                  teamMember -> !processedEmails.contains(teamMember.getRosterStudent().getEmail()))
113
              .collect(Collectors.toSet());
114
      ctx.log("Group members to be removed:" + removedMembers);
115 1 1. accept : removed call to java/util/Set::forEach → KILLED
      removedMembers.forEach(
116
          teamMember -> {
117
            teamMember.getTeam().getTeamMembers().remove(teamMember);
118
            teamMember.getRosterStudent().getTeamMembers().remove(teamMember);
119
          });
120 1 1. accept : removed call to edu/ucsb/cs156/frontiers/repositories/TeamMemberRepository::deleteAll → KILLED
      teamMemberRepository.deleteAll(removedMembers);
121
    }
122
    teamRepository.saveAll(createdTeams);
123
  }
124
}

Mutations

38

1.1
Location : getCourse
Killed by : edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests]/[method:test_getCourse_returnsCourse()]
replaced return value with null for edu/ucsb/cs156/frontiers/jobs/PullTeamsFromCanvasJob::getCourse → KILLED

53

1.1
Location : accept
Killed by : edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests]/[method:testAccept_SkipsMembersNotOnRoster()]
removed call to java/util/List::forEach → KILLED

56

1.1
Location : accept
Killed by : edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests]/[method:testAccept_ThrowsDuplicateGroupException()]
removed call to java/util/List::forEach → KILLED

59

1.1
Location : lambda$accept$1
Killed by : edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests]/[method:testAccept_LinksExistingTeamByCanvasId()]
negated conditional → KILLED

68

1.1
Location : accept
Killed by : edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests]/[method:testAccept_ThrowsDuplicateGroupException()]
negated conditional → KILLED

70

1.1
Location : accept
Killed by : edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests]/[method:testAccept_ThrowsDuplicateGroupException()]
negated conditional → KILLED

80

1.1
Location : accept
Killed by : edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests]/[method:testAccept_ThrowsDuplicateGroupException()]
negated conditional → KILLED

2.2
Location : accept
Killed by : edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests]/[method:testAccept_ThrowsDuplicateGroupException()]
negated conditional → KILLED

87

1.1
Location : accept
Killed by : edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests]/[method:testAccept_LinksTeamByNameWithTrimmedWhitespace()]
removed call to edu/ucsb/cs156/frontiers/entities/Team::setCanvasId → KILLED

92

1.1
Location : accept
Killed by : edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests]/[method:testAccept_SkipsMembersNotOnRoster()]
removed call to java/util/List::forEach → KILLED

96

1.1
Location : lambda$accept$3
Killed by : edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests]/[method:testAccept_SkipsMembersNotOnRoster()]
negated conditional → KILLED

99

1.1
Location : lambda$accept$3
Killed by : edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests]/[method:testAccept_SkipsMembersNotOnRoster()]
negated conditional → KILLED

2.2
Location : lambda$accept$2
Killed by : edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests]/[method:testAccept_SkipsExistingTeamMembers()]
replaced boolean return with false for edu/ucsb/cs156/frontiers/jobs/PullTeamsFromCanvasJob::lambda$accept$2 → KILLED

3.3
Location : lambda$accept$2
Killed by : edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests]/[method:testAccept_AddsNewMemberToExistingTeam()]
replaced boolean return with true for edu/ucsb/cs156/frontiers/jobs/PullTeamsFromCanvasJob::lambda$accept$2 → KILLED

112

1.1
Location : lambda$accept$4
Killed by : edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests]/[method:testAccept_SkipsMembersNotOnRoster()]
replaced boolean return with true for edu/ucsb/cs156/frontiers/jobs/PullTeamsFromCanvasJob::lambda$accept$4 → KILLED

2.2
Location : lambda$accept$4
Killed by : edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests]/[method:testAccept_SkipsMembersNotOnRoster()]
negated conditional → KILLED

115

1.1
Location : accept
Killed by : edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests]/[method:testAccept_LinksExistingTeamByName()]
removed call to java/util/Set::forEach → KILLED

120

1.1
Location : accept
Killed by : edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.PullTeamsFromCanvasJobTests]/[method:testAccept_LinksExistingTeamByName()]
removed call to edu/ucsb/cs156/frontiers/repositories/TeamMemberRepository::deleteAll → KILLED

Active mutators

Tests examined


Report generated by PIT 1.17.0