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
  @Transactional
38
  public void accept(JobContext ctx) throws Exception {
39
    // Prior to attempting to optimize this code or modify any repository calls, please see here:
40
    // https://github.com/ucsb-cs156/ucsb-cs156.github.io/blob/main/topics/spring_boot/spring_boot_entity_relationships.md
41
    Optional<Course> courseOpt = courseRepository.findById(course.getId());
42
    course = courseOpt.get();
43
    ctx.log("Processing...");
44
    List<CanvasGroup> groups = canvasService.getCanvasGroups(course, groupsetId);
45
    HashMap<String, RosterStudent> mappedStudents = new HashMap<>();
46
    HashMap<String, Team> teamsByName = new HashMap<>();
47
    HashMap<Integer, Team> teamsByCanvasId = new HashMap<>();
48 1 1. accept : removed call to java/util/List::forEach → KILLED
    course.getRosterStudents().forEach(student -> mappedStudents.put(student.getEmail(), student));
49
    course
50
        .getTeams()
51 1 1. accept : removed call to java/util/List::forEach → KILLED
        .forEach(
52
            team -> {
53
              teamsByName.put(team.getName(), team);
54 1 1. lambda$accept$1 : negated conditional → KILLED
              if (team.getCanvasId() != null) {
55
                teamsByCanvasId.put(team.getCanvasId(), team);
56
              }
57
            });
58
59
    List<Team> createdTeams = new ArrayList<>();
60
61
    for (CanvasGroup group : groups) {
62
      Team linked;
63 1 1. accept : negated conditional → KILLED
      if (teamsByCanvasId.containsKey(group.getId())) {
64
        linked = teamsByCanvasId.get(group.getId());
65 1 1. accept : negated conditional → KILLED
      } else if (teamsByName.containsKey(group.getName().trim())) {
66
        linked = teamsByName.get(group.getName().trim());
67
      } else {
68
        linked =
69
            Team.builder()
70
                .name(group.getName())
71
                .teamMembers(new ArrayList<>())
72
                .course(course)
73
                .build();
74
      }
75 2 1. accept : negated conditional → KILLED
2. accept : negated conditional → KILLED
      if (linked.getCanvasId() != null && !linked.getCanvasId().equals(group.getId())) {
76
        ctx.log("Duplicate group found: " + group.getName() + " with canvasId: " + group.getId());
77
        throw new DuplicateGroupException();
78
      }
79
80
      HashSet<String> processedEmails = new HashSet<>();
81
82 1 1. accept : removed call to edu/ucsb/cs156/frontiers/entities/Team::setCanvasId → KILLED
      linked.setCanvasId(group.getId());
83
      ctx.log("Processing group: " + group.getName() + " with canvasId: " + group.getId());
84
      Team finalLinked = linked;
85
      group
86
          .getMembers()
87 1 1. accept : removed call to java/util/List::forEach → KILLED
          .forEach(
88
              email -> {
89
                RosterStudent student =
90
                    mappedStudents.get(CanonicalFormConverter.convertToValidEmail(email));
91 1 1. lambda$accept$3 : negated conditional → KILLED
                if (student != null) {
92
                  processedEmails.add(student.getEmail());
93
                  if (student.getTeamMembers().stream()
94 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))) {
95
                    return;
96
                  } else {
97
                    finalLinked
98
                        .getTeamMembers()
99
                        .add(TeamMember.builder().team(finalLinked).rosterStudent(student).build());
100
                  }
101
                }
102
              });
103
      createdTeams.add(finalLinked);
104
      Set<TeamMember> removedMembers =
105
          finalLinked.getTeamMembers().stream()
106
              .filter(
107 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()))
108
              .collect(Collectors.toSet());
109
      ctx.log("Group members to be removed:" + removedMembers);
110 1 1. accept : removed call to java/util/Set::forEach → KILLED
      removedMembers.forEach(
111
          teamMember -> {
112
            teamMember.getTeam().getTeamMembers().remove(teamMember);
113
            teamMember.getRosterStudent().getTeamMembers().remove(teamMember);
114
          });
115 1 1. accept : removed call to edu/ucsb/cs156/frontiers/repositories/TeamMemberRepository::deleteAll → KILLED
      teamMemberRepository.deleteAll(removedMembers);
116
    }
117
    teamRepository.saveAll(createdTeams);
118
  }
119
}

Mutations

48

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

51

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

54

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

63

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

65

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

75

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

82

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

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_LinksExistingTeamByCanvasId()]
removed call to java/util/List::forEach → KILLED

91

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_LinksExistingTeamByCanvasId()]
negated conditional → KILLED

94

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_LinksExistingTeamByCanvasId()]
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

107

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_LinksExistingTeamByCanvasId()]
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_LinksExistingTeamByCanvasId()]
negated conditional → KILLED

110

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

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 edu/ucsb/cs156/frontiers/repositories/TeamMemberRepository::deleteAll → KILLED

Active mutators

Tests examined


Report generated by PIT 1.17.0