CourseOverTimeBuildingController.java

1
package edu.ucsb.cs156.courses.controllers;
2
3
import com.fasterxml.jackson.core.JsonProcessingException;
4
import com.fasterxml.jackson.databind.ObjectMapper;
5
import edu.ucsb.cs156.courses.collections.ConvertedSectionCollection;
6
import edu.ucsb.cs156.courses.documents.ConvertedSection;
7
import io.swagger.v3.oas.annotations.Operation;
8
import io.swagger.v3.oas.annotations.Parameter;
9
import java.util.List;
10
import java.util.Set;
11
import java.util.TreeSet;
12
import java.util.stream.Collectors;
13
import java.util.stream.Stream;
14
import org.springframework.beans.factory.annotation.Autowired;
15
import org.springframework.http.ResponseEntity;
16
import org.springframework.web.bind.annotation.GetMapping;
17
import org.springframework.web.bind.annotation.RequestMapping;
18
import org.springframework.web.bind.annotation.RequestParam;
19
import org.springframework.web.bind.annotation.RestController;
20
21
@RestController
22
@RequestMapping("/api/public/courseovertime")
23
public class CourseOverTimeBuildingController {
24
25
  private ObjectMapper mapper = new ObjectMapper();
26
27
  @Autowired ConvertedSectionCollection convertedSectionCollection;
28
29
  @Operation(summary = "Get a list of courses over time, filtered by (abbreviated) building code")
30
  @GetMapping(value = "/buildingsearch", produces = "application/json")
31
  public ResponseEntity<String> search(
32
      @Parameter(
33
              name = "startQtr",
34
              description =
35
                  "Starting quarter in yyyyq format, e.g. 20232 for S23, 20234 for F23, etc. (1=Winter, 2=Spring, 3=Summer, 4=Fall)",
36
              example = "20232",
37
              required = true)
38
          @RequestParam
39
          String startQtr,
40
      @Parameter(
41
              name = "endQtr",
42
              description =
43
                  "Ending quarter in yyyyq format, e.g. 20232 for S23, 20234 for F23, etc. (1=Winter, 2=Spring, 3=Summer, 4=Fall)",
44
              example = "20232",
45
              required = true)
46
          @RequestParam
47
          String endQtr,
48
      @Parameter(
49
              name = "buildingCode",
50
              description = "Building code such as PHELP for Phelps, GIRV for Girvetz",
51
              example = "GIRV",
52
              required = true)
53
          @RequestParam
54
          String buildingCode,
55
      @Parameter(
56
              name = "classroom",
57
              description = "Classroom number",
58
              example = "1431",
59
              required = false)
60
          @RequestParam(required = false, defaultValue = "")
61
          String classroom)
62
      throws JsonProcessingException {
63
    List<ConvertedSection> courseResults =
64
        new java.util.ArrayList<>(
65
            convertedSectionCollection.findByQuarterRangeAndBuildingCode(
66
                startQtr, endQtr, buildingCode));
67
68 2 1. search : negated conditional → KILLED
2. search : negated conditional → KILLED
    if (!classroom.isEmpty() && !classroom.equals("ALL")) {
69
      courseResults =
70
          courseResults.stream()
71
              .filter(
72
                  result ->
73 2 1. lambda$search$1 : replaced boolean return with true for edu/ucsb/cs156/courses/controllers/CourseOverTimeBuildingController::lambda$search$1 → KILLED
2. lambda$search$1 : negated conditional → KILLED
                      result.getSection() != null
74 1 1. lambda$search$1 : negated conditional → KILLED
                          && result.getSection().getTimeLocations() != null
75
                          && result.getSection().getTimeLocations().stream()
76 1 1. lambda$search$1 : negated conditional → KILLED
                              .anyMatch(
77
                                  loc ->
78 2 1. lambda$search$0 : negated conditional → KILLED
2. lambda$search$0 : replaced boolean return with true for edu/ucsb/cs156/courses/controllers/CourseOverTimeBuildingController::lambda$search$0 → KILLED
                                      loc.getBuilding() != null
79 1 1. lambda$search$0 : negated conditional → KILLED
                                          && loc.getBuilding().equalsIgnoreCase(buildingCode)
80 1 1. lambda$search$0 : negated conditional → KILLED
                                          && loc.getRoom() != null
81 1 1. lambda$search$0 : negated conditional → KILLED
                                          && loc.getRoom().equals(classroom)))
82
              .collect(Collectors.toList());
83
    }
84
85 1 1. search : removed call to java/util/List::sort → KILLED
    courseResults.sort(new ConvertedSection.ConvertedSectionSortDescendingByQuarterComparator());
86
87
    String body = mapper.writeValueAsString(courseResults);
88
89 1 1. search : replaced return value with null for edu/ucsb/cs156/courses/controllers/CourseOverTimeBuildingController::search → KILLED
    return ResponseEntity.ok().body(body);
90
  }
91
92
  @Operation(
93
      summary =
94
          "Get a list of classroom numbers within a particular building, given a quarter and building code")
95
  @GetMapping(value = "/buildingsearch/classrooms", produces = "application/json")
96
  public ResponseEntity<String> searchNew(
97
      @Parameter(
98
              name = "quarter",
99
              description =
100
                  "Quarter in yyyyq format, e.g. 20232 for S23, 20234 for F23, etc. (1=Winter, 2=Spring, 3=Summer, 4=Fall)",
101
              example = "20232",
102
              required = true)
103
          @RequestParam
104
          String quarter,
105
      @Parameter(
106
              name = "buildingCode",
107
              description = "Building code such as PHELP for Phelps, GIRV for Girvetz",
108
              example = "GIRV",
109
              required = true)
110
          @RequestParam
111
          String buildingCode)
112
      throws JsonProcessingException {
113
    List<ConvertedSection> courseResults =
114
        convertedSectionCollection.findByQuarterAndBuildingCode(quarter, buildingCode);
115
116
    Set<String> classrooms =
117
        courseResults.stream()
118
            .flatMap(
119
                result -> {
120 1 1. lambda$searchNew$2 : negated conditional → KILLED
                  if (result.getSection() != null
121 1 1. lambda$searchNew$2 : negated conditional → KILLED
                      && result.getSection().getTimeLocations() != null) {
122 1 1. lambda$searchNew$2 : replaced return value with Stream.empty for edu/ucsb/cs156/courses/controllers/CourseOverTimeBuildingController::lambda$searchNew$2 → KILLED
                    return result.getSection().getTimeLocations().stream();
123
                  } else {
124
                    return Stream.empty();
125
                  }
126
                })
127
            .filter(
128
                loc ->
129 3 1. lambda$searchNew$3 : negated conditional → KILLED
2. lambda$searchNew$3 : replaced boolean return with true for edu/ucsb/cs156/courses/controllers/CourseOverTimeBuildingController::lambda$searchNew$3 → KILLED
3. lambda$searchNew$3 : negated conditional → KILLED
                    loc.getBuilding() != null && loc.getBuilding().equalsIgnoreCase(buildingCode))
130 1 1. lambda$searchNew$4 : replaced return value with "" for edu/ucsb/cs156/courses/controllers/CourseOverTimeBuildingController::lambda$searchNew$4 → KILLED
            .map(loc -> loc.getRoom())
131 3 1. lambda$searchNew$5 : negated conditional → KILLED
2. lambda$searchNew$5 : replaced boolean return with true for edu/ucsb/cs156/courses/controllers/CourseOverTimeBuildingController::lambda$searchNew$5 → KILLED
3. lambda$searchNew$5 : negated conditional → KILLED
            .filter(room -> room != null && !room.isEmpty())
132
            .collect(Collectors.toCollection(TreeSet::new));
133
134
    String body = mapper.writeValueAsString(classrooms);
135 1 1. searchNew : replaced return value with null for edu/ucsb/cs156/courses/controllers/CourseOverTimeBuildingController::searchNew → KILLED
    return ResponseEntity.ok().body(body);
136
  }
137
}

Mutations

68

1.1
Location : search
Killed by : edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests]/[method:test_buildingsearch_with_classroom_no_match()]
negated conditional → KILLED

2.2
Location : search
Killed by : edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests]/[method:test_buildingsearch_with_classroom_no_match()]
negated conditional → KILLED

73

1.1
Location : lambda$search$1
Killed by : edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests]/[method:test_buildingsearch_with_classroom_no_match()]
replaced boolean return with true for edu/ucsb/cs156/courses/controllers/CourseOverTimeBuildingController::lambda$search$1 → KILLED

2.2
Location : lambda$search$1
Killed by : edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests]/[method:test_buildingsearch_with_classroom_and_null_room()]
negated conditional → KILLED

74

1.1
Location : lambda$search$1
Killed by : edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests]/[method:test_buildingsearch_with_classroom_and_null_room()]
negated conditional → KILLED

76

1.1
Location : lambda$search$1
Killed by : edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests]/[method:test_buildingsearch_with_classroom_no_match()]
negated conditional → KILLED

78

1.1
Location : lambda$search$0
Killed by : edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests]/[method:test_buildingsearch_with_classroom_and_null_room()]
negated conditional → KILLED

2.2
Location : lambda$search$0
Killed by : edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests]/[method:test_buildingsearch_with_classroom_no_match()]
replaced boolean return with true for edu/ucsb/cs156/courses/controllers/CourseOverTimeBuildingController::lambda$search$0 → KILLED

79

1.1
Location : lambda$search$0
Killed by : edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests]/[method:test_buildingsearch_with_classroom_and_null_room()]
negated conditional → KILLED

80

1.1
Location : lambda$search$0
Killed by : edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests]/[method:test_buildingsearch_with_classroom_and_null_room()]
negated conditional → KILLED

81

1.1
Location : lambda$search$0
Killed by : edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests]/[method:test_buildingsearch_with_classroom_no_match()]
negated conditional → KILLED

85

1.1
Location : search
Killed by : edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests]/[method:test_old_endpoint_returns_course_sections()]
removed call to java/util/List::sort → KILLED

89

1.1
Location : search
Killed by : edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests]/[method:test_buildingsearch_with_classroom_no_match()]
replaced return value with null for edu/ucsb/cs156/courses/controllers/CourseOverTimeBuildingController::search → KILLED

120

1.1
Location : lambda$searchNew$2
Killed by : edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests]/[method:test_search_sectionIsNull()]
negated conditional → KILLED

121

1.1
Location : lambda$searchNew$2
Killed by : edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests]/[method:test_search_timeLocationsIsNull()]
negated conditional → KILLED

122

1.1
Location : lambda$searchNew$2
Killed by : edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests]/[method:test_search_validRequestWithoutSuffix()]
replaced return value with Stream.empty for edu/ucsb/cs156/courses/controllers/CourseOverTimeBuildingController::lambda$searchNew$2 → KILLED

129

1.1
Location : lambda$searchNew$3
Killed by : edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests]/[method:test_search_validRequestWithoutSuffix()]
negated conditional → KILLED

2.2
Location : lambda$searchNew$3
Killed by : edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests]/[method:test_search_buildingDoesNotMatch()]
replaced boolean return with true for edu/ucsb/cs156/courses/controllers/CourseOverTimeBuildingController::lambda$searchNew$3 → KILLED

3.3
Location : lambda$searchNew$3
Killed by : edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests]/[method:test_search_buildingDoesNotMatch()]
negated conditional → KILLED

130

1.1
Location : lambda$searchNew$4
Killed by : edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests]/[method:test_search_validRequestWithoutSuffix()]
replaced return value with "" for edu/ucsb/cs156/courses/controllers/CourseOverTimeBuildingController::lambda$searchNew$4 → KILLED

131

1.1
Location : lambda$searchNew$5
Killed by : edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests]/[method:test_search_validRequestWithoutSuffix()]
negated conditional → KILLED

2.2
Location : lambda$searchNew$5
Killed by : edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests]/[method:test_search_roomNullOrEmpty_skipsRoom()]
replaced boolean return with true for edu/ucsb/cs156/courses/controllers/CourseOverTimeBuildingController::lambda$searchNew$5 → KILLED

3.3
Location : lambda$searchNew$5
Killed by : edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests]/[method:test_search_validRequestWithoutSuffix()]
negated conditional → KILLED

135

1.1
Location : searchNew
Killed by : edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.controllers.CourseOverTimeBuildingControllerTests]/[method:test_search_timeLocationsIsNull()]
replaced return value with null for edu/ucsb/cs156/courses/controllers/CourseOverTimeBuildingController::searchNew → KILLED

Active mutators

Tests examined


Report generated by PIT 1.17.0