ProjectsController.java

1
package edu.ucsb.cs.citelines.controller;
2
3
import edu.ucsb.cs.citelines.entity.Project;
4
import edu.ucsb.cs.citelines.entity.ProjectCollaborator;
5
import edu.ucsb.cs.citelines.errors.EntityNotFoundException;
6
import edu.ucsb.cs.citelines.model.CurrentUser;
7
import edu.ucsb.cs.citelines.repository.ProjectCollaboratorRepository;
8
import edu.ucsb.cs.citelines.repository.ProjectRepository;
9
import io.swagger.v3.oas.annotations.Operation;
10
import io.swagger.v3.oas.annotations.Parameter;
11
import io.swagger.v3.oas.annotations.tags.Tag;
12
import java.time.LocalDateTime;
13
import java.util.List;
14
import lombok.extern.slf4j.Slf4j;
15
import org.springframework.beans.factory.annotation.Autowired;
16
import org.springframework.security.access.prepost.PreAuthorize;
17
import org.springframework.transaction.annotation.Transactional;
18
import org.springframework.web.bind.annotation.DeleteMapping;
19
import org.springframework.web.bind.annotation.GetMapping;
20
import org.springframework.web.bind.annotation.PathVariable;
21
import org.springframework.web.bind.annotation.PostMapping;
22
import org.springframework.web.bind.annotation.PutMapping;
23
import org.springframework.web.bind.annotation.RequestMapping;
24
import org.springframework.web.bind.annotation.RequestParam;
25
import org.springframework.web.bind.annotation.RestController;
26
27
@Tag(name = "Projects")
28
@RequestMapping("/api/projects")
29
@RestController
30
@Slf4j
31
public class ProjectsController extends ApiController {
32
33
  @Autowired private ProjectRepository projectRepository;
34
35
  @Autowired private ProjectCollaboratorRepository projectCollaboratorRepository;
36
37
  /**
38
   * This method creates a new Project, owned by the current user.
39
   *
40
   * @param name the name of the project
41
   * @param description the description of the project
42
   * @return the created project
43
   */
44
  @Operation(summary = "Create a new project")
45
  @PreAuthorize("hasRole('ROLE_ADMIN') || hasRole('ROLE_RESEARCHER')")
46
  @PostMapping("/post")
47
  public Project postProject(
48
      @Parameter(name = "name") @RequestParam String name,
49
      @Parameter(name = "description") @RequestParam String description) {
50
    CurrentUser currentUser = getCurrentUser();
51
    Project project =
52
        Project.builder()
53
            .name(name)
54
            .description(description)
55
            .owner(currentUser.getUser().getEmail())
56
            .dateCreated(LocalDateTime.now())
57
            .build();
58 1 1. postProject : replaced return value with null for edu/ucsb/cs/citelines/controller/ProjectsController::postProject → KILLED
    return projectRepository.save(project);
59
  }
60
61
  /**
62
   * This method returns a list of projects owned by the current user.
63
   *
64
   * @return a list of projects owned by the current user.
65
   */
66
  @Operation(summary = "List all projects owned by the current user")
67
  @PreAuthorize("hasRole('ROLE_RESEARCHER')")
68
  @GetMapping("/list/owner")
69
  public Iterable<Project> listForOwner() {
70
    String email = getCurrentUser().getUser().getEmail();
71 1 1. listForOwner : replaced return value with Collections.emptyList for edu/ucsb/cs/citelines/controller/ProjectsController::listForOwner → KILLED
    return projectRepository.findByOwner(email);
72
  }
73
74
  /**
75
   * This method returns a list of projects the current user collaborates on.
76
   *
77
   * @return a list of projects the current user collaborates on.
78
   */
79
  @Operation(summary = "List all projects the current user collaborates on")
80
  @PreAuthorize("hasRole('ROLE_USER')")
81
  @GetMapping("/list/collaborator")
82
  public List<Project> listForCollaborator() {
83
    String email = getCurrentUser().getUser().getEmail();
84 1 1. listForCollaborator : replaced return value with Collections.emptyList for edu/ucsb/cs/citelines/controller/ProjectsController::listForCollaborator → KILLED
    return projectCollaboratorRepository.findAllByEmail(email).stream()
85
        .map(ProjectCollaborator::getProject)
86
        .distinct()
87
        .toList();
88
  }
89
90
  /**
91
   * This method returns a single project by its id.
92
   *
93
   * @return a project
94
   */
95
  @Operation(summary = "Get project by id")
96
  @PreAuthorize("@ProjectSecurity.hasManagePermissions(#root, #id)")
97
  @GetMapping("/{id}")
98
  public Project getProjectById(@Parameter(name = "id") @PathVariable Long id) {
99 1 1. getProjectById : replaced return value with null for edu/ucsb/cs/citelines/controller/ProjectsController::getProjectById → KILLED
    return projectRepository
100
        .findById(id)
101 1 1. lambda$getProjectById$0 : replaced return value with null for edu/ucsb/cs/citelines/controller/ProjectsController::lambda$getProjectById$0 → KILLED
        .orElseThrow(() -> new EntityNotFoundException(Project.class, id));
102
  }
103
104
  /**
105
   * This method updates the name and description of an existing project.
106
   *
107
   * @param projectId the id of the project to update
108
   * @param name the new name of the project
109
   * @param description the new description of the project
110
   * @return the updated project
111
   */
112
  @Operation(summary = "Update an existing project")
113
  @PreAuthorize("@ProjectSecurity.hasOwnerPermissions(#root, #projectId)")
114
  @PutMapping("")
115
  public Project updateProject(
116
      @Parameter(name = "projectId") @RequestParam Long projectId,
117
      @Parameter(name = "name") @RequestParam String name,
118
      @Parameter(name = "description") @RequestParam String description) {
119
    Project project =
120
        projectRepository
121
            .findById(projectId)
122 1 1. lambda$updateProject$1 : replaced return value with null for edu/ucsb/cs/citelines/controller/ProjectsController::lambda$updateProject$1 → KILLED
            .orElseThrow(() -> new EntityNotFoundException(Project.class, projectId));
123
124 1 1. updateProject : removed call to edu/ucsb/cs/citelines/entity/Project::setName → KILLED
    project.setName(name);
125 1 1. updateProject : removed call to edu/ucsb/cs/citelines/entity/Project::setDescription → KILLED
    project.setDescription(description);
126
127 1 1. updateProject : replaced return value with null for edu/ucsb/cs/citelines/controller/ProjectsController::updateProject → KILLED
    return projectRepository.save(project);
128
  }
129
130
  /**
131
   * This method deletes a project, along with any collaborators on it.
132
   *
133
   * @param projectId the id of the project to delete
134
   * @return a message confirming deletion
135
   */
136
  @Operation(summary = "Delete a project")
137
  @PreAuthorize("@ProjectSecurity.hasOwnerPermissions(#root, #projectId)")
138
  @DeleteMapping("")
139
  @Transactional
140
  public Object deleteProject(@RequestParam Long projectId) {
141
    Project project =
142
        projectRepository
143
            .findById(projectId)
144 1 1. lambda$deleteProject$2 : replaced return value with null for edu/ucsb/cs/citelines/controller/ProjectsController::lambda$deleteProject$2 → KILLED
            .orElseThrow(() -> new EntityNotFoundException(Project.class, projectId));
145
146 1 1. deleteProject : removed call to edu/ucsb/cs/citelines/repository/ProjectCollaboratorRepository::deleteAll → KILLED
    projectCollaboratorRepository.deleteAll(
147
        projectCollaboratorRepository.findByProjectId(projectId));
148 1 1. deleteProject : removed call to edu/ucsb/cs/citelines/repository/ProjectRepository::delete → KILLED
    projectRepository.delete(project);
149
150 1 1. deleteProject : replaced return value with null for edu/ucsb/cs/citelines/controller/ProjectsController::deleteProject → KILLED
    return genericMessage("Project with id %s deleted".formatted(project.getId()));
151
  }
152
}

Mutations

58

1.1
Location : postProject
Killed by : edu.ucsb.cs.citelines.controller.ProjectsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.citelines.controller.ProjectsControllerTests]/[method:a_researcher_can_post_a_new_project()]
replaced return value with null for edu/ucsb/cs/citelines/controller/ProjectsController::postProject → KILLED

71

1.1
Location : listForOwner
Killed by : edu.ucsb.cs.citelines.controller.ProjectsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.citelines.controller.ProjectsControllerTests]/[method:a_researcher_can_list_their_own_projects()]
replaced return value with Collections.emptyList for edu/ucsb/cs/citelines/controller/ProjectsController::listForOwner → KILLED

84

1.1
Location : listForCollaborator
Killed by : edu.ucsb.cs.citelines.controller.ProjectsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.citelines.controller.ProjectsControllerTests]/[method:a_user_can_list_projects_they_collaborate_on()]
replaced return value with Collections.emptyList for edu/ucsb/cs/citelines/controller/ProjectsController::listForCollaborator → KILLED

99

1.1
Location : getProjectById
Killed by : edu.ucsb.cs.citelines.controller.ProjectsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.citelines.controller.ProjectsControllerTests]/[method:owner_can_get_project_by_id()]
replaced return value with null for edu/ucsb/cs/citelines/controller/ProjectsController::getProjectById → KILLED

101

1.1
Location : lambda$getProjectById$0
Killed by : edu.ucsb.cs.citelines.controller.ProjectsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.citelines.controller.ProjectsControllerTests]/[method:get_by_id_throws_not_found_for_nonexistent_project()]
replaced return value with null for edu/ucsb/cs/citelines/controller/ProjectsController::lambda$getProjectById$0 → KILLED

122

1.1
Location : lambda$updateProject$1
Killed by : edu.ucsb.cs.citelines.controller.ProjectsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.citelines.controller.ProjectsControllerTests]/[method:update_throws_not_found_for_nonexistent_project()]
replaced return value with null for edu/ucsb/cs/citelines/controller/ProjectsController::lambda$updateProject$1 → KILLED

124

1.1
Location : updateProject
Killed by : edu.ucsb.cs.citelines.controller.ProjectsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.citelines.controller.ProjectsControllerTests]/[method:owner_can_update_a_project()]
removed call to edu/ucsb/cs/citelines/entity/Project::setName → KILLED

125

1.1
Location : updateProject
Killed by : edu.ucsb.cs.citelines.controller.ProjectsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.citelines.controller.ProjectsControllerTests]/[method:owner_can_update_a_project()]
removed call to edu/ucsb/cs/citelines/entity/Project::setDescription → KILLED

127

1.1
Location : updateProject
Killed by : edu.ucsb.cs.citelines.controller.ProjectsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.citelines.controller.ProjectsControllerTests]/[method:owner_can_update_a_project()]
replaced return value with null for edu/ucsb/cs/citelines/controller/ProjectsController::updateProject → KILLED

144

1.1
Location : lambda$deleteProject$2
Killed by : edu.ucsb.cs.citelines.controller.ProjectsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.citelines.controller.ProjectsControllerTests]/[method:delete_throws_not_found_for_nonexistent_project()]
replaced return value with null for edu/ucsb/cs/citelines/controller/ProjectsController::lambda$deleteProject$2 → KILLED

146

1.1
Location : deleteProject
Killed by : edu.ucsb.cs.citelines.controller.ProjectsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.citelines.controller.ProjectsControllerTests]/[method:owner_can_delete_a_project_and_its_collaborators()]
removed call to edu/ucsb/cs/citelines/repository/ProjectCollaboratorRepository::deleteAll → KILLED

148

1.1
Location : deleteProject
Killed by : edu.ucsb.cs.citelines.controller.ProjectsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.citelines.controller.ProjectsControllerTests]/[method:owner_can_delete_a_project_and_its_collaborators()]
removed call to edu/ucsb/cs/citelines/repository/ProjectRepository::delete → KILLED

150

1.1
Location : deleteProject
Killed by : edu.ucsb.cs.citelines.controller.ProjectsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.citelines.controller.ProjectsControllerTests]/[method:owner_can_delete_a_project_and_its_collaborators()]
replaced return value with null for edu/ucsb/cs/citelines/controller/ProjectsController::deleteProject → KILLED

Active mutators

Tests examined


Report generated by PIT 1.17.0