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

Mutations

31

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

38

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

66

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

67

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/Team::setGithubTeamId → KILLED

81

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

89

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

91

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

104

1.1
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

2.2
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

107

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

116

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

129

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