OrganizationMemberService.java

1
package edu.ucsb.cs156.frontiers.services;
2
3
import com.fasterxml.jackson.core.JsonProcessingException;
4
import com.fasterxml.jackson.core.type.TypeReference;
5
import com.fasterxml.jackson.databind.DeserializationFeature;
6
import com.fasterxml.jackson.databind.ObjectMapper;
7
import edu.ucsb.cs156.frontiers.entities.Course;
8
import edu.ucsb.cs156.frontiers.models.OrgMember;
9
import org.springframework.boot.web.client.RestTemplateBuilder;
10
import org.springframework.http.HttpEntity;
11
import org.springframework.http.HttpHeaders;
12
import org.springframework.http.HttpMethod;
13
import org.springframework.http.ResponseEntity;
14
import org.springframework.stereotype.Service;
15
import org.springframework.web.client.RestTemplate;
16
17
import java.security.NoSuchAlgorithmException;
18
import java.security.spec.InvalidKeySpecException;
19
import java.util.ArrayList;
20
import java.util.HashMap;
21
import java.util.List;
22
import java.util.Map;
23
import java.util.regex.Matcher;
24
import java.util.regex.Pattern;
25
26
@Service
27
public class OrganizationMemberService {
28
29
    private final JwtService jwtService;
30
    private final ObjectMapper objectMapper;
31
    private final RestTemplate restTemplate;
32
33
    public OrganizationMemberService(JwtService jwtService, ObjectMapper objectMapper, RestTemplateBuilder builder) {
34
        this.jwtService = jwtService;
35
        this.objectMapper = objectMapper;
36
        this.objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
37
        this.restTemplate = builder.build();
38
    }
39
40
    public Iterable<OrgMember> getOrganizationMembers(Course course) throws NoSuchAlgorithmException, InvalidKeySpecException, JsonProcessingException {
41
        String ENDPOINT = "https://api.github.com/orgs/" + course.getOrgName() + "/members";
42
        //happily stolen directly from GitHub: https://docs.github.com/en/rest/using-the-rest-api/using-pagination-in-the-rest-api?apiVersion=2022-11-28
43
        Pattern pattern = Pattern.compile("(?<=<)([\\S]*)(?=>; rel=\"next\")");
44
        String token = jwtService.getInstallationToken(course);
45
        HttpHeaders headers = new HttpHeaders();
46 1 1. getOrganizationMembers : removed call to org/springframework/http/HttpHeaders::add → KILLED
        headers.add("Authorization", "Bearer " + token);
47 1 1. getOrganizationMembers : removed call to org/springframework/http/HttpHeaders::add → KILLED
        headers.add("Accept", "application/vnd.github+json");
48 1 1. getOrganizationMembers : removed call to org/springframework/http/HttpHeaders::add → KILLED
        headers.add("X-GitHub-Api-Version", "2022-11-28");
49
        HttpEntity<String> entity = new HttpEntity<>(headers);
50
        ResponseEntity<String> response = restTemplate.exchange(ENDPOINT, HttpMethod.GET, entity, String.class);
51
        List<String> responseLinks = response.getHeaders().getOrEmpty("link");
52
        List<OrgMember> orgMembers = new ArrayList<>();
53 2 1. getOrganizationMembers : negated conditional → KILLED
2. getOrganizationMembers : negated conditional → KILLED
        while (!responseLinks.isEmpty()&&responseLinks.getFirst().contains("next")) {
54
            orgMembers.addAll(objectMapper.convertValue(objectMapper.readTree(response.getBody()), new TypeReference<List<OrgMember>>() {
55
            }));
56
            Matcher matcher = pattern.matcher(responseLinks.getFirst());
57
            matcher.find();
58
            response = restTemplate.exchange(matcher.group(0), HttpMethod.GET, entity, String.class);
59
            responseLinks = response.getHeaders().getOrEmpty("link");
60
        }
61
        orgMembers.addAll(objectMapper.convertValue(objectMapper.readTree(response.getBody()), new TypeReference<List<OrgMember>>() {
62
        }));
63 1 1. getOrganizationMembers : replaced return value with Collections.emptyList for edu/ucsb/cs156/frontiers/services/OrganizationMemberService::getOrganizationMembers → KILLED
        return orgMembers;
64
    }
65
}

Mutations

46

1.1
Location : getOrganizationMembers
Killed by : edu.ucsb.cs156.frontiers.services.OrganizationMemberServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.services.OrganizationMemberServiceTests]/[method:testGetOrganizationMembers_MultiplePages()]
removed call to org/springframework/http/HttpHeaders::add → KILLED

47

1.1
Location : getOrganizationMembers
Killed by : edu.ucsb.cs156.frontiers.services.OrganizationMemberServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.services.OrganizationMemberServiceTests]/[method:testGetOrganizationMembers_SinglePage()]
removed call to org/springframework/http/HttpHeaders::add → KILLED

48

1.1
Location : getOrganizationMembers
Killed by : edu.ucsb.cs156.frontiers.services.OrganizationMemberServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.services.OrganizationMemberServiceTests]/[method:testGetOrganizationMembers_SinglePage()]
removed call to org/springframework/http/HttpHeaders::add → KILLED

53

1.1
Location : getOrganizationMembers
Killed by : edu.ucsb.cs156.frontiers.services.OrganizationMemberServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.services.OrganizationMemberServiceTests]/[method:testGetOrganizationMembers_MultiplePages()]
negated conditional → KILLED

2.2
Location : getOrganizationMembers
Killed by : edu.ucsb.cs156.frontiers.services.OrganizationMemberServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.services.OrganizationMemberServiceTests]/[method:testGetOrganizationMembers_MultiplePages()]
negated conditional → KILLED

63

1.1
Location : getOrganizationMembers
Killed by : edu.ucsb.cs156.frontiers.services.OrganizationMemberServiceTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.services.OrganizationMemberServiceTests]/[method:testGetOrganizationMembers_MultiplePages()]
replaced return value with Collections.emptyList for edu/ucsb/cs156/frontiers/services/OrganizationMemberService::getOrganizationMembers → KILLED

Active mutators

Tests examined


Report generated by PIT 1.17.0