RepositoryController.java

1
package edu.ucsb.cs156.frontiers.controllers;
2
3
import edu.ucsb.cs156.frontiers.entities.Course;
4
import edu.ucsb.cs156.frontiers.entities.Job;
5
import edu.ucsb.cs156.frontiers.enums.RepositoryCreationOption;
6
import edu.ucsb.cs156.frontiers.enums.RepositoryPermissions;
7
import edu.ucsb.cs156.frontiers.errors.EntityNotFoundException;
8
import edu.ucsb.cs156.frontiers.errors.NoLinkedOrganizationException;
9
import edu.ucsb.cs156.frontiers.jobs.CreateStudentOrStaffRepositoriesJob;
10
import edu.ucsb.cs156.frontiers.jobs.CreateTeamRepositoriesJob;
11
import edu.ucsb.cs156.frontiers.jobs.DeleteRepoJob;
12
import edu.ucsb.cs156.frontiers.repositories.CourseRepository;
13
import edu.ucsb.cs156.frontiers.services.GithubTeamService;
14
import edu.ucsb.cs156.frontiers.services.RepositoryService;
15
import edu.ucsb.cs156.frontiers.services.jobs.JobService;
16
import io.swagger.v3.oas.annotations.Operation;
17
import io.swagger.v3.oas.annotations.Parameter;
18
import io.swagger.v3.oas.annotations.tags.Tag;
19
import java.util.Optional;
20
import org.springframework.beans.factory.annotation.Autowired;
21
import org.springframework.security.access.prepost.PreAuthorize;
22
import org.springframework.web.bind.annotation.DeleteMapping;
23
import org.springframework.web.bind.annotation.PostMapping;
24
import org.springframework.web.bind.annotation.RequestMapping;
25
import org.springframework.web.bind.annotation.RequestParam;
26
import org.springframework.web.bind.annotation.RestController;
27
28
@Tag(name = "Repository Controller")
29
@RestController
30
@RequestMapping("/api/repos")
31
public class RepositoryController extends ApiController {
32
33
  @Autowired RepositoryService repositoryService;
34
35
  @Autowired JobService jobService;
36
37
  @Autowired CourseRepository courseRepository;
38
39
  @Autowired GithubTeamService githubTeamService;
40
41
  /**
42
   * Fires a job that creates a repo for every RosterStudent with a linked user with a GitHub
43
   * account.
44
   *
45
   * @param courseId ID of course to create repos for
46
   * @param repoPrefix each repo created will begin with this prefix, followed by a dash and the
47
   *     student's GitHub username
48
   * @param isPrivate determines whether the repository being created is private
49
   * @return the {@link edu.ucsb.cs156.frontiers.entities.Job Job} started to create the repos.
50
   */
51
  @PostMapping("/createRepos")
52
  @PreAuthorize("@CourseSecurity.hasManagePermissions(#root, #courseId)")
53
  public Job createRepos(
54
      @RequestParam Long courseId,
55
      @RequestParam String repoPrefix,
56
      @RequestParam Optional<Boolean> isPrivate,
57
      @RequestParam RepositoryPermissions permissions,
58
      @RequestParam(required = false, defaultValue = "STUDENTS_ONLY")
59
          RepositoryCreationOption creationOption) {
60
    Course course =
61
        courseRepository
62
            .findById(courseId)
63 1 1. lambda$createRepos$0 : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RepositoryController::lambda$createRepos$0 → KILLED
            .orElseThrow(() -> new EntityNotFoundException(Course.class, courseId));
64 2 1. createRepos : negated conditional → KILLED
2. createRepos : negated conditional → KILLED
    if (course.getOrgName() == null || course.getInstallationId() == null) {
65
      throw new NoLinkedOrganizationException(course.getCourseName());
66
    } else {
67
      CreateStudentOrStaffRepositoriesJob job =
68
          CreateStudentOrStaffRepositoriesJob.builder()
69
              .repositoryPrefix(repoPrefix)
70
              .isPrivate(isPrivate.orElse(false))
71
              .repositoryService(repositoryService)
72
              .course(course)
73
              .permissions(permissions)
74
              .creationOption(creationOption)
75
              .build();
76 1 1. createRepos : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RepositoryController::createRepos → KILLED
      return jobService.runAsJob(job);
77
    }
78
  }
79
80
  /**
81
   * Fires a job that creates team repos shared by all TeamMembers of each Team in a Course .
82
   *
83
   * @param courseId ID of course to create team repos for
84
   * @param repoPrefix each team repo created will begin with this prefix, followed by a dash and
85
   *     the team's name
86
   * @param isPrivate determines whether the repository being created is private
87
   * @param teamRegex optional regular expression that will only create repos for team names that
88
   *     match this expression if omitted, repos will be created for every team
89
   * @return the {@link edu.ucsb.cs156.frontiers.entities.Job Job} started to create the repos.
90
   */
91
  @PostMapping("/createTeamRepos")
92
  @PreAuthorize("@CourseSecurity.hasManagePermissions(#root, #courseId)")
93
  public Job createTeamRepos(
94
      @RequestParam Long courseId,
95
      @RequestParam String repoPrefix,
96
      @RequestParam Optional<Boolean> isPrivate,
97
      @RequestParam RepositoryPermissions permissions,
98
      @RequestParam(required = false) String teamRegex) {
99
    Course course =
100
        courseRepository
101
            .findById(courseId)
102 1 1. lambda$createTeamRepos$1 : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RepositoryController::lambda$createTeamRepos$1 → KILLED
            .orElseThrow(() -> new EntityNotFoundException(Course.class, courseId));
103 2 1. createTeamRepos : negated conditional → KILLED
2. createTeamRepos : negated conditional → KILLED
    if (course.getOrgName() == null || course.getInstallationId() == null) {
104
      throw new NoLinkedOrganizationException(course.getCourseName());
105
    } else {
106
      CreateTeamRepositoriesJob job =
107
          CreateTeamRepositoriesJob.builder()
108
              .repositoryPrefix(repoPrefix)
109
              .isPrivate(isPrivate.orElse(false))
110
              .repositoryService(repositoryService)
111
              .githubTeamService(githubTeamService)
112
              .course(course)
113
              .permissions(permissions)
114
              .teamRegex(teamRegex)
115
              .build();
116 1 1. createTeamRepos : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RepositoryController::createTeamRepos → KILLED
      return jobService.runAsJob(job);
117
    }
118
  }
119
120
  @Operation(summary = "Delete empty repos matching a prefix for a specific course")
121
  @PreAuthorize("@CourseSecurity.hasManagePermissions(#root, #courseId)")
122
  @DeleteMapping("") // Maps to /api/repos
123
  public Job launchDeleteRepoJob(
124
      @Parameter(name = "courseId") @RequestParam Long courseId,
125
      @Parameter(name = "prefix") @RequestParam String prefix) {
126
127
    Course course =
128
        courseRepository
129
            .findById(courseId)
130 1 1. lambda$launchDeleteRepoJob$2 : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RepositoryController::lambda$launchDeleteRepoJob$2 → KILLED
            .orElseThrow(() -> new EntityNotFoundException(Course.class, courseId));
131
132 2 1. launchDeleteRepoJob : negated conditional → KILLED
2. launchDeleteRepoJob : negated conditional → KILLED
    if (course.getOrgName() == null || course.getInstallationId() == null) {
133
      throw new NoLinkedOrganizationException(course.getCourseName());
134
    }
135
136
    DeleteRepoJob job =
137
        DeleteRepoJob.builder()
138
            .course(course)
139
            .prefix(prefix)
140
            .repositoryService(repositoryService)
141
            .build();
142
143 1 1. launchDeleteRepoJob : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RepositoryController::launchDeleteRepoJob → KILLED
    return jobService.runAsJob(job);
144
  }
145
}

Mutations

63

1.1
Location : lambda$createRepos$0
Killed by : edu.ucsb.cs156.frontiers.controllers.RepositoryControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RepositoryControllerTests]/[method:notFound()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RepositoryController::lambda$createRepos$0 → KILLED

64

1.1
Location : createRepos
Killed by : edu.ucsb.cs156.frontiers.controllers.RepositoryControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RepositoryControllerTests]/[method:job_actually_fires()]
negated conditional → KILLED

2.2
Location : createRepos
Killed by : edu.ucsb.cs156.frontiers.controllers.RepositoryControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RepositoryControllerTests]/[method:just_no_install_id()]
negated conditional → KILLED

76

1.1
Location : createRepos
Killed by : edu.ucsb.cs156.frontiers.controllers.RepositoryControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RepositoryControllerTests]/[method:job_actually_fires()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RepositoryController::createRepos → KILLED

102

1.1
Location : lambda$createTeamRepos$1
Killed by : edu.ucsb.cs156.frontiers.controllers.RepositoryControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RepositoryControllerTests]/[method:team_repo_job_notFound()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RepositoryController::lambda$createTeamRepos$1 → KILLED

103

1.1
Location : createTeamRepos
Killed by : edu.ucsb.cs156.frontiers.controllers.RepositoryControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RepositoryControllerTests]/[method:team_repo_job_actually_fires_with_teamRegex()]
negated conditional → KILLED

2.2
Location : createTeamRepos
Killed by : edu.ucsb.cs156.frontiers.controllers.RepositoryControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RepositoryControllerTests]/[method:team_repo_job_just_no_install_id()]
negated conditional → KILLED

116

1.1
Location : createTeamRepos
Killed by : edu.ucsb.cs156.frontiers.controllers.RepositoryControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RepositoryControllerTests]/[method:team_repo_job_actually_fires_with_teamRegex()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RepositoryController::createTeamRepos → KILLED

130

1.1
Location : lambda$launchDeleteRepoJob$2
Killed by : edu.ucsb.cs156.frontiers.controllers.RepositoryControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RepositoryControllerTests]/[method:delete_repo_job_notFound()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RepositoryController::lambda$launchDeleteRepoJob$2 → KILLED

132

1.1
Location : launchDeleteRepoJob
Killed by : edu.ucsb.cs156.frontiers.controllers.RepositoryControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RepositoryControllerTests]/[method:delete_repo_job_actually_fires()]
negated conditional → KILLED

2.2
Location : launchDeleteRepoJob
Killed by : edu.ucsb.cs156.frontiers.controllers.RepositoryControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RepositoryControllerTests]/[method:delete_repo_job_just_no_install_id()]
negated conditional → KILLED

143

1.1
Location : launchDeleteRepoJob
Killed by : edu.ucsb.cs156.frontiers.controllers.RepositoryControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.RepositoryControllerTests]/[method:delete_repo_job_actually_fires()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/RepositoryController::launchDeleteRepoJob → KILLED

Active mutators

Tests examined


Report generated by PIT 1.17.0