UsersController.java

1
package edu.ucsb.cs156.rec.controllers;
2
3
import com.fasterxml.jackson.core.JsonProcessingException;
4
import com.fasterxml.jackson.databind.ObjectMapper;
5
import edu.ucsb.cs156.rec.entities.User;
6
import edu.ucsb.cs156.rec.errors.EntityNotFoundException;
7
import edu.ucsb.cs156.rec.repositories.UserRepository;
8
import io.swagger.v3.oas.annotations.Operation;
9
import io.swagger.v3.oas.annotations.Parameter;
10
import io.swagger.v3.oas.annotations.tags.Tag;
11
import java.util.ArrayList;
12
import java.util.HashMap;
13
import java.util.List;
14
import java.util.Map;
15
import org.springframework.beans.factory.annotation.Autowired;
16
import org.springframework.http.ResponseEntity;
17
import org.springframework.security.access.prepost.PreAuthorize;
18
import org.springframework.web.bind.annotation.DeleteMapping;
19
import org.springframework.web.bind.annotation.GetMapping;
20
import org.springframework.web.bind.annotation.PostMapping;
21
import org.springframework.web.bind.annotation.RequestMapping;
22
import org.springframework.web.bind.annotation.RequestParam;
23
import org.springframework.web.bind.annotation.RestController;
24
25
/**
26
 * This is a REST controller for getting information about the users.
27
 *
28
 * <p>These endpoints are only accessible to users with the role "ROLE_ADMIN".
29
 */
30
@Tag(name = "User information (admin only except for /professors)")
31
@RequestMapping("/api/admin/users")
32
@RestController
33
public class UsersController extends ApiController {
34
  @Autowired UserRepository userRepository;
35
36
  @Autowired ObjectMapper mapper;
37
38
  /**
39
   * This method returns a list of all users. Accessible only to users with the role "ROLE_ADMIN".
40
   *
41
   * @return a list of all users
42
   * @throws JsonProcessingException if there is an error processing the JSON
43
   */
44
  @Operation(summary = "Get a list of all users")
45
  @PreAuthorize("hasRole('ROLE_ADMIN')")
46
  @GetMapping("")
47
  public ResponseEntity<String> users() throws JsonProcessingException {
48
    Iterable<User> users = userRepository.findAll();
49
    String body = mapper.writeValueAsString(users);
50 1 1. users : replaced return value with null for edu/ucsb/cs156/rec/controllers/UsersController::users → KILLED
    return ResponseEntity.ok().body(body);
51
  }
52
53
  /**
54
   * This method returns a list of all Recommendation Requests requested by current student.
55
   *
56
   * @return a list of all Recommendation Requests requested by the current user
57
   */
58
  @Operation(summary = "List all professors")
59
  @PreAuthorize("hasRole('ROLE_USER')")
60
  @GetMapping("/professors")
61
  public Iterable<Map<String, Object>> allProfessors() {
62
    Iterable<User> professors = userRepository.professorIsTrue();
63
    // to add privacy, only return professor_id and professor_name
64
    List<Map<String, Object>> limited_list = new ArrayList<>();
65
    for (User professor : professors) {
66
      Map<String, Object> map = new HashMap<>();
67
      map.put("id", professor.getId());
68
      map.put("fullName", professor.getFullName());
69
      limited_list.add(map);
70
    }
71 1 1. allProfessors : replaced return value with Collections.emptyList for edu/ucsb/cs156/rec/controllers/UsersController::allProfessors → KILLED
    return limited_list;
72
  }
73
74
  @Operation(summary = "Get user by id")
75
  @PreAuthorize("hasRole('ROLE_ADMIN')")
76
  @GetMapping("/get")
77
  public User users(
78
      @Parameter(
79
              name = "id",
80
              description = "Long, id number of user to get",
81
              example = "1",
82
              required = true)
83
          @RequestParam
84
          Long id)
85
      throws JsonProcessingException {
86
    User user =
87 1 1. lambda$users$0 : replaced return value with null for edu/ucsb/cs156/rec/controllers/UsersController::lambda$users$0 → KILLED
        userRepository.findById(id).orElseThrow(() -> new EntityNotFoundException(User.class, id));
88
89 1 1. users : replaced return value with null for edu/ucsb/cs156/rec/controllers/UsersController::users → KILLED
    return user;
90
  }
91
92
  @Operation(summary = "Delete a user (admin)")
93
  @PreAuthorize("hasRole('ROLE_ADMIN')")
94
  @DeleteMapping("/delete")
95
  public Object deleteUser_Admin(
96
      @Parameter(
97
              name = "id",
98
              description = "Long, id number of user to delete",
99
              example = "1",
100
              required = true)
101
          @RequestParam
102
          Long id) {
103
    User user =
104 1 1. lambda$deleteUser_Admin$1 : replaced return value with null for edu/ucsb/cs156/rec/controllers/UsersController::lambda$deleteUser_Admin$1 → KILLED
        userRepository.findById(id).orElseThrow(() -> new EntityNotFoundException(User.class, id));
105 1 1. deleteUser_Admin : removed call to edu/ucsb/cs156/rec/repositories/UserRepository::delete → KILLED
    userRepository.delete(user);
106 1 1. deleteUser_Admin : replaced return value with null for edu/ucsb/cs156/rec/controllers/UsersController::deleteUser_Admin → KILLED
    return genericMessage("User with id %s has been deleted.".formatted(id));
107
  }
108
109
  @Operation(summary = "Toggle the admin field")
110
  @PreAuthorize("hasRole('ROLE_ADMIN')")
111
  @PostMapping("/toggleAdmin")
112
  public Object toggleAdmin(
113
      @Parameter(
114
              name = "id",
115
              description = "Long, id number of user to toggle their admin field",
116
              example = "1",
117
              required = true)
118
          @RequestParam
119
          Long id) {
120
    User user =
121 1 1. lambda$toggleAdmin$2 : replaced return value with null for edu/ucsb/cs156/rec/controllers/UsersController::lambda$toggleAdmin$2 → KILLED
        userRepository.findById(id).orElseThrow(() -> new EntityNotFoundException(User.class, id));
122
123
    // Get the current user
124
    User currentUser = getCurrentUser().getUser();
125
126
    // Check if the user is trying to remove admin from themselves
127 2 1. toggleAdmin : negated conditional → KILLED
2. toggleAdmin : negated conditional → KILLED
    if (user.getId() == currentUser.getId() && user.getAdmin()) {
128
      throw new IllegalArgumentException(
129
          "Cannot remove admin from currently logged in user; ask another admin to do that.");
130
    }
131
132 2 1. toggleAdmin : negated conditional → KILLED
2. toggleAdmin : removed call to edu/ucsb/cs156/rec/entities/User::setAdmin → KILLED
    user.setAdmin(!user.getAdmin());
133
    userRepository.save(user);
134 1 1. toggleAdmin : replaced return value with null for edu/ucsb/cs156/rec/controllers/UsersController::toggleAdmin → KILLED
    return genericMessage(
135
        "User with id %s has toggled admin status to %s".formatted(id, user.getAdmin()));
136
  }
137
138
  @Operation(summary = "Toggle the professor field")
139
  @PreAuthorize("hasRole('ROLE_ADMIN')")
140
  @PostMapping("/toggleProfessor")
141
  public Object toggleProfessor(
142
      @Parameter(
143
              name = "id",
144
              description = "Long, id number of user to toggle their professor field",
145
              example = "1",
146
              required = true)
147
          @RequestParam
148
          Long id) {
149
    User user =
150 1 1. lambda$toggleProfessor$3 : replaced return value with null for edu/ucsb/cs156/rec/controllers/UsersController::lambda$toggleProfessor$3 → KILLED
        userRepository.findById(id).orElseThrow(() -> new EntityNotFoundException(User.class, id));
151
152 2 1. toggleProfessor : negated conditional → KILLED
2. toggleProfessor : removed call to edu/ucsb/cs156/rec/entities/User::setProfessor → KILLED
    user.setProfessor(!user.getProfessor());
153
    userRepository.save(user);
154 1 1. toggleProfessor : replaced return value with null for edu/ucsb/cs156/rec/controllers/UsersController::toggleProfessor → KILLED
    return genericMessage(
155
        "User with id %s has toggled professor status to %s".formatted(id, user.getProfessor()));
156
  }
157
}

Mutations

50

1.1
Location : users
Killed by : edu.ucsb.cs156.rec.controllers.UsersControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.rec.controllers.UsersControllerTests]/[method:users__admin_logged_in()]
replaced return value with null for edu/ucsb/cs156/rec/controllers/UsersController::users → KILLED

71

1.1
Location : allProfessors
Killed by : edu.ucsb.cs156.rec.controllers.UsersControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.rec.controllers.UsersControllerTests]/[method:non_admin_can_get_all_professors()]
replaced return value with Collections.emptyList for edu/ucsb/cs156/rec/controllers/UsersController::allProfessors → KILLED

87

1.1
Location : lambda$users$0
Killed by : edu.ucsb.cs156.rec.controllers.UsersControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.rec.controllers.UsersControllerTests]/[method:admin_cant_get_nonexistent()]
replaced return value with null for edu/ucsb/cs156/rec/controllers/UsersController::lambda$users$0 → KILLED

89

1.1
Location : users
Killed by : edu.ucsb.cs156.rec.controllers.UsersControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.rec.controllers.UsersControllerTests]/[method:admin_can_get()]
replaced return value with null for edu/ucsb/cs156/rec/controllers/UsersController::users → KILLED

104

1.1
Location : lambda$deleteUser_Admin$1
Killed by : edu.ucsb.cs156.rec.controllers.UsersControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.rec.controllers.UsersControllerTests]/[method:admin_cant_delete_nonexistent()]
replaced return value with null for edu/ucsb/cs156/rec/controllers/UsersController::lambda$deleteUser_Admin$1 → KILLED

105

1.1
Location : deleteUser_Admin
Killed by : edu.ucsb.cs156.rec.controllers.UsersControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.rec.controllers.UsersControllerTests]/[method:admin_can_delete()]
removed call to edu/ucsb/cs156/rec/repositories/UserRepository::delete → KILLED

106

1.1
Location : deleteUser_Admin
Killed by : edu.ucsb.cs156.rec.controllers.UsersControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.rec.controllers.UsersControllerTests]/[method:admin_can_delete()]
replaced return value with null for edu/ucsb/cs156/rec/controllers/UsersController::deleteUser_Admin → KILLED

121

1.1
Location : lambda$toggleAdmin$2
Killed by : edu.ucsb.cs156.rec.controllers.UsersControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.rec.controllers.UsersControllerTests]/[method:admin_cant_toggle_admin_nonexistent()]
replaced return value with null for edu/ucsb/cs156/rec/controllers/UsersController::lambda$toggleAdmin$2 → KILLED

127

1.1
Location : toggleAdmin
Killed by : edu.ucsb.cs156.rec.controllers.UsersControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.rec.controllers.UsersControllerTests]/[method:admin_can_toggle_admin_flip()]
negated conditional → KILLED

2.2
Location : toggleAdmin
Killed by : edu.ucsb.cs156.rec.controllers.UsersControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.rec.controllers.UsersControllerTests]/[method:admin_cannot_remove_own_admin_status()]
negated conditional → KILLED

132

1.1
Location : toggleAdmin
Killed by : edu.ucsb.cs156.rec.controllers.UsersControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.rec.controllers.UsersControllerTests]/[method:admin_can_toggle_admin()]
negated conditional → KILLED

2.2
Location : toggleAdmin
Killed by : edu.ucsb.cs156.rec.controllers.UsersControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.rec.controllers.UsersControllerTests]/[method:admin_can_toggle_admin()]
removed call to edu/ucsb/cs156/rec/entities/User::setAdmin → KILLED

134

1.1
Location : toggleAdmin
Killed by : edu.ucsb.cs156.rec.controllers.UsersControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.rec.controllers.UsersControllerTests]/[method:admin_can_toggle_admin()]
replaced return value with null for edu/ucsb/cs156/rec/controllers/UsersController::toggleAdmin → KILLED

150

1.1
Location : lambda$toggleProfessor$3
Killed by : edu.ucsb.cs156.rec.controllers.UsersControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.rec.controllers.UsersControllerTests]/[method:admin_cant_toggle_professor_nonexistent()]
replaced return value with null for edu/ucsb/cs156/rec/controllers/UsersController::lambda$toggleProfessor$3 → KILLED

152

1.1
Location : toggleProfessor
Killed by : edu.ucsb.cs156.rec.controllers.UsersControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.rec.controllers.UsersControllerTests]/[method:admin_can_toggle_professor_flip()]
negated conditional → KILLED

2.2
Location : toggleProfessor
Killed by : edu.ucsb.cs156.rec.controllers.UsersControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.rec.controllers.UsersControllerTests]/[method:admin_can_toggle_professor_flip()]
removed call to edu/ucsb/cs156/rec/entities/User::setProfessor → KILLED

154

1.1
Location : toggleProfessor
Killed by : edu.ucsb.cs156.rec.controllers.UsersControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.rec.controllers.UsersControllerTests]/[method:admin_can_toggle_professor_flip()]
replaced return value with null for edu/ucsb/cs156/rec/controllers/UsersController::toggleProfessor → KILLED

Active mutators

Tests examined


Report generated by PIT 1.17.0