PushTeamsToGithubJob.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.enums.TeamStatus;
8
import edu.ucsb.cs156.frontiers.repositories.CourseRepository;
9
import edu.ucsb.cs156.frontiers.repositories.TeamMemberRepository;
10
import edu.ucsb.cs156.frontiers.repositories.TeamRepository;
11
import edu.ucsb.cs156.frontiers.services.GithubTeamService;
12
import edu.ucsb.cs156.frontiers.services.GithubTeamService.GithubTeamInfo;
13
import edu.ucsb.cs156.frontiers.services.jobs.JobContext;
14
import edu.ucsb.cs156.frontiers.services.jobs.JobContextConsumer;
15
import java.util.Objects;
16
import java.util.Optional;
17
import lombok.Builder;
18
19
@Builder
20
public class PushTeamsToGithubJob implements JobContextConsumer {
21
  Long courseId;
22
  CourseRepository courseRepository;
23
  TeamRepository teamRepository;
24
  TeamMemberRepository teamMemberRepository;
25
  GithubTeamService githubTeamService;
26
27
  @Override
28
  public Course getCourse() {
29
    Optional<Course> courseOpt = courseRepository.findById(courseId);
30 1 1. getCourse : replaced return value with null for edu/ucsb/cs156/frontiers/jobs/PushTeamsToGithubJob::getCourse → KILLED
    return courseOpt.orElse(null);
31
  }
32
33
  @Override
34
  public void accept(JobContext ctx) throws Exception {
35
    ctx.log("Starting push teams to GitHub job for course ID: " + courseId);
36
37
    // Get the course
38
    Optional<Course> courseOpt = courseRepository.findById(courseId);
39 1 1. accept : negated conditional → KILLED
    if (courseOpt.isEmpty()) {
40
      ctx.log("ERROR: Course with ID " + courseId + " not found");
41
      return;
42
    }
43
    Course course = courseOpt.get();
44
    ctx.log("Processing course: " + course.getCourseName() + " (org: " + course.getOrgName() + ")");
45
46 2 1. accept : negated conditional → KILLED
2. accept : negated conditional → KILLED
    if (course.getOrgName() == null || course.getInstallationId() == null) {
47
      ctx.log("ERROR: Course has no linked GitHub organization");
48
      return;
49
    }
50
51
    // Get the organization id
52
53
    Integer orgId = null;
54
    try {
55
      orgId = githubTeamService.getOrgId(course.getOrgName(), course);
56
57
    } catch (Exception e) {
58
      ctx.log(
59
          "ERROR: Failed to get organization ID for org: "
60
              + course.getOrgName()
61
              + " - "
62
              + e.getMessage());
63
      return;
64
    }
65
66
    // Get all teams for this course
67
    Iterable<Team> teams = teamRepository.findByCourseId(courseId);
68
69
    // First pass: Create teams on GitHub and update githubTeamId
70
    for (Team team : teams) {
71
      ctx.log("Processing team: " + team.getName());
72
      try {
73
        GithubTeamInfo githubTeamInfo = githubTeamService.createOrGetTeamInfo(team, course);
74 1 1. accept : negated conditional → KILLED
        if (!githubTeamInfo.id().equals(team.getGithubTeamId())
75 1 1. accept : negated conditional → KILLED
            || !Objects.equals(githubTeamInfo.slug(), team.getGithubTeamSlug())) {
76 1 1. accept : removed call to edu/ucsb/cs156/frontiers/entities/Team::setGithubTeamId → KILLED
          team.setGithubTeamId(githubTeamInfo.id());
77 1 1. accept : removed call to edu/ucsb/cs156/frontiers/entities/Team::setGithubTeamSlug → KILLED
          team.setGithubTeamSlug(githubTeamInfo.slug());
78
          teamRepository.save(team);
79
          ctx.log(
80
              "Updated team '" + team.getName() + "' with GitHub team ID: " + githubTeamInfo.id());
81
        } else {
82
          ctx.log(
83
              "Team '"
84
                  + team.getName()
85
                  + "' already has correct GitHub team ID: "
86
                  + githubTeamInfo.id());
87
        }
88
      } catch (Exception e) {
89
        ctx.log("ERROR: Failed to create/get team '" + team.getName() + "': " + e.getMessage());
90
      }
91
    }
92
93
    // Second pass: Process team members
94
    for (Team team : teams) {
95 1 1. accept : negated conditional → KILLED
      if (team.getGithubTeamId() == null) {
96
        ctx.log("Skipping team members for '" + team.getName() + "' - no GitHub team ID");
97
        continue;
98
      }
99
100
      ctx.log("Processing members for team: " + team.getName());
101
      for (TeamMember teamMember : team.getTeamMembers()) {
102
        RosterStudent student = teamMember.getRosterStudent();
103 1 1. accept : negated conditional → KILLED
        if (student.getGithubLogin() == null) {
104
          // Update status to NO_GITHUB_ID
105 1 1. accept : removed call to edu/ucsb/cs156/frontiers/entities/TeamMember::setTeamStatus → KILLED
          teamMember.setTeamStatus(TeamStatus.NO_GITHUB_ID);
106
          teamMemberRepository.save(teamMember);
107
          ctx.log(
108
              "Student " + student.getEmail() + " has no GitHub login - marked as NO_GITHUB_ID");
109
          continue;
110
        }
111
112
        try {
113
          // Check current status
114
          TeamStatus currentStatus =
115
              githubTeamService.getTeamMembershipStatus(
116
                  student.getGithubLogin(), team.getGithubTeamId(), course, orgId);
117
118 2 1. accept : negated conditional → KILLED
2. accept : negated conditional → KILLED
          if (currentStatus == TeamStatus.TEAM_MEMBER
119
              || currentStatus == TeamStatus.TEAM_MAINTAINER) {
120
            // Already a member, just update the status
121 1 1. accept : removed call to edu/ucsb/cs156/frontiers/entities/TeamMember::setTeamStatus → KILLED
            teamMember.setTeamStatus(currentStatus);
122
            teamMemberRepository.save(teamMember);
123
            ctx.log(
124
                "Student " + student.getGithubLogin() + " already has status: " + currentStatus);
125
          } else {
126
            // Add as member
127
            TeamStatus newStatus =
128
                githubTeamService.addMemberToGithubTeam(
129
                    student.getGithubLogin(), team.getGithubTeamId(), "member", course, orgId);
130 1 1. accept : removed call to edu/ucsb/cs156/frontiers/entities/TeamMember::setTeamStatus → KILLED
            teamMember.setTeamStatus(newStatus);
131
            teamMemberRepository.save(teamMember);
132
            ctx.log(
133
                "Added student " + student.getGithubLogin() + " to team with status: " + newStatus);
134
          }
135
        } catch (Exception e) {
136
          ctx.log(
137
              "ERROR: Failed to process team member "
138
                  + student.getGithubLogin()
139
                  + " for team '"
140
                  + team.getName()
141
                  + "': "
142
                  + e.getMessage());
143 1 1. accept : removed call to edu/ucsb/cs156/frontiers/entities/TeamMember::setTeamStatus → KILLED
          teamMember.setTeamStatus(TeamStatus.NOT_ORG_MEMBER);
144
          teamMemberRepository.save(teamMember);
145
        }
146
      }
147
    }
148
149
    ctx.log("Completed push teams to GitHub job for course ID: " + courseId);
150
  }
151
}

Mutations

30

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

39

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

46

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

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

74

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

75

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

76

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

77

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

95

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

103

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

105

1.1
Location : accept
Killed by : edu.ucsb.cs156.frontiers.jobs.PushTeamsToGithubJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.PushTeamsToGithubJobTests]/[method:testAccept_SuccessfulTeamCreationAndMemberProcessing()]
removed call to edu/ucsb/cs156/frontiers/entities/TeamMember::setTeamStatus → KILLED

118

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

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

121

1.1
Location : accept
Killed by : edu.ucsb.cs156.frontiers.jobs.PushTeamsToGithubJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.PushTeamsToGithubJobTests]/[method:testAccept_ExistingTeamMember()]
removed call to edu/ucsb/cs156/frontiers/entities/TeamMember::setTeamStatus → KILLED

130

1.1
Location : accept
Killed by : edu.ucsb.cs156.frontiers.jobs.PushTeamsToGithubJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.PushTeamsToGithubJobTests]/[method:testAccept_SuccessfulTeamCreationAndMemberProcessing()]
removed call to edu/ucsb/cs156/frontiers/entities/TeamMember::setTeamStatus → KILLED

143

1.1
Location : accept
Killed by : edu.ucsb.cs156.frontiers.jobs.PushTeamsToGithubJobTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.jobs.PushTeamsToGithubJobTests]/[method:testAccept_TeamMemberProcessingFailure()]
removed call to edu/ucsb/cs156/frontiers/entities/TeamMember::setTeamStatus → KILLED

Active mutators

Tests examined


Report generated by PIT 1.17.0