CourseStaffCSVController.java

1
package edu.ucsb.cs156.frontiers.controllers;
2
3
import com.opencsv.CSVReader;
4
import com.opencsv.exceptions.CsvException;
5
import edu.ucsb.cs156.frontiers.entities.Course;
6
import edu.ucsb.cs156.frontiers.entities.CourseStaff;
7
import edu.ucsb.cs156.frontiers.enums.OrgStatus;
8
import edu.ucsb.cs156.frontiers.errors.EntityNotFoundException;
9
import edu.ucsb.cs156.frontiers.repositories.CourseRepository;
10
import edu.ucsb.cs156.frontiers.repositories.CourseStaffRepository;
11
import edu.ucsb.cs156.frontiers.services.UpdateUserService;
12
import io.swagger.v3.oas.annotations.Operation;
13
import io.swagger.v3.oas.annotations.Parameter;
14
import io.swagger.v3.oas.annotations.tags.Tag;
15
import java.io.BufferedInputStream;
16
import java.io.IOException;
17
import java.io.InputStream;
18
import java.io.InputStreamReader;
19
import java.util.Map;
20
import lombok.extern.slf4j.Slf4j;
21
import org.springframework.beans.factory.annotation.Autowired;
22
import org.springframework.http.ResponseEntity;
23
import org.springframework.security.access.prepost.PreAuthorize;
24
import org.springframework.web.bind.annotation.PostMapping;
25
import org.springframework.web.bind.annotation.RequestMapping;
26
import org.springframework.web.bind.annotation.RequestParam;
27
import org.springframework.web.bind.annotation.RestController;
28
import org.springframework.web.multipart.MultipartFile;
29
30
@Tag(name = "CourseStaff")
31
@RequestMapping("/api/coursestaff")
32
@RestController
33
@Slf4j
34
public class CourseStaffCSVController extends ApiController {
35
36
  @Autowired private CourseStaffRepository courseStaffRepository;
37
38
  @Autowired private CourseRepository courseRepository;
39
40
  @Autowired private UpdateUserService updateUserService;
41
42
  /**
43
   * Upload staff for a Course from a CSV file. Each row should contain firstName, lastName, and
44
   * email.
45
   *
46
   * @param courseId the ID of the course
47
   * @param file the CSV file to upload
48
   * @return
49
   * @throws IOException
50
   * @throws CsvException
51
   */
52
  @Operation(summary = "Upload Staff CSV for a course")
53
  @PreAuthorize("@CourseSecurity.hasInstructorPermissions(#root, #courseId)")
54
  @PostMapping(
55
      value = "/upload/csv",
56
      consumes = {"multipart/form-data"})
57
  public ResponseEntity<Object> uploadStaffCSV(
58
      @Parameter(name = "courseId") @RequestParam Long courseId,
59
      @Parameter(name = "file") @RequestParam("file") MultipartFile file)
60
      throws IOException, CsvException {
61
62
    Course course =
63
        courseRepository
64
            .findById(courseId)
65 1 1. lambda$uploadStaffCSV$0 : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/CourseStaffCSVController::lambda$uploadStaffCSV$0 → KILLED
            .orElseThrow(() -> new EntityNotFoundException(Course.class, courseId.toString()));
66
67
    int inserted = 0;
68
69
    try (InputStream inputStream = new BufferedInputStream(file.getInputStream());
70
        InputStreamReader reader = new InputStreamReader(inputStream);
71
        CSVReader csvReader = new CSVReader(reader); ) {
72
73
      csvReader.readNext(); // skip header row
74
75
      for (String[] row : csvReader.readAll()) {
76
        CourseStaff staff =
77
            CourseStaff.builder()
78
                .firstName(row[0].trim())
79
                .lastName(row[1].trim())
80
                .email(row[2].trim())
81
                .course(course)
82
                .build();
83
84 1 1. uploadStaffCSV : negated conditional → KILLED
        if (course.getInstallationId() != null) {
85 1 1. uploadStaffCSV : removed call to edu/ucsb/cs156/frontiers/entities/CourseStaff::setOrgStatus → KILLED
          staff.setOrgStatus(OrgStatus.JOINCOURSE);
86
        } else {
87 1 1. uploadStaffCSV : removed call to edu/ucsb/cs156/frontiers/entities/CourseStaff::setOrgStatus → KILLED
          staff.setOrgStatus(OrgStatus.PENDING);
88
        }
89
90
        CourseStaff saved = courseStaffRepository.save(staff);
91 1 1. uploadStaffCSV : removed call to edu/ucsb/cs156/frontiers/services/UpdateUserService::attachUserToCourseStaff → KILLED
        updateUserService.attachUserToCourseStaff(saved);
92 1 1. uploadStaffCSV : Changed increment from 1 to -1 → KILLED
        inserted++;
93
      }
94
    }
95
96 1 1. uploadStaffCSV : replaced return value with null for edu/ucsb/cs156/frontiers/controllers/CourseStaffCSVController::uploadStaffCSV → KILLED
    return ResponseEntity.ok(Map.of("inserted", inserted));
97
  }
98
}

Mutations

65

1.1
Location : lambda$uploadStaffCSV$0
Killed by : edu.ucsb.cs156.frontiers.controllers.CourseStaffCSVControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.CourseStaffCSVControllerTests]/[method:instructor_cannot_upload_staff_csv_for_a_course_that_does_not_exist()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/CourseStaffCSVController::lambda$uploadStaffCSV$0 → KILLED

84

1.1
Location : uploadStaffCSV
Killed by : edu.ucsb.cs156.frontiers.controllers.CourseStaffCSVControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.CourseStaffCSVControllerTests]/[method:org_status_is_pending_when_no_installation_id()]
negated conditional → KILLED

85

1.1
Location : uploadStaffCSV
Killed by : edu.ucsb.cs156.frontiers.controllers.CourseStaffCSVControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.CourseStaffCSVControllerTests]/[method:org_status_is_joincourse_when_installation_id_is_set()]
removed call to edu/ucsb/cs156/frontiers/entities/CourseStaff::setOrgStatus → KILLED

87

1.1
Location : uploadStaffCSV
Killed by : edu.ucsb.cs156.frontiers.controllers.CourseStaffCSVControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.CourseStaffCSVControllerTests]/[method:org_status_is_pending_when_no_installation_id()]
removed call to edu/ucsb/cs156/frontiers/entities/CourseStaff::setOrgStatus → KILLED

91

1.1
Location : uploadStaffCSV
Killed by : edu.ucsb.cs156.frontiers.controllers.CourseStaffCSVControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.CourseStaffCSVControllerTests]/[method:instructor_can_upload_staff_csv()]
removed call to edu/ucsb/cs156/frontiers/services/UpdateUserService::attachUserToCourseStaff → KILLED

92

1.1
Location : uploadStaffCSV
Killed by : edu.ucsb.cs156.frontiers.controllers.CourseStaffCSVControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.CourseStaffCSVControllerTests]/[method:instructor_can_upload_staff_csv()]
Changed increment from 1 to -1 → KILLED

96

1.1
Location : uploadStaffCSV
Killed by : edu.ucsb.cs156.frontiers.controllers.CourseStaffCSVControllerTests.[engine:junit-jupiter]/[class:edu.ucsb.cs156.frontiers.controllers.CourseStaffCSVControllerTests]/[method:instructor_can_upload_staff_csv()]
replaced return value with null for edu/ucsb/cs156/frontiers/controllers/CourseStaffCSVController::uploadStaffCSV → KILLED

Active mutators

Tests examined


Report generated by PIT 1.17.0