CourseOptionsController.java

1
package edu.ucsb.cs.scaffold.controller;
2
3
import edu.ucsb.cs.scaffold.entity.Course;
4
import edu.ucsb.cs.scaffold.entity.CourseOption;
5
import edu.ucsb.cs.scaffold.enums.CourseOptions;
6
import edu.ucsb.cs.scaffold.errors.EntityNotFoundException;
7
import edu.ucsb.cs.scaffold.repository.CourseOptionRepository;
8
import edu.ucsb.cs.scaffold.repository.CourseRepository;
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.util.LinkedHashMap;
13
import java.util.Map;
14
import org.springframework.beans.factory.annotation.Autowired;
15
import org.springframework.security.access.prepost.PreAuthorize;
16
import org.springframework.web.bind.annotation.GetMapping;
17
import org.springframework.web.bind.annotation.PostMapping;
18
import org.springframework.web.bind.annotation.RequestMapping;
19
import org.springframework.web.bind.annotation.RequestParam;
20
import org.springframework.web.bind.annotation.RestController;
21
22
@Tag(name = "CourseOptions")
23
@RequestMapping("/api/course/options")
24
@RestController
25
public class CourseOptionsController extends ApiController {
26
27
  @Autowired private CourseOptionRepository courseOptionRepository;
28
29
  @Autowired private CourseRepository courseRepository;
30
31
  @Operation(summary = "Get toggleable options for a course")
32
  @PreAuthorize("@CourseSecurity.hasInstructorPermissions(#root, #courseId)")
33
  @GetMapping("")
34
  public Map<String, Boolean> getCourseOptions(
35
      @Parameter(name = "courseId") @RequestParam Long courseId,
36
      @Parameter(name = "option") @RequestParam(required = false) String option) {
37 1 1. getCourseOptions : removed call to edu/ucsb/cs/scaffold/controller/CourseOptionsController::ensureCourseExists → KILLED
    ensureCourseExists(courseId);
38
39 2 1. getCourseOptions : negated conditional → KILLED
2. getCourseOptions : negated conditional → KILLED
    if (option != null && !option.isBlank()) {
40
      String normalizedOption = normalizeAndValidateOption(option);
41
      boolean enabled =
42
          courseOptionRepository
43
              .findByCourseIdAndOption(courseId, normalizedOption)
44
              .map(CourseOption::getEnabled)
45
              .orElse(false);
46 1 1. getCourseOptions : replaced return value with Collections.emptyMap for edu/ucsb/cs/scaffold/controller/CourseOptionsController::getCourseOptions → KILLED
      return Map.of(normalizedOption, enabled);
47
    }
48
49
    LinkedHashMap<String, Boolean> options = new LinkedHashMap<>();
50
    for (CourseOptions courseOption : CourseOptions.values()) {
51
      options.put(courseOption.name(), false);
52
    }
53
    for (CourseOption courseOption : courseOptionRepository.findByCourseId(courseId)) {
54 1 1. getCourseOptions : negated conditional → KILLED
      if (options.containsKey(courseOption.getOption())) {
55
        options.put(courseOption.getOption(), courseOption.getEnabled());
56
      }
57
    }
58 1 1. getCourseOptions : replaced return value with Collections.emptyMap for edu/ucsb/cs/scaffold/controller/CourseOptionsController::getCourseOptions → KILLED
    return options;
59
  }
60
61
  @Operation(summary = "Set toggleable option for a course")
62
  @PreAuthorize("@CourseSecurity.hasInstructorPermissions(#root, #courseId)")
63
  @PostMapping("")
64
  public Map<String, Boolean> setCourseOption(
65
      @Parameter(name = "courseId") @RequestParam Long courseId,
66
      @Parameter(name = "option") @RequestParam String option,
67
      @Parameter(name = "enabled") @RequestParam Boolean enabled) {
68 1 1. setCourseOption : removed call to edu/ucsb/cs/scaffold/controller/CourseOptionsController::ensureCourseExists → KILLED
    ensureCourseExists(courseId);
69
70
    String normalizedOption = normalizeAndValidateOption(option);
71
    CourseOption courseOption =
72
        courseOptionRepository
73
            .findByCourseIdAndOption(courseId, normalizedOption)
74
            .orElse(CourseOption.builder().courseId(courseId).option(normalizedOption).build());
75 1 1. setCourseOption : removed call to edu/ucsb/cs/scaffold/entity/CourseOption::setEnabled → KILLED
    courseOption.setEnabled(enabled);
76
    courseOptionRepository.save(courseOption);
77
78 1 1. setCourseOption : replaced return value with Collections.emptyMap for edu/ucsb/cs/scaffold/controller/CourseOptionsController::setCourseOption → KILLED
    return Map.of(normalizedOption, enabled);
79
  }
80
81
  private void ensureCourseExists(Long courseId) {
82
    courseRepository
83
        .findById(courseId)
84 1 1. lambda$ensureCourseExists$0 : replaced return value with null for edu/ucsb/cs/scaffold/controller/CourseOptionsController::lambda$ensureCourseExists$0 → KILLED
        .orElseThrow(() -> new EntityNotFoundException(Course.class, courseId));
85
  }
86
87
  private String normalizeAndValidateOption(String option) {
88
    String normalizedOption = option.strip().toUpperCase();
89
    try {
90
      CourseOptions.valueOf(normalizedOption);
91 1 1. normalizeAndValidateOption : replaced return value with "" for edu/ucsb/cs/scaffold/controller/CourseOptionsController::normalizeAndValidateOption → KILLED
      return normalizedOption;
92
    } catch (IllegalArgumentException e) {
93
      throw new IllegalArgumentException("Invalid course option: " + option);
94
    }
95
  }
96
}

Mutations

37

1.1
Location : getCourseOptions
Killed by : edu.ucsb.cs.scaffold.controller.CourseOptionsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.scaffold.controller.CourseOptionsControllerTests]/[method:getCourseOptions_missingCourse_returnsNotFound()]
removed call to edu/ucsb/cs/scaffold/controller/CourseOptionsController::ensureCourseExists → KILLED

39

1.1
Location : getCourseOptions
Killed by : edu.ucsb.cs.scaffold.controller.CourseOptionsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.scaffold.controller.CourseOptionsControllerTests]/[method:getCourseOptions_withBlankOptionParam_returnsAllOptions()]
negated conditional → KILLED

2.2
Location : getCourseOptions
Killed by : edu.ucsb.cs.scaffold.controller.CourseOptionsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.scaffold.controller.CourseOptionsControllerTests]/[method:adminCanGetCourseOptions()]
negated conditional → KILLED

46

1.1
Location : getCourseOptions
Killed by : edu.ucsb.cs.scaffold.controller.CourseOptionsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.scaffold.controller.CourseOptionsControllerTests]/[method:getCourseOptions_withOptionParam_returnsSingleOption()]
replaced return value with Collections.emptyMap for edu/ucsb/cs/scaffold/controller/CourseOptionsController::getCourseOptions → KILLED

54

1.1
Location : getCourseOptions
Killed by : edu.ucsb.cs.scaffold.controller.CourseOptionsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.scaffold.controller.CourseOptionsControllerTests]/[method:getCourseOptions_withUnknownOptionInDb_skipsUnknownOption()]
negated conditional → KILLED

58

1.1
Location : getCourseOptions
Killed by : edu.ucsb.cs.scaffold.controller.CourseOptionsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.scaffold.controller.CourseOptionsControllerTests]/[method:getCourseOptions_withBlankOptionParam_returnsAllOptions()]
replaced return value with Collections.emptyMap for edu/ucsb/cs/scaffold/controller/CourseOptionsController::getCourseOptions → KILLED

68

1.1
Location : setCourseOption
Killed by : edu.ucsb.cs.scaffold.controller.CourseOptionsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.scaffold.controller.CourseOptionsControllerTests]/[method:setCourseOption_missingCourse_returnsNotFound()]
removed call to edu/ucsb/cs/scaffold/controller/CourseOptionsController::ensureCourseExists → KILLED

75

1.1
Location : setCourseOption
Killed by : edu.ucsb.cs.scaffold.controller.CourseOptionsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.scaffold.controller.CourseOptionsControllerTests]/[method:setCourseOption_updatesExistingValue()]
removed call to edu/ucsb/cs/scaffold/entity/CourseOption::setEnabled → KILLED

78

1.1
Location : setCourseOption
Killed by : edu.ucsb.cs.scaffold.controller.CourseOptionsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.scaffold.controller.CourseOptionsControllerTests]/[method:setCourseOption_createsNewValue()]
replaced return value with Collections.emptyMap for edu/ucsb/cs/scaffold/controller/CourseOptionsController::setCourseOption → KILLED

84

1.1
Location : lambda$ensureCourseExists$0
Killed by : edu.ucsb.cs.scaffold.controller.CourseOptionsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.scaffold.controller.CourseOptionsControllerTests]/[method:getCourseOptions_missingCourse_returnsNotFound()]
replaced return value with null for edu/ucsb/cs/scaffold/controller/CourseOptionsController::lambda$ensureCourseExists$0 → KILLED

91

1.1
Location : normalizeAndValidateOption
Killed by : edu.ucsb.cs.scaffold.controller.CourseOptionsControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs.scaffold.controller.CourseOptionsControllerTests]/[method:getCourseOptions_withOptionParam_returnsSingleOption()]
replaced return value with "" for edu/ucsb/cs/scaffold/controller/CourseOptionsController::normalizeAndValidateOption → KILLED

Active mutators

Tests examined


Report generated by PIT 1.17.0