UsersController.java

1
package edu.ucsb.cs156.dining.controllers;
2
3
import com.fasterxml.jackson.core.JsonProcessingException;
4
import com.fasterxml.jackson.databind.ObjectMapper;
5
import edu.ucsb.cs156.dining.entities.User;
6
import edu.ucsb.cs156.dining.errors.EntityNotFoundException;
7
import edu.ucsb.cs156.dining.models.CurrentUser;
8
import edu.ucsb.cs156.dining.repositories.UserRepository;
9
import edu.ucsb.cs156.dining.statuses.ModerationStatus;
10
import io.swagger.v3.oas.annotations.Operation;
11
import io.swagger.v3.oas.annotations.tags.Tag;
12
import java.time.LocalDate;
13
import java.util.ArrayList;
14
import java.util.List;
15
import org.springframework.beans.factory.annotation.Autowired;
16
import org.springframework.beans.factory.annotation.Value;
17
import org.springframework.http.HttpStatus;
18
import org.springframework.http.ResponseEntity;
19
import org.springframework.security.access.prepost.PreAuthorize;
20
import org.springframework.web.bind.annotation.*;
21
import org.springframework.web.bind.annotation.GetMapping;
22
import org.springframework.web.bind.annotation.RequestMapping;
23
import org.springframework.web.bind.annotation.RestController;
24
import org.springframework.web.server.ResponseStatusException;
25
26
/**
27
 * This is a REST controller for getting information about the users.
28
 *
29
 * <p>These endpoints are only accessible to users with the role "ROLE_ADMIN".
30
 */
31
@Tag(name = "User information (admin only)")
32
@RequestMapping("/api")
33
@RestController
34
public class UsersController extends ApiController {
35
36
  @Value("${app.admin.emails}")
37
  private final List<String> adminEmails = new ArrayList<>();
38
39
  @Autowired UserRepository userRepository;
40
41
  @Autowired ObjectMapper mapper;
42
43
  /**
44
   * This method returns a list of all users. Accessible only to users with the role "ROLE_ADMIN".
45
   *
46
   * @return a list of all users
47
   * @throws JsonProcessingException if there is an error processing the JSON
48
   */
49
  @Operation(summary = "Get a list of all users")
50
  @PreAuthorize("hasRole('ROLE_ADMIN')")
51
  @GetMapping("/admin/users")
52
  public ResponseEntity<String> users() throws JsonProcessingException {
53
54
    Iterable<User> users = userRepository.findAll();
55
    String body = mapper.writeValueAsString(users);
56 1 1. users : replaced return value with null for edu/ucsb/cs156/dining/controllers/UsersController::users → KILLED
    return ResponseEntity.ok().body(body);
57
  }
58
59
  /**
60
   * This method returns list of all users with a proposed alias.
61
   *
62
   * @return a list of users with a proposed alias
63
   * @throws JsonProcessingException if there is an error processing the JSON
64
   */
65
  @Operation(summary = "Get a list of all users with a proposed alias")
66
  @PreAuthorize("hasRole('ROLE_ADMIN')")
67
  @GetMapping("/admin/usersWithProposedAlias")
68
  public ResponseEntity<String> getUsersWithProposedAlias() throws JsonProcessingException {
69
    Iterable<User> users = userRepository.findByProposedAliasNotNull();
70
    String body = mapper.writeValueAsString(users);
71 1 1. getUsersWithProposedAlias : replaced return value with null for edu/ucsb/cs156/dining/controllers/UsersController::getUsersWithProposedAlias → KILLED
    return ResponseEntity.ok().body(body);
72
  }
73
74
  /** Get all users whose proposed alias is awaiting moderation. */
75
  @Operation(summary = "Get all aliases needing moderation")
76
  @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_MODERATOR')")
77
  @GetMapping("/admin/users/needsmoderation")
78
  public ResponseEntity<String> getAliasesNeedingModeration() throws JsonProcessingException {
79
80
    Iterable<User> users =
81
        userRepository.findByStatusAndProposedAliasNotNull(ModerationStatus.AWAITING_REVIEW);
82
83
    String body = mapper.writeValueAsString(users);
84
85 1 1. getAliasesNeedingModeration : replaced return value with null for edu/ucsb/cs156/dining/controllers/UsersController::getAliasesNeedingModeration → KILLED
    return ResponseEntity.ok().body(body);
86
  }
87
88
  /**
89
   * This method allows the user to update their alias.
90
   *
91
   * @param proposedAlias the new alias
92
   * @return the updated user
93
   */
94
  @Operation(summary = "Update proposed alias of the current user")
95
  @PreAuthorize("hasRole('ROLE_USER')")
96
  @PostMapping("/currentUser/updateAlias")
97
  public ResponseEntity<User> updateProposedAlias(@RequestParam String proposedAlias) {
98
    CurrentUser currentUser = super.getCurrentUser();
99
    User user = currentUser.getUser();
100
101 1 1. updateProposedAlias : negated conditional → KILLED
    if (userRepository.findByAlias(proposedAlias).isPresent()) {
102
      throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Alias already in use.");
103
    }
104
105 1 1. updateProposedAlias : removed call to edu/ucsb/cs156/dining/entities/User::setProposedAlias → KILLED
    user.setProposedAlias(proposedAlias);
106 1 1. updateProposedAlias : removed call to edu/ucsb/cs156/dining/entities/User::setStatus → KILLED
    user.setStatus(ModerationStatus.AWAITING_REVIEW);
107
    User savedUser = userRepository.save(user);
108
109 1 1. updateProposedAlias : replaced return value with null for edu/ucsb/cs156/dining/controllers/UsersController::updateProposedAlias → KILLED
    return ResponseEntity.ok(savedUser);
110
  }
111
112
  /**
113
   * This method allows an admin to update the moderation status of a user's alias.
114
   *
115
   * @param id the id of the user to update
116
   * @param approved the new moderation status
117
   * @return the updated user
118
   */
119
  @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_MODERATOR')")
120
  @PutMapping("/currentUser/updateAliasModeration")
121
  public User updateAliasModeration(@RequestParam long id, @RequestParam Boolean approved) {
122
123
    User user =
124 1 1. lambda$updateAliasModeration$0 : replaced return value with null for edu/ucsb/cs156/dining/controllers/UsersController::lambda$updateAliasModeration$0 → KILLED
        userRepository.findById(id).orElseThrow(() -> new EntityNotFoundException(User.class, id));
125
126 1 1. updateAliasModeration : negated conditional → KILLED
    if (approved) {
127 1 1. updateAliasModeration : removed call to edu/ucsb/cs156/dining/entities/User::setAlias → KILLED
      user.setAlias(user.getProposedAlias());
128 1 1. updateAliasModeration : removed call to edu/ucsb/cs156/dining/entities/User::setStatus → KILLED
      user.setStatus(ModerationStatus.APPROVED);
129 1 1. updateAliasModeration : removed call to edu/ucsb/cs156/dining/entities/User::setDateApproved → KILLED
      user.setDateApproved(LocalDate.now());
130 1 1. updateAliasModeration : removed call to edu/ucsb/cs156/dining/entities/User::setProposedAlias → KILLED
      user.setProposedAlias(null);
131
    } else {
132 1 1. updateAliasModeration : removed call to edu/ucsb/cs156/dining/entities/User::setStatus → KILLED
      user.setStatus(ModerationStatus.REJECTED);
133
    }
134
135
    userRepository.save(user);
136
137 1 1. updateAliasModeration : replaced return value with null for edu/ucsb/cs156/dining/controllers/UsersController::updateAliasModeration → KILLED
    return user;
138
  }
139
140
  /**
141
   * This method allows an admin to toggle the admin status of a user. Will not toggle status of
142
   * admin in adminEmails.
143
   *
144
   * @param id the id of the user to toggle
145
   * @return the updated user
146
   */
147
  @PreAuthorize("hasRole('ROLE_ADMIN')")
148
  @PutMapping("/admin/toggleAdmin")
149
  public User toggleAdminStatus(@RequestParam long id) {
150
151
    User user =
152 1 1. lambda$toggleAdminStatus$1 : replaced return value with null for edu/ucsb/cs156/dining/controllers/UsersController::lambda$toggleAdminStatus$1 → KILLED
        userRepository.findById(id).orElseThrow(() -> new EntityNotFoundException(User.class, id));
153
154 1 1. toggleAdminStatus : negated conditional → KILLED
    if (!adminEmails.contains(user.getEmail())) {
155 2 1. toggleAdminStatus : removed call to edu/ucsb/cs156/dining/entities/User::setAdmin → KILLED
2. toggleAdminStatus : negated conditional → KILLED
      user.setAdmin(!user.isAdmin());
156
    }
157
158
    userRepository.save(user);
159
160 1 1. toggleAdminStatus : replaced return value with null for edu/ucsb/cs156/dining/controllers/UsersController::toggleAdminStatus → KILLED
    return user;
161
  }
162
163
  /**
164
   * This method allows an admin to toggle the moderator status of a user.
165
   *
166
   * @param id the id of the user to toggle
167
   * @return the updated user
168
   */
169
  @PreAuthorize("hasRole('ROLE_ADMIN')")
170
  @PutMapping("/admin/toggleModerator")
171
  public User toggleModeratorStatus(@RequestParam long id) {
172
173
    User user =
174 1 1. lambda$toggleModeratorStatus$2 : replaced return value with null for edu/ucsb/cs156/dining/controllers/UsersController::lambda$toggleModeratorStatus$2 → KILLED
        userRepository.findById(id).orElseThrow(() -> new EntityNotFoundException(User.class, id));
175
176 2 1. toggleModeratorStatus : removed call to edu/ucsb/cs156/dining/entities/User::setModerator → KILLED
2. toggleModeratorStatus : negated conditional → KILLED
    user.setModerator(!user.isModerator());
177
178
    userRepository.save(user);
179
180 1 1. toggleModeratorStatus : replaced return value with null for edu/ucsb/cs156/dining/controllers/UsersController::toggleModeratorStatus → KILLED
    return user;
181
  }
182
}

Mutations

56

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

71

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

85

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

101

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

105

1.1
Location : updateProposedAlias
Killed by : edu.ucsb.cs156.dining.controllers.UsersControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.dining.controllers.UsersControllerTests]/[method:a_user_can_post_a_new_alias()]
removed call to edu/ucsb/cs156/dining/entities/User::setProposedAlias → KILLED

106

1.1
Location : updateProposedAlias
Killed by : edu.ucsb.cs156.dining.controllers.UsersControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.dining.controllers.UsersControllerTests]/[method:a_user_can_post_a_new_alias()]
removed call to edu/ucsb/cs156/dining/entities/User::setStatus → KILLED

109

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

124

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

126

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

127

1.1
Location : updateAliasModeration
Killed by : edu.ucsb.cs156.dining.controllers.UsersControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.dining.controllers.UsersControllerTests]/[method:admin_can_approve_proposed_alias()]
removed call to edu/ucsb/cs156/dining/entities/User::setAlias → KILLED

128

1.1
Location : updateAliasModeration
Killed by : edu.ucsb.cs156.dining.controllers.UsersControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.dining.controllers.UsersControllerTests]/[method:admin_can_approve_proposed_alias()]
removed call to edu/ucsb/cs156/dining/entities/User::setStatus → KILLED

129

1.1
Location : updateAliasModeration
Killed by : edu.ucsb.cs156.dining.controllers.UsersControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.dining.controllers.UsersControllerTests]/[method:admin_can_approve_proposed_alias()]
removed call to edu/ucsb/cs156/dining/entities/User::setDateApproved → KILLED

130

1.1
Location : updateAliasModeration
Killed by : edu.ucsb.cs156.dining.controllers.UsersControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.dining.controllers.UsersControllerTests]/[method:admin_can_approve_proposed_alias()]
removed call to edu/ucsb/cs156/dining/entities/User::setProposedAlias → KILLED

132

1.1
Location : updateAliasModeration
Killed by : edu.ucsb.cs156.dining.controllers.UsersControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.dining.controllers.UsersControllerTests]/[method:admin_does_not_approve_alias()]
removed call to edu/ucsb/cs156/dining/entities/User::setStatus → KILLED

137

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

152

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

154

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

155

1.1
Location : toggleAdminStatus
Killed by : edu.ucsb.cs156.dining.controllers.UsersControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.dining.controllers.UsersControllerTests]/[method:admin_can_toggle_admin_of_basic_admin()]
removed call to edu/ucsb/cs156/dining/entities/User::setAdmin → KILLED

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

160

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

174

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

176

1.1
Location : toggleModeratorStatus
Killed by : edu.ucsb.cs156.dining.controllers.UsersControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.dining.controllers.UsersControllerTests]/[method:admin_can_toggle_moderator_of_moderator()]
removed call to edu/ucsb/cs156/dining/entities/User::setModerator → KILLED

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

180

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

Active mutators

Tests examined


Report generated by PIT 1.17.0