UCSBCurriculumService.java

1
package edu.ucsb.cs156.courses.services;
2
3
import com.fasterxml.jackson.databind.ObjectMapper;
4
import edu.ucsb.cs156.courses.documents.ConvertedSection;
5
import edu.ucsb.cs156.courses.documents.CoursePage;
6
import java.util.Arrays;
7
import java.util.HashMap;
8
import java.util.List;
9
import java.util.Map;
10
import lombok.extern.slf4j.Slf4j;
11
import org.springframework.beans.factory.annotation.Autowired;
12
import org.springframework.beans.factory.annotation.Value;
13
import org.springframework.boot.web.client.RestTemplateBuilder;
14
import org.springframework.http.HttpEntity;
15
import org.springframework.http.HttpHeaders;
16
import org.springframework.http.HttpMethod;
17
import org.springframework.http.HttpStatus;
18
import org.springframework.http.MediaType;
19
import org.springframework.http.ResponseEntity;
20
import org.springframework.stereotype.Service;
21
import org.springframework.web.client.RestTemplate;
22
23
/** Service object that wraps the UCSB Academic Curriculum API */
24
@Service
25
@Slf4j
26
public class UCSBCurriculumService {
27
28
  @Autowired private ObjectMapper objectMapper;
29
30
  @Value("${app.ucsb.api.consumer_key}")
31
  private String apiKey;
32
33
  private RestTemplate restTemplate = new RestTemplate();
34
35
  public UCSBCurriculumService(RestTemplateBuilder restTemplateBuilder) throws Exception {
36
    restTemplate = restTemplateBuilder.build();
37
  }
38
39
  public static final String CURRICULUM_ENDPOINT =
40
      "https://api.ucsb.edu/academics/curriculums/v1/classes/search";
41
42
  public static final String SUBJECTS_ENDPOINT =
43
      "https://api.ucsb.edu/students/lookups/v1/subjects";
44
45
  public static final String SECTION_ENDPOINT =
46
      "https://api.ucsb.edu/academics/curriculums/v1/classsection/{quarter}/{enrollcode}";
47
48
  public static final String ALL_SECTIONS_ENDPOINT =
49
      "https://api.ucsb.edu/academics/curriculums/v3/classes/{quarter}/{enrollcode}";
50
51
  public String getJSON(String subjectArea, String quarter, String courseLevel) throws Exception {
52
53
    HttpHeaders headers = new HttpHeaders();
54 1 1. getJSON : removed call to org/springframework/http/HttpHeaders::setAccept → KILLED
    headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
55 1 1. getJSON : removed call to org/springframework/http/HttpHeaders::setContentType → KILLED
    headers.setContentType(MediaType.APPLICATION_JSON);
56 1 1. getJSON : removed call to org/springframework/http/HttpHeaders::set → KILLED
    headers.set("ucsb-api-version", "1.0");
57 1 1. getJSON : removed call to org/springframework/http/HttpHeaders::set → KILLED
    headers.set("ucsb-api-key", this.apiKey);
58
59
    HttpEntity<String> entity = new HttpEntity<>("body", headers);
60
61
    String params =
62
        String.format(
63
            "?quarter=%s&subjectCode=%s&objLevelCode=%s&pageNumber=%d&pageSize=%d&includeClassSections=%s",
64
            quarter, subjectArea, courseLevel, 1, 100, "true");
65
    String url = CURRICULUM_ENDPOINT + params;
66
67 1 1. getJSON : negated conditional → KILLED
    if (courseLevel.equals("A")) {
68
      params =
69
          String.format(
70
              "?quarter=%s&subjectCode=%s&pageNumber=%d&pageSize=%d&includeClassSections=%s",
71
              quarter, subjectArea, 1, 100, "true");
72
      url = CURRICULUM_ENDPOINT + params;
73
    }
74
75
    log.info("url=" + url);
76
77
    String retVal = "";
78
    MediaType contentType = null;
79
    HttpStatus statusCode = null;
80
81
    ResponseEntity<String> re = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
82
    contentType = re.getHeaders().getContentType();
83
    statusCode = (HttpStatus) re.getStatusCode();
84
    retVal = re.getBody();
85
86
    log.info("json: {} contentType: {} statusCode: {}", retVal, contentType, statusCode);
87 1 1. getJSON : replaced return value with "" for edu/ucsb/cs156/courses/services/UCSBCurriculumService::getJSON → KILLED
    return retVal;
88
  }
89
90
  public List<ConvertedSection> getConvertedSections(
91
      String subjectArea, String quarter, String courseLevel) throws Exception {
92
    String json = getJSON(subjectArea, quarter, courseLevel);
93
    CoursePage coursePage = objectMapper.readValue(json, CoursePage.class);
94
    List<ConvertedSection> result = coursePage.convertedSections();
95 1 1. getConvertedSections : replaced return value with Collections.emptyList for edu/ucsb/cs156/courses/services/UCSBCurriculumService::getConvertedSections → KILLED
    return result;
96
  }
97
98
  public String getSectionJSON(String subjectArea, String quarter, String courseLevel)
99
      throws Exception {
100
    List<ConvertedSection> l = getConvertedSections(subjectArea, quarter, courseLevel);
101
102
    String arrayToJson = objectMapper.writeValueAsString(l);
103
104 1 1. getSectionJSON : replaced return value with "" for edu/ucsb/cs156/courses/services/UCSBCurriculumService::getSectionJSON → KILLED
    return arrayToJson;
105
  }
106
107
  public String getSubjectsJSON() throws Exception {
108
109
    HttpHeaders headers = new HttpHeaders();
110 1 1. getSubjectsJSON : removed call to org/springframework/http/HttpHeaders::setAccept → KILLED
    headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
111 1 1. getSubjectsJSON : removed call to org/springframework/http/HttpHeaders::setContentType → KILLED
    headers.setContentType(MediaType.APPLICATION_JSON);
112 1 1. getSubjectsJSON : removed call to org/springframework/http/HttpHeaders::set → KILLED
    headers.set("ucsb-api-version", "1.0");
113 1 1. getSubjectsJSON : removed call to org/springframework/http/HttpHeaders::set → KILLED
    headers.set("ucsb-api-key", this.apiKey);
114
115
    HttpEntity<String> entity = new HttpEntity<>("body", headers);
116
117
    log.info("url=" + SUBJECTS_ENDPOINT);
118
119
    String retVal = "";
120
    MediaType contentType = null;
121
    HttpStatus statusCode = null;
122
123
    ResponseEntity<String> re =
124
        restTemplate.exchange(SUBJECTS_ENDPOINT, HttpMethod.GET, entity, String.class);
125
    contentType = re.getHeaders().getContentType();
126
    statusCode = (HttpStatus) re.getStatusCode();
127
    retVal = re.getBody();
128
129
    log.info("json: {} contentType: {} statusCode: {}", retVal, contentType, statusCode);
130 1 1. getSubjectsJSON : replaced return value with "" for edu/ucsb/cs156/courses/services/UCSBCurriculumService::getSubjectsJSON → KILLED
    return retVal;
131
  }
132
133
  /**
134
   * This method retrieves exactly one section matching the enrollCode and quarter arguments, if
135
   * such a section exists.
136
   */
137
  public String getSection(String enrollCode, String quarter) throws Exception {
138
139
    HttpHeaders headers = new HttpHeaders();
140 1 1. getSection : removed call to org/springframework/http/HttpHeaders::setAccept → KILLED
    headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
141 1 1. getSection : removed call to org/springframework/http/HttpHeaders::setContentType → KILLED
    headers.setContentType(MediaType.APPLICATION_JSON);
142 1 1. getSection : removed call to org/springframework/http/HttpHeaders::set → KILLED
    headers.set("ucsb-api-version", "1.0");
143 1 1. getSection : removed call to org/springframework/http/HttpHeaders::set → KILLED
    headers.set("ucsb-api-key", this.apiKey);
144
145
    HttpEntity<String> entity = new HttpEntity<>("body", headers);
146
147
    String url = SECTION_ENDPOINT;
148
149
    log.info("url=" + url);
150
151
    Map<String, String> params = new HashMap<>();
152
    params.put("quarter", quarter);
153
    params.put("enrollcode", enrollCode);
154
155
    String retVal = "";
156
    MediaType contentType = null;
157
    HttpStatus statusCode = null;
158
159
    ResponseEntity<String> re =
160
        restTemplate.exchange(url, HttpMethod.GET, entity, String.class, params);
161
    contentType = re.getHeaders().getContentType();
162
    statusCode = (HttpStatus) re.getStatusCode();
163
    retVal = re.getBody();
164
165 1 1. getSection : negated conditional → KILLED
    if (retVal.equals("null")) {
166
      retVal = "{\"error\": \"Enroll code doesn't exist in that quarter.\"}";
167
    }
168
169
    log.info("json: {} contentType: {} statusCode: {}", retVal, contentType, statusCode);
170 1 1. getSection : replaced return value with "" for edu/ucsb/cs156/courses/services/UCSBCurriculumService::getSection → KILLED
    return retVal;
171
  }
172
173
  /**
174
   * This method retrieves all of the sections related to a certain enroll code. For example, if the
175
   * enrollCode is for a discussion section, the lecture section and all related discussion sections
176
   * will also be returned.
177
   */
178
  public String getAllSections(String enrollCode, String quarter) throws Exception {
179
180
    HttpHeaders headers = new HttpHeaders();
181 1 1. getAllSections : removed call to org/springframework/http/HttpHeaders::setAccept → KILLED
    headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
182 1 1. getAllSections : removed call to org/springframework/http/HttpHeaders::setContentType → KILLED
    headers.setContentType(MediaType.APPLICATION_JSON);
183 1 1. getAllSections : removed call to org/springframework/http/HttpHeaders::set → KILLED
    headers.set("ucsb-api-version", "3.0");
184 1 1. getAllSections : removed call to org/springframework/http/HttpHeaders::set → KILLED
    headers.set("ucsb-api-key", this.apiKey);
185
186
    HttpEntity<String> entity = new HttpEntity<>("body", headers);
187
188
    String url = ALL_SECTIONS_ENDPOINT;
189
190
    log.info("url=" + url);
191
192
    Map<String, String> params = new HashMap<>();
193
    params.put("quarter", quarter);
194
    params.put("enrollcode", enrollCode);
195
196
    String retVal = "";
197
    MediaType contentType = null;
198
    HttpStatus statusCode = null;
199
200
    ResponseEntity<String> re =
201
        restTemplate.exchange(url, HttpMethod.GET, entity, String.class, params);
202
    contentType = re.getHeaders().getContentType();
203
    statusCode = (HttpStatus) re.getStatusCode();
204
    retVal = re.getBody();
205
206 1 1. getAllSections : negated conditional → KILLED
    if (retVal.equals("null")) {
207
      retVal = "{\"error\": \"Enroll code doesn't exist in that quarter.\"}";
208
    }
209
210
    log.info("json: {} contentType: {} statusCode: {}", retVal, contentType, statusCode);
211 1 1. getAllSections : replaced return value with "" for edu/ucsb/cs156/courses/services/UCSBCurriculumService::getAllSections → KILLED
    return retVal;
212
  }
213
214
  public String getJSONbyQtrEnrollCd(String quarter, String enrollCd) throws Exception {
215
216
    HttpHeaders headers = new HttpHeaders();
217 1 1. getJSONbyQtrEnrollCd : removed call to org/springframework/http/HttpHeaders::setAccept → KILLED
    headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
218 1 1. getJSONbyQtrEnrollCd : removed call to org/springframework/http/HttpHeaders::setContentType → KILLED
    headers.setContentType(MediaType.APPLICATION_JSON);
219 1 1. getJSONbyQtrEnrollCd : removed call to org/springframework/http/HttpHeaders::set → KILLED
    headers.set("ucsb-api-version", "1.0");
220 1 1. getJSONbyQtrEnrollCd : removed call to org/springframework/http/HttpHeaders::set → KILLED
    headers.set("ucsb-api-key", this.apiKey);
221
222
    HttpEntity<String> entity = new HttpEntity<>("body", headers);
223
224
    String url =
225
        "https://api.ucsb.edu/academics/curriculums/v3/classsection/" + quarter + "/" + enrollCd;
226
227
    log.info("url=" + url);
228
229
    String retVal = "";
230
    MediaType contentType = null;
231
    HttpStatus statusCode = null;
232
233
    ResponseEntity<String> re = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
234
    contentType = re.getHeaders().getContentType();
235
    statusCode = (HttpStatus) re.getStatusCode();
236
    retVal = re.getBody();
237
238
    log.info("json: {} contentType: {} statusCode: {}", retVal, contentType, statusCode);
239 1 1. getJSONbyQtrEnrollCd : replaced return value with "" for edu/ucsb/cs156/courses/services/UCSBCurriculumService::getJSONbyQtrEnrollCd → KILLED
    return retVal;
240
  }
241
}

Mutations

54

1.1
Location : getJSON
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getJSON_success()]
removed call to org/springframework/http/HttpHeaders::setAccept → KILLED

55

1.1
Location : getJSON
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getJSON_success()]
removed call to org/springframework/http/HttpHeaders::setContentType → KILLED

56

1.1
Location : getJSON
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getJSON_success()]
removed call to org/springframework/http/HttpHeaders::set → KILLED

57

1.1
Location : getJSON
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getJSON_success()]
removed call to org/springframework/http/HttpHeaders::set → KILLED

67

1.1
Location : getJSON
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getJSON_success()]
negated conditional → KILLED

87

1.1
Location : getJSON
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getJSON_success()]
replaced return value with "" for edu/ucsb/cs156/courses/services/UCSBCurriculumService::getJSON → KILLED

95

1.1
Location : getConvertedSections
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getConvertedSections()]
replaced return value with Collections.emptyList for edu/ucsb/cs156/courses/services/UCSBCurriculumService::getConvertedSections → KILLED

104

1.1
Location : getSectionJSON
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getSectionJSON()]
replaced return value with "" for edu/ucsb/cs156/courses/services/UCSBCurriculumService::getSectionJSON → KILLED

110

1.1
Location : getSubjectsJSON
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getSubjectsJSON_success()]
removed call to org/springframework/http/HttpHeaders::setAccept → KILLED

111

1.1
Location : getSubjectsJSON
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getSubjectsJSON_success()]
removed call to org/springframework/http/HttpHeaders::setContentType → KILLED

112

1.1
Location : getSubjectsJSON
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getSubjectsJSON_success()]
removed call to org/springframework/http/HttpHeaders::set → KILLED

113

1.1
Location : getSubjectsJSON
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getSubjectsJSON_success()]
removed call to org/springframework/http/HttpHeaders::set → KILLED

130

1.1
Location : getSubjectsJSON
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getSubjectsJSON_success()]
replaced return value with "" for edu/ucsb/cs156/courses/services/UCSBCurriculumService::getSubjectsJSON → KILLED

140

1.1
Location : getSection
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getSection_not_found()]
removed call to org/springframework/http/HttpHeaders::setAccept → KILLED

141

1.1
Location : getSection
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getSection_not_found()]
removed call to org/springframework/http/HttpHeaders::setContentType → KILLED

142

1.1
Location : getSection
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getSection_not_found()]
removed call to org/springframework/http/HttpHeaders::set → KILLED

143

1.1
Location : getSection
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getSection_not_found()]
removed call to org/springframework/http/HttpHeaders::set → KILLED

165

1.1
Location : getSection
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getSection_not_found()]
negated conditional → KILLED

170

1.1
Location : getSection
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getSection_not_found()]
replaced return value with "" for edu/ucsb/cs156/courses/services/UCSBCurriculumService::getSection → KILLED

181

1.1
Location : getAllSections
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getAllSections_not_found()]
removed call to org/springframework/http/HttpHeaders::setAccept → KILLED

182

1.1
Location : getAllSections
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getAllSections_not_found()]
removed call to org/springframework/http/HttpHeaders::setContentType → KILLED

183

1.1
Location : getAllSections
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getAllSections_not_found()]
removed call to org/springframework/http/HttpHeaders::set → KILLED

184

1.1
Location : getAllSections
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getAllSections_not_found()]
removed call to org/springframework/http/HttpHeaders::set → KILLED

206

1.1
Location : getAllSections
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getAllSections_not_found()]
negated conditional → KILLED

211

1.1
Location : getAllSections
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getAllSections_not_found()]
replaced return value with "" for edu/ucsb/cs156/courses/services/UCSBCurriculumService::getAllSections → KILLED

217

1.1
Location : getJSONbyQtrEnrollCd
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getJSONbyQtrEnrollCd_success()]
removed call to org/springframework/http/HttpHeaders::setAccept → KILLED

218

1.1
Location : getJSONbyQtrEnrollCd
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getJSONbyQtrEnrollCd_success()]
removed call to org/springframework/http/HttpHeaders::setContentType → KILLED

219

1.1
Location : getJSONbyQtrEnrollCd
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getJSONbyQtrEnrollCd_success()]
removed call to org/springframework/http/HttpHeaders::set → KILLED

220

1.1
Location : getJSONbyQtrEnrollCd
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getJSONbyQtrEnrollCd_success()]
removed call to org/springframework/http/HttpHeaders::set → KILLED

239

1.1
Location : getJSONbyQtrEnrollCd
Killed by : edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.courses.services.UCSBCurriculumServiceTests]/[method:test_getJSONbyQtrEnrollCd_success()]
replaced return value with "" for edu/ucsb/cs156/courses/services/UCSBCurriculumService::getJSONbyQtrEnrollCd → KILLED

Active mutators

Tests examined


Report generated by PIT 1.17.0